├── README.md ├── book ├── PERMISSIONS ├── ch02 │ └── ch02-printenv.c ├── ch03 │ ├── ch03-getline.c │ └── ch03-memaddr.c ├── ch04 │ ├── ch04-cat.c │ ├── ch04-holes.c │ └── ch04-maxfds.c ├── ch05 │ ├── ch05-catdir.c │ ├── ch05-devnum.c │ └── ch05-trymkdir.c ├── ch06 │ ├── ch06-echodate.c │ ├── ch06-groupinfo.c │ ├── ch06-searchemp.c │ ├── ch06-sortdir.c │ ├── ch06-sortemp.c │ └── presdata.txt ├── ch08 │ ├── ch08-chdir.c │ ├── ch08-getcwd.c │ ├── ch08-mounted.c │ ├── ch08-nftw.c │ ├── ch08-statfs.c │ └── ch08-statvfs.c ├── ch09 │ ├── ch09-atexit.c │ ├── ch09-pipedemo.c │ ├── ch09-pipeline.c │ ├── ch09-reparent.c │ └── ch09-run.c ├── ch10 │ ├── .ch11-catchcont.c.swp │ ├── ch10-catchint.c │ ├── ch10-reap1.c │ ├── ch10-reap2.c │ └── ch10-status.c ├── ch12 │ ├── ch12-assert.c │ ├── ch12-devrandom.c │ ├── ch12-glob.c │ ├── ch12-grep.c │ ├── ch12-memleak.c │ ├── ch12-mkstemp.c │ ├── ch12-mktemp.c │ ├── ch12-rand.c │ ├── ch12-random.c │ ├── ch12-setjmp.c │ └── ch12-tmpfile.c ├── ch13 │ ├── ch13-compare.c │ ├── ch13-echodate.c │ ├── ch13-lconv.c │ ├── ch13-quoteflag.c │ ├── ch13-strfmon.c │ ├── ch13-strings.c │ ├── ch13-times.c │ ├── echodate.pot │ ├── gettext.h │ └── piglat.po ├── ch14 │ ├── ch14-lockall.c │ ├── ch14-timers.c │ ├── ch14-tsearch.c │ └── presdata.txt └── ch15 │ ├── ch15-abort.c │ ├── ch15-badmem1.c │ ├── ch15-badmem2.c │ ├── ch15-badmem3.c │ └── ch15-union.c ├── gnu ├── README ├── coreutils-5.0 │ ├── COPYING │ ├── lib │ │ ├── safe-read.c │ │ ├── safe-write.c │ │ ├── utime.c │ │ └── xreadlink.c │ └── src │ │ ├── du.c │ │ ├── env.c │ │ ├── install.c │ │ ├── link.c │ │ ├── ls.c │ │ ├── pathchk.c │ │ ├── sort.c │ │ ├── sys2.h │ │ └── wc.c ├── gawk-3.0.6 │ ├── COPYING │ └── eval.c ├── gawk-3.1.3 │ ├── COPYING │ ├── awk.h │ ├── builtin.c │ ├── eval.c │ ├── io.c │ ├── main.c │ └── posix │ │ └── gawkmisc.c ├── gawk-3.1.4 │ ├── COPYING │ ├── README │ └── builtin.c ├── getopt │ ├── COPYING.LIB │ ├── getopt.c │ ├── getopt.h │ └── getopt1.c ├── glibc-2.3.2 │ ├── COPYING │ ├── COPYING.LIB │ ├── locale │ │ └── locale.h │ ├── posix │ │ └── unistd.h │ └── time │ │ └── sys │ │ └── time.h └── make-3.80 │ ├── COPYING │ └── read.c ├── v6 └── usr │ └── source │ └── s1 │ └── glob.c └── v7 └── usr ├── include └── sys │ └── dir.h ├── man └── man3 │ └── end.3 └── src ├── cmd ├── cat.c ├── echo.c ├── grep.c ├── ls.c └── rmdir.c └── libc └── gen └── sleep.c /README.md: -------------------------------------------------------------------------------- 1 | # Code for the _Linux Programming by Example: The Fundamentals_ 2 | 3 | Written by Arnold Robbins, Copyright (C) 2004 by Prentice Hall. 4 | 5 | The directories are as follows: 6 | 7 | * `book` Files for example programs written from scratch for the book 8 | * `gnu` Files from GNU Project programs. 9 | * `v6` Files from V6 Unix 10 | * `v7` Files from V7 Unix 11 | -------------------------------------------------------------------------------- /book/PERMISSIONS: -------------------------------------------------------------------------------- 1 | The example programs included in this archive that were created for 2 | this book and that are not part of the GNU project or Unix V6 or V7 3 | are Copyright 2004 Pearson Education, Inc. These programs are free 4 | software and you can redistribute and/or modify them under the terms 5 | of the Open Publication License (http://www.opencontent.org/openpub). 6 | Inclusion of them in this archive implies no warranty of any kind. 7 | -------------------------------------------------------------------------------- /book/ch02/ch02-printenv.c: -------------------------------------------------------------------------------- 1 | /* ch02-printenv.c --- Print out the environment. */ 2 | 3 | #include 4 | 5 | extern char **environ; 6 | 7 | int main(int argc, char **argv) 8 | { 9 | int i; 10 | 11 | if (environ != NULL) 12 | for (i = 0; environ[i] != NULL; i++) 13 | printf("%s\n", environ[i]); 14 | 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /book/ch03/ch03-getline.c: -------------------------------------------------------------------------------- 1 | /* ch03-getline.c --- demonstrate getline(). */ 2 | 3 | #define _GNU_SOURCE 1 4 | #include 5 | #include 6 | 7 | /* main --- read a line and echo it back out until EOF. */ 8 | 9 | int main(void) 10 | { 11 | char *line = NULL; 12 | size_t size = 0; 13 | ssize_t ret; 14 | 15 | while ((ret = getline(& line, & size, stdin)) != -1) 16 | printf("(%lu) %s", size, line); 17 | 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /book/ch03/ch03-memaddr.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ch03-memaddr.c --- Show address of code, data and stack sections, 3 | * as well as BSS and dynamic memory. 4 | */ 5 | 6 | #include 7 | #include /* for definition of ptrdiff_t on GLIBC */ 8 | #include 9 | #include /* for demonstration only */ 10 | 11 | extern void afunc(void); /* a function for showing stack growth */ 12 | 13 | int bss_var; /* auto init to 0, should be in BSS */ 14 | int data_var = 42; /* init to nonzero, should be data */ 15 | 16 | int 17 | main(int argc, char **argv) /* arguments aren't used */ 18 | { 19 | char *p, *b, *nb; 20 | 21 | printf("Text Locations:\n"); 22 | printf("\tAddress of main: %p\n", main); 23 | printf("\tAddress of afunc: %p\n", afunc); 24 | 25 | printf("Stack Locations:\n"); 26 | afunc(); 27 | 28 | p = (char *) alloca(32); 29 | if (p != NULL) { 30 | printf("\tStart of alloca()'ed array: %p\n", p); 31 | printf("\tEnd of alloca()'ed array: %p\n", p + 31); 32 | } 33 | 34 | printf("Data Locations:\n"); 35 | printf("\tAddress of data_var: %p\n", & data_var); 36 | 37 | printf("BSS Locations:\n"); 38 | printf("\tAddress of bss_var: %p\n", & bss_var); 39 | 40 | b = sbrk((ptrdiff_t) 32); /* grow address space */ 41 | nb = sbrk((ptrdiff_t) 0); 42 | printf("Heap Locations:\n"); 43 | printf("\tInitial end of heap: %p\n", b); 44 | printf("\tNew end of heap: %p\n", nb); 45 | 46 | b = sbrk((ptrdiff_t) -16); /* shrink it */ 47 | nb = sbrk((ptrdiff_t) 0); 48 | printf("\tFinal end of heap: %p\n", nb); 49 | } 50 | 51 | void 52 | afunc(void) 53 | { 54 | static int level = 0; /* recursion level */ 55 | auto int stack_var; /* automatic variable, on stack */ 56 | 57 | if (++level == 3) /* avoid infinite recursion */ 58 | return; 59 | 60 | printf("\tStack level %d: address of stack_var: %p\n", 61 | level, & stack_var); 62 | afunc(); /* recursive call */ 63 | } 64 | -------------------------------------------------------------------------------- /book/ch04/ch04-cat.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ch04-cat.c --- Demonstrate open(), read(), write(), close(), 3 | * errno and strerror(). 4 | */ 5 | 6 | #include /* for fprintf(), stderr, BUFSIZ */ 7 | #include /* declare errno */ 8 | #include /* for flags for open() */ 9 | #include /* declare strerror() */ 10 | #include /* for ssize_t */ 11 | #include 12 | #include /* for mode_t */ 13 | 14 | char *myname; 15 | int process(char *file); 16 | 17 | /* main --- loop over file arguments */ 18 | 19 | int 20 | main(int argc, char **argv) 21 | { 22 | int i; 23 | int errs = 0; 24 | 25 | myname = argv[0]; 26 | 27 | if (argc == 1) 28 | errs = process("-"); 29 | else 30 | for (i = 1; i < argc; i++) 31 | errs += process(argv[i]); 32 | 33 | return (errs != 0); 34 | } 35 | 36 | /* 37 | * process --- do something with the file, in this case, 38 | * send it to stdout (fd 1). 39 | * Returns 0 if all OK, 1 otherwise. 40 | */ 41 | 42 | int 43 | process(char *file) 44 | { 45 | int fd; 46 | ssize_t rcount, wcount; 47 | char buffer[BUFSIZ]; 48 | int errors = 0; 49 | 50 | if (strcmp(file, "-") == 0) 51 | fd = 0; 52 | else if ((fd = open(file, O_RDONLY)) < 0) { 53 | fprintf(stderr, "%s: %s: cannot open for reading: %s\n", 54 | myname, file, strerror(errno)); 55 | return 1; 56 | } 57 | 58 | while ((rcount = read(fd, buffer, sizeof buffer)) > 0) { 59 | wcount = write(1, buffer, rcount); 60 | if (wcount != rcount) { 61 | fprintf(stderr, "%s: %s: write error: %s\n", 62 | myname, file, strerror(errno)); 63 | errors++; 64 | break; 65 | } 66 | } 67 | 68 | if (rcount < 0) { 69 | fprintf(stderr, "%s: %s: read error: %s\n", 70 | myname, file, strerror(errno)); 71 | errors++; 72 | } 73 | 74 | if (fd != 0) { 75 | if (close(fd) < 0) { 76 | fprintf(stderr, "%s: %s: close error: %s\n", 77 | myname, file, strerror(errno)); 78 | errors++; 79 | } 80 | } 81 | 82 | return (errors != 0); 83 | } 84 | -------------------------------------------------------------------------------- /book/ch04/ch04-holes.c: -------------------------------------------------------------------------------- 1 | /* ch04-holes.c --- Demonstrate lseek() and holes in files. */ 2 | 3 | #include /* for fprintf(), stderr, BUFSIZ */ 4 | #include /* declare errno */ 5 | #include /* for flags for open() */ 6 | #include /* declare strerror() */ 7 | #include /* for ssize_t */ 8 | #include /* for off_t, etc. */ 9 | #include /* for mode_t */ 10 | 11 | struct person { 12 | char name[10]; /* first name */ 13 | char id[10]; /* ID number */ 14 | off_t pos; /* position in file, for demonstration */ 15 | } people[] = { 16 | { "arnold", "123456789", 0 }, 17 | { "miriam", "987654321", 10240 }, 18 | { "joe", "192837465", 81920 }, 19 | }; 20 | 21 | int 22 | main(int argc, char **argv) 23 | { 24 | int fd; 25 | int i, j; 26 | 27 | if (argc < 2) { 28 | fprintf(stderr, "usage: %s file\n", argv[0]); 29 | return 1; 30 | } 31 | 32 | fd = open(argv[1], O_RDWR|O_CREAT|O_TRUNC, 0666); 33 | if (fd < 0) { 34 | fprintf(stderr, "%s: %s: cannot open for read/write: %s\n", 35 | argv[0], argv[1], strerror(errno)); 36 | return 1; 37 | } 38 | 39 | j = sizeof(people) / sizeof(people[0]); /* count of elements */ 40 | 41 | for (i = 0; i < j; i++) { 42 | if (lseek(fd, people[i].pos, SEEK_SET) < 0) { 43 | fprintf(stderr, "%s: %s: seek error: %s\n", 44 | argv[0], argv[1], strerror(errno)); 45 | (void) close(fd); 46 | return 1; 47 | } 48 | 49 | if (write(fd, &people[i], sizeof(people[i])) != sizeof(people[i])) { 50 | fprintf(stderr, "%s: %s: write error: %s\n", 51 | argv[0], argv[1], strerror(errno)); 52 | (void) close(fd); 53 | return 1; 54 | } 55 | } 56 | 57 | /* all ok here */ 58 | (void) close(fd); 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /book/ch04/ch04-maxfds.c: -------------------------------------------------------------------------------- 1 | /* ch04-maxfds.c --- Demonstrate getdtablesize(). */ 2 | 3 | #include /* for fprintf(), stderr, BUFSIZ */ 4 | #include /* for ssize_t */ 5 | 6 | int 7 | main(int argc, char **argv) 8 | { 9 | printf("max fds: %d\n", getdtablesize()); 10 | exit(0); 11 | } 12 | -------------------------------------------------------------------------------- /book/ch05/ch05-catdir.c: -------------------------------------------------------------------------------- 1 | /* ch05-catdir.c --- Demonstrate opendir(), readdir(), closedir(). */ 2 | 3 | #include /* for printf() etc. */ 4 | #include /* for errno */ 5 | #include /* for system types */ 6 | #include /* for directory functions */ 7 | 8 | char *myname; 9 | int process(char *dir); 10 | 11 | /* main --- loop over directory arguments */ 12 | 13 | int main(int argc, char **argv) 14 | { 15 | int i; 16 | int errs = 0; 17 | 18 | myname = argv[0]; 19 | 20 | if (argc == 1) 21 | errs = process("."); /* default to current directory */ 22 | else 23 | for (i = 1; i < argc; i++) 24 | errs += process(argv[i]); 25 | 26 | return (errs != 0); 27 | } 28 | 29 | /* 30 | * process --- do something with the directory, in this case, 31 | * print inode/name pairs on standard output. 32 | * Returns 0 if all ok, 1 otherwise. 33 | */ 34 | 35 | int 36 | process(char *dir) 37 | { 38 | DIR *dp; 39 | struct dirent *ent; 40 | 41 | if ((dp = opendir(dir)) == NULL) { 42 | fprintf(stderr, "%s: %s: cannot open for reading: %s\n", 43 | myname, dir, strerror(errno)); 44 | return 1; 45 | } 46 | 47 | errno = 0; 48 | while ((ent = readdir(dp)) != NULL) 49 | printf("%8ld %s\n", ent->d_ino, ent->d_name); 50 | 51 | if (errno != 0) { 52 | fprintf(stderr, "%s: %s: reading directory entries: %s\n", 53 | myname, dir, strerror(errno)); 54 | return 1; 55 | } 56 | 57 | if (closedir(dp) != 0) { 58 | fprintf(stderr, "%s: %s: closedir: %s\n", 59 | myname, dir, strerror(errno)); 60 | return 1; 61 | } 62 | 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /book/ch05/ch05-devnum.c: -------------------------------------------------------------------------------- 1 | /* ch05-devnum.c --- Demonstrate stat(), major(), minor(). */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | int main(int argc, char **argv) 10 | { 11 | struct stat sbuf; 12 | char *devtype; 13 | 14 | if (argc != 2) { 15 | fprintf(stderr, "usage: %s path\n", argv[0]); 16 | exit(1); 17 | } 18 | 19 | if (stat(argv[1], & sbuf) < 0) { 20 | fprintf(stderr, "%s: stat: %s\n", argv[1], strerror(errno)); 21 | exit(1); 22 | } 23 | 24 | if (S_ISCHR(sbuf.st_mode)) 25 | devtype = "char"; 26 | else if (S_ISBLK(sbuf.st_mode)) 27 | devtype = "block"; 28 | else { 29 | fprintf(stderr, "%s is not a block or character device\n", argv[1]); 30 | exit(1); 31 | } 32 | 33 | printf("%s: major: %d, minor: %d\n", devtype, 34 | major(sbuf.st_rdev), minor(sbuf.st_rdev)); 35 | 36 | exit(0); 37 | } 38 | -------------------------------------------------------------------------------- /book/ch05/ch05-trymkdir.c: -------------------------------------------------------------------------------- 1 | /* ch05-trymkdir.c --- Demonstrate mkdir() behavior. 2 | Courtesy of Nelson H.F. Beebe. */ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #if !defined(EXIT_SUCCESS) 9 | #define EXIT_SUCCESS 0 10 | #endif 11 | 12 | void do_test(const char *path) 13 | { 14 | int retcode; 15 | 16 | errno = 0; 17 | retcode = mkdir(path, 0755); 18 | printf("mkdir(\"%s\") returns %d: errno = %d [%s]\n", 19 | path, retcode, errno, strerror(errno)); 20 | } 21 | 22 | int main(void) 23 | { 24 | do_test("/tmp/t1/t2/t3/t4"); 25 | do_test("/tmp/t1/t2/t3"); 26 | do_test("/tmp/t1/t2"); 27 | do_test("/tmp/t1"); 28 | 29 | do_test("/tmp/u1"); 30 | do_test("/tmp/u1/u2"); 31 | do_test("/tmp/u1/u2/u3"); 32 | do_test("/tmp/u1/u2/u3/u4"); 33 | 34 | do_test("/tmp/v1/"); 35 | do_test("/tmp/v1/v2/"); 36 | do_test("/tmp/v1/v2/v3/"); 37 | do_test("/tmp/v1/v2/v3/v4/"); 38 | 39 | return (EXIT_SUCCESS); 40 | } 41 | -------------------------------------------------------------------------------- /book/ch06/ch06-echodate.c: -------------------------------------------------------------------------------- 1 | /* ch06-echodate.c --- demonstrate mktime(). */ 2 | 3 | #include 4 | #include 5 | 6 | int main(void) 7 | { 8 | struct tm tm; 9 | time_t then; 10 | 11 | printf("Enter a Date/time as YYYY/MM/DD HH:MM:SS : "); 12 | scanf("%d/%d/%d %d:%d:%d", 13 | & tm.tm_year, & tm.tm_mon, & tm.tm_mday, 14 | & tm.tm_hour, & tm.tm_min, & tm.tm_sec); 15 | 16 | /* Error checking on values omitted for brevity. */ 17 | tm.tm_year -= 1900; 18 | tm.tm_mon--; 19 | 20 | tm.tm_isdst = -1; /* Don't know about DST */ 21 | 22 | then = mktime(& tm); 23 | 24 | printf("Got: %s", ctime(& then)); 25 | exit(0); 26 | } 27 | -------------------------------------------------------------------------------- /book/ch06/ch06-groupinfo.c: -------------------------------------------------------------------------------- 1 | /* ch06-groupinfo.c --- Demonstrate getgrent() and struct group */ 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | extern void print_group(const struct group *gr); 8 | 9 | /* main --- print group lines for user named in argv[1] */ 10 | 11 | int 12 | main(int argc, char **argv) 13 | { 14 | struct group *gr; 15 | int i; 16 | 17 | if (argc != 2) { 18 | fprintf(stderr, "usage: %s user\n", argv[0]); 19 | exit(1); 20 | } 21 | 22 | while ((gr = getgrent()) != NULL) 23 | for (i = 0; gr->gr_mem[i] != NULL; i++) 24 | if (strcmp(gr->gr_mem[i], argv[1]) == 0) 25 | print_group(gr); 26 | 27 | endgrent(); 28 | 29 | exit(0); 30 | } 31 | 32 | /* print_group --- print a group record */ 33 | 34 | void 35 | print_group(const struct group *gr) 36 | { 37 | int i; 38 | 39 | printf("%s:%s:%ld:", gr->gr_name, gr->gr_passwd, (long) gr->gr_gid); 40 | 41 | for (i = 0; gr->gr_mem[i] != NULL; i++) { 42 | printf("%s", gr->gr_mem[i]); 43 | if (gr->gr_mem[i+1] != NULL) 44 | putchar(','); 45 | } 46 | 47 | putchar('\n'); 48 | } 49 | -------------------------------------------------------------------------------- /book/ch06/ch06-searchemp.c: -------------------------------------------------------------------------------- 1 | /* ch06-searchemp.c --- Demonstrate bsearch(). */ 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | struct employee { 8 | char lastname[30]; 9 | char firstname[30]; 10 | long emp_id; 11 | time_t start_date; 12 | }; 13 | 14 | /* emp_id_compare --- compare by ID */ 15 | 16 | int emp_id_compare(const void *e1p, const void *e2p) 17 | { 18 | const struct employee *e1, *e2; 19 | 20 | e1 = (const struct employee *) e1p; 21 | e2 = (const struct employee *) e2p; 22 | 23 | if (e1->emp_id < e2->emp_id) 24 | return -1; 25 | else if (e1->emp_id == e2->emp_id) 26 | return 0; 27 | else 28 | return 1; 29 | } 30 | 31 | /* print_employee --- print an employee structure */ 32 | 33 | void print_employee(const struct employee *emp) 34 | { 35 | printf("%s %s\t%d\t%s", emp->lastname, emp->firstname, 36 | emp->emp_id, ctime(& emp->start_date)); 37 | } 38 | 39 | /* main --- demonstrate sorting */ 40 | 41 | int main(int argc, char **argv) 42 | { 43 | #define NPRES 10 44 | struct employee presidents[NPRES]; 45 | int i, npres; 46 | char buf[BUFSIZ]; 47 | struct employee *the_pres; 48 | struct employee key; 49 | int id; 50 | FILE *fp; 51 | 52 | if (argc != 2) { 53 | fprintf(stderr, "usage: %s datafile\n", argv[0]); 54 | exit(1); 55 | } 56 | 57 | if ((fp = fopen(argv[1], "r")) == NULL) { 58 | fprintf(stderr, "%s: %s: could not open: %s\n", argv[0], 59 | argv[1], strerror(errno)); 60 | exit(1); 61 | } 62 | 63 | /* Very simple code to read data: */ 64 | for (npres = 0; npres < NPRES && fgets(buf, BUFSIZ, fp) != NULL; 65 | npres++) { 66 | sscanf(buf, "%s %s %ld %ld", 67 | presidents[npres].lastname, 68 | presidents[npres].firstname, 69 | & presidents[npres].emp_id, 70 | & presidents[npres].start_date); 71 | } 72 | fclose(fp); 73 | 74 | /* npres is now number of actual lines read. */ 75 | 76 | /* First, sort by id */ 77 | qsort(presidents, npres, sizeof(struct employee), emp_id_compare); 78 | 79 | /* Print output */ 80 | printf("Sorted by ID:\n"); 81 | for (i = 0; i < npres; i++) { 82 | putchar('\t'); 83 | print_employee(& presidents[i]); 84 | } 85 | 86 | for (;;) { 87 | printf("Enter ID number: "); 88 | if (fgets(buf, BUFSIZ, stdin) == NULL) 89 | break; 90 | 91 | sscanf(buf, "%d\n", & id); 92 | key.emp_id = id; 93 | the_pres = (struct employee *) bsearch(& key, presidents, npres, 94 | sizeof(struct employee), emp_id_compare); 95 | 96 | if (the_pres != NULL) { 97 | printf("Found: "); 98 | print_employee(the_pres); 99 | } else 100 | printf("Employee with ID %d not found!\n", id); 101 | } 102 | 103 | putchar('\n'); /* Print a newline on EOF. */ 104 | 105 | exit(0); 106 | } 107 | -------------------------------------------------------------------------------- /book/ch06/ch06-sortdir.c: -------------------------------------------------------------------------------- 1 | /* ch06-sortdir.c --- Demonstrate scandir(), alphasort(). */ 2 | 3 | #include /* for printf() etc. */ 4 | #include /* for errno */ 5 | #include /* for system types */ 6 | #include /* for directory functions */ 7 | 8 | char *myname; 9 | int process(const char *dir); 10 | 11 | /* main --- loop over directory arguments */ 12 | 13 | int main(int argc, char **argv) 14 | { 15 | int i; 16 | int errs = 0; 17 | 18 | myname = argv[0]; 19 | 20 | if (argc == 1) 21 | errs = process("."); /* default to current directory */ 22 | else 23 | for (i = 1; i < argc; i++) 24 | errs += process(argv[i]); 25 | 26 | return (errs != 0); 27 | } 28 | 29 | /* nodots --- ignore dot files, for use by scandir() */ 30 | 31 | int 32 | nodots(const struct dirent *dp) 33 | { 34 | return (dp->d_name[0] != '.'); 35 | } 36 | 37 | /* 38 | * process --- do something with the directory, in this case, 39 | * print inode/name pairs on standard output. 40 | * Return 0 if all OK, 1 otherwise. 41 | */ 42 | 43 | int 44 | process(const char *dir) 45 | { 46 | DIR *dp; 47 | struct dirent **entries; 48 | int nents, i; 49 | 50 | nents = scandir(dir, & entries, nodots, alphasort); 51 | if (nents < 0) { 52 | fprintf(stderr, "%s: scandir failed: %s\n", myname, 53 | strerror(errno)); 54 | return 1; 55 | } 56 | 57 | for (i = 0; i < nents; i++) { 58 | printf("%8ld %s\n", entries[i]->d_ino, entries[i]->d_name); 59 | free(entries[i]); 60 | } 61 | 62 | free(entries); 63 | 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /book/ch06/ch06-sortemp.c: -------------------------------------------------------------------------------- 1 | /* ch06-sortemp.c --- Demonstrate qsort() with two comparison functions. */ 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | struct employee { 8 | char lastname[30]; 9 | char firstname[30]; 10 | long emp_id; 11 | time_t start_date; 12 | }; 13 | 14 | /* emp_name_id_compare --- compare by name, then by ID */ 15 | 16 | int emp_name_id_compare(const void *e1p, const void *e2p) 17 | { 18 | const struct employee *e1, *e2; 19 | int last, first; 20 | 21 | e1 = (const struct employee *) e1p; 22 | e2 = (const struct employee *) e2p; 23 | 24 | if ((last = strcmp(e1->lastname, e2->lastname)) != 0) 25 | return last; 26 | 27 | /* same last name, check first name */ 28 | if ((first = strcmp(e1->firstname, e2->firstname)) != 0) 29 | return first; 30 | 31 | /* same first name, check ID numbers */ 32 | if (e1->emp_id < e2->emp_id) 33 | return -1; 34 | else if (e1->emp_id == e2->emp_id) 35 | return 0; 36 | else 37 | return 1; 38 | 39 | } 40 | 41 | /* emp_seniority_compare --- compare by seniority */ 42 | 43 | int emp_seniority_compare(const void *e1p, const void *e2p) 44 | { 45 | const struct employee *e1, *e2; 46 | double diff; 47 | 48 | e1 = (const struct employee *) e1p; 49 | e2 = (const struct employee *) e2p; 50 | 51 | diff = difftime(e1->start_date, e2->start_date); 52 | if (diff < 0.0) 53 | return -1; 54 | else if (diff > 0.0) 55 | return 1; 56 | else 57 | return 0; 58 | } 59 | 60 | /* main --- demonstrate sorting */ 61 | 62 | int main(void) 63 | { 64 | #define NPRES 10 65 | struct employee presidents[NPRES]; 66 | int i, npres; 67 | char buf[BUFSIZ]; 68 | 69 | /* Very simple code to read data: */ 70 | for (npres = 0; npres < NPRES && fgets(buf, BUFSIZ, stdin) != NULL; 71 | npres++) { 72 | sscanf(buf, "%s %s %ld %ld\n", 73 | presidents[npres].lastname, 74 | presidents[npres].firstname, 75 | & presidents[npres].emp_id, 76 | & presidents[npres].start_date); 77 | } 78 | 79 | /* npres is now number of actual lines read. */ 80 | 81 | /* First, sort by name */ 82 | qsort(presidents, npres, sizeof(struct employee), emp_name_id_compare); 83 | 84 | /* Print output */ 85 | printf("Sorted by name:\n"); 86 | for (i = 0; i < npres; i++) 87 | printf("\t%s %s\t%d\t%s", 88 | presidents[i].lastname, 89 | presidents[i].firstname, 90 | presidents[i].emp_id, 91 | ctime(& presidents[i].start_date)); 92 | 93 | /* Now, sort by seniority */ 94 | qsort(presidents, npres, sizeof(struct employee), emp_seniority_compare); 95 | 96 | /* And print again */ 97 | printf("Sorted by seniority:\n"); 98 | for (i = 0; i < npres; i++) 99 | printf("\t%s %s\t%d\t%s", 100 | presidents[i].lastname, 101 | presidents[i].firstname, 102 | presidents[i].emp_id, 103 | ctime(& presidents[i].start_date)); 104 | } 105 | -------------------------------------------------------------------------------- /book/ch06/presdata.txt: -------------------------------------------------------------------------------- 1 | Bush George 43 980013600 2 | Clinton William 42 727552800 3 | Bush George 41 601322400 4 | Reagan Ronald 40 348861600 5 | Carter James 39 222631200 6 | -------------------------------------------------------------------------------- /book/ch08/ch08-chdir.c: -------------------------------------------------------------------------------- 1 | /* ch08-chdir.c --- demonstrate chdir() and fchdir(). 2 | Error checking omitted for brevity */ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | int main(void) 11 | { 12 | int fd; 13 | struct stat sbuf; 14 | 15 | fd = open(".", O_RDONLY); /* open directory for reading */ 16 | fstat(fd, & sbuf); /* obtain info, need original permissions */ 17 | chdir(".."); /* `cd ..' */ 18 | fchmod(fd, 0); /* zap permissions on original directory */ 19 | 20 | if (fchdir(fd) < 0) /* try to `cd' back, should fail */ 21 | perror("fchdir back"); 22 | 23 | fchmod(fd, sbuf.st_mode & 07777); /* restore original permissions */ 24 | close(fd); /* all done */ 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /book/ch08/ch08-getcwd.c: -------------------------------------------------------------------------------- 1 | /* ch08-getcwd.c --- demonstrate getcwd(). 2 | Error checking omitted for brevity */ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | int main(void) 11 | { 12 | char buf[BUFSIZ]; 13 | char *cp; 14 | 15 | cp = getcwd(buf, sizeof(buf)); 16 | printf("Current dir: %s\n", buf); 17 | 18 | printf("Changing to ..\n"); 19 | chdir(".."); /* `cd ..' */ 20 | 21 | cp = getcwd(buf, sizeof(buf)); 22 | printf("Current dir is now: %s\n", buf); 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /book/ch08/ch08-mounted.c: -------------------------------------------------------------------------------- 1 | /* ch08-mounted.c --- print a list of mounted filesystems */ 2 | 3 | /* NOTE: GNU/Linux specific! */ 4 | 5 | #include 6 | #include 7 | #include /* for getmntent(), et al. */ 8 | #include /* for getopt() */ 9 | 10 | void process(const char *filename); 11 | void print_mount(const struct mntent *fs); 12 | 13 | char *myname; 14 | 15 | /* main --- process options */ 16 | 17 | int main(int argc, char **argv) 18 | { 19 | int c; 20 | char *file = "/etc/mtab"; /* default file to read */ 21 | 22 | myname = argv[0]; 23 | while ((c = getopt(argc, argv, "f:")) != -1) { 24 | switch (c) { 25 | case 'f': 26 | file = optarg; 27 | break; 28 | default: 29 | fprintf(stderr, "usage: %s [-f fstab-file]\n", argv[0]); 30 | exit(1); 31 | } 32 | } 33 | 34 | process(file); 35 | return 0; 36 | } 37 | 38 | /* process --- read struct mntent structures from file */ 39 | 40 | void process(const char *filename) 41 | { 42 | FILE *fp; 43 | struct mntent *fs; 44 | 45 | fp = setmntent(filename, "r"); /* read only */ 46 | if (fp == NULL) { 47 | fprintf(stderr, "%s: %s: could not open: %s\n", 48 | myname, filename, strerror(errno)); 49 | exit(1); 50 | } 51 | 52 | while ((fs = getmntent(fp)) != NULL) 53 | print_mount(fs); 54 | 55 | endmntent(fp); 56 | } 57 | 58 | /* print_mount --- print a single mount entry */ 59 | 60 | void print_mount(const struct mntent *fs) 61 | { 62 | printf("%s %s %s %s %d %d\n", 63 | fs->mnt_fsname, 64 | fs->mnt_dir, 65 | fs->mnt_type, 66 | fs->mnt_opts, 67 | fs->mnt_freq, 68 | fs->mnt_passno); 69 | } 70 | -------------------------------------------------------------------------------- /book/ch08/ch08-nftw.c: -------------------------------------------------------------------------------- 1 | /* ch08-nftw.c --- demonstrate nftw() */ 2 | 3 | #define _XOPEN_SOURCE 1 /* Required under GLIBC for nftw() */ 4 | #define _XOPEN_SOURCE_EXTENDED 1 /* Same */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include /* gets and for us */ 10 | #include /* for PATH_MAX */ 11 | #include /* for getdtablesize(), getcwd() declarations */ 12 | 13 | #define SPARE_FDS 5 /* fds for use by other functions, see text */ 14 | 15 | extern int process(const char *file, const struct stat *sb, 16 | int flag, struct FTW *s); 17 | 18 | /* usage --- print message and die */ 19 | 20 | void usage(const char *name) 21 | { 22 | fprintf(stderr, "usage: %s [-c] directory ...\n", name); 23 | exit(1); 24 | } 25 | 26 | /* main --- call nftw() on each command-line argument */ 27 | 28 | int main(int argc, char **argv) 29 | { 30 | int i, c, nfds; 31 | int errors = 0; 32 | int flags = FTW_PHYS; 33 | char start[PATH_MAX], finish[PATH_MAX]; 34 | 35 | while ((c = getopt(argc, argv, "c")) != -1) { 36 | switch (c) { 37 | case 'c': 38 | flags |= FTW_CHDIR; 39 | break; 40 | default: 41 | usage(argv[0]); 42 | break; 43 | } 44 | } 45 | 46 | if (optind == argc) 47 | usage(argv[0]); 48 | 49 | getcwd(start, sizeof start); 50 | 51 | nfds = getdtablesize() - SPARE_FDS; /* leave some spare descriptors */ 52 | for (i = optind; i < argc; i++) { 53 | if (nftw(argv[i], process, nfds, flags) != 0) { 54 | fprintf(stderr, "%s: %s: stopped early\n", 55 | argv[0], argv[i]); 56 | errors++; 57 | } 58 | } 59 | 60 | if ((flags & FTW_CHDIR) != 0) { 61 | getcwd(finish, sizeof finish); 62 | printf("Starting dir: %s\n", start); 63 | printf("Finishing dir: %s\n", finish); 64 | } 65 | 66 | return (errors != 0); 67 | } 68 | 69 | /* process --- print out each file at the right level */ 70 | 71 | int process(const char *file, const struct stat *sb, 72 | int flag, struct FTW *s) 73 | { 74 | int retval = 0; 75 | const char *name = file + s->base; 76 | 77 | printf("%*s", s->level * 4, ""); /* indent over */ 78 | 79 | switch (flag) { 80 | case FTW_F: 81 | printf("%s (file)\n", name); 82 | break; 83 | case FTW_D: 84 | printf("%s (directory)\n", name); 85 | break; 86 | case FTW_DNR: 87 | printf("%s (unreadable directory)\n", name); 88 | break; 89 | case FTW_SL: 90 | printf("%s (symbolic link)\n", name); 91 | break; 92 | case FTW_NS: 93 | printf("%s (stat failed): %s\n", name, strerror(errno)); 94 | break; 95 | case FTW_DP: 96 | case FTW_SLN: 97 | printf("%s: FTW_DP or FTW_SLN: can't happen!\n", name); 98 | retval = 1; 99 | break; 100 | default: 101 | printf("%s: unknown flag %d: can't happen!\n", name, flag); 102 | retval = 1; 103 | break; 104 | } 105 | 106 | return retval; 107 | } 108 | -------------------------------------------------------------------------------- /book/ch08/ch08-statfs.c: -------------------------------------------------------------------------------- 1 | /* ch08-statfs.c --- demonstrate Linux statfs */ 2 | 3 | /* NOTE: GNU/Linux specific! */ 4 | 5 | #include 6 | #include 7 | #include /* for getmntent(), et al. */ 8 | #include /* for getopt() */ 9 | #include 10 | #include 11 | 12 | /* Defines taken from statfs(2) man page: */ 13 | #define AFFS_SUPER_MAGIC 0xADFF 14 | #define EFS_SUPER_MAGIC 0x00414A53 15 | #define EXT_SUPER_MAGIC 0x137D 16 | #define EXT2_OLD_SUPER_MAGIC 0xEF51 17 | #define EXT2_SUPER_MAGIC 0xEF53 18 | #define HPFS_SUPER_MAGIC 0xF995E849 19 | #define ISOFS_SUPER_MAGIC 0x9660 20 | #define MINIX_SUPER_MAGIC 0x137F /* orig. minix */ 21 | #define MINIX_SUPER_MAGIC2 0x138F /* 30-char minix */ 22 | #define MINIX2_SUPER_MAGIC 0x2468 /* minix V2 */ 23 | #define MINIX2_SUPER_MAGIC2 0x2478 /* minix V2, 30 char names */ 24 | #define MSDOS_SUPER_MAGIC 0x4d44 25 | #define NCP_SUPER_MAGIC 0x564c 26 | #define NFS_SUPER_MAGIC 0x6969 27 | #define PROC_SUPER_MAGIC 0x9fa0 28 | #define SMB_SUPER_MAGIC 0x517B 29 | #define XENIX_SUPER_MAGIC 0x012FF7B4 30 | #define SYSV4_SUPER_MAGIC 0x012FF7B5 31 | #define SYSV2_SUPER_MAGIC 0x012FF7B6 32 | #define COH_SUPER_MAGIC 0x012FF7B7 33 | #define UFS_MAGIC 0x00011954 34 | #define XFS_SUPER_MAGIC 0x58465342 35 | #define _XIAFS_SUPER_MAGIC 0x012FD16D 36 | 37 | void process(const char *filename); 38 | void do_statfs(const struct mntent *fs); 39 | 40 | int errors = 0; 41 | char *myname; 42 | 43 | /* main --- process options */ 44 | 45 | int main(int argc, char **argv) 46 | { 47 | int c; 48 | char *file = "/etc/mtab"; /* default file to read */ 49 | 50 | myname = argv[0]; 51 | while ((c = getopt(argc, argv, "f:")) != -1) { 52 | switch (c) { 53 | case 'f': 54 | file = optarg; 55 | break; 56 | default: 57 | fprintf(stderr, "usage: %s [-f fstab-file]\n", argv[0]); 58 | exit(1); 59 | } 60 | } 61 | 62 | process(file); 63 | return (errors != 0); 64 | } 65 | 66 | /* process --- read struct mntent structures from file */ 67 | 68 | void process(const char *filename) 69 | { 70 | FILE *fp; 71 | struct mntent *fs; 72 | 73 | fp = setmntent(filename, "r"); /* read only */ 74 | if (fp == NULL) { 75 | fprintf(stderr, "%s: %s: could not open: %s\n", 76 | myname, filename, strerror(errno)); 77 | exit(1); 78 | } 79 | 80 | while ((fs = getmntent(fp)) != NULL) 81 | do_statfs(fs); 82 | 83 | endmntent(fp); 84 | } 85 | 86 | /* type2str --- convert fs type to printable string, from statfs(2) */ 87 | 88 | const char *type2str(long type) 89 | { 90 | static struct fsname { 91 | long type; 92 | const char *name; 93 | } table[] = { 94 | { AFFS_SUPER_MAGIC, "AFFS" }, 95 | { COH_SUPER_MAGIC, "COH" }, 96 | { EXT2_OLD_SUPER_MAGIC, "OLD EXT2" }, 97 | { EXT2_SUPER_MAGIC, "EXT2" }, 98 | { HPFS_SUPER_MAGIC, "HPFS" }, 99 | { ISOFS_SUPER_MAGIC, "ISOFS" }, 100 | { MINIX2_SUPER_MAGIC, "MINIX V2" }, 101 | { MINIX2_SUPER_MAGIC2, "MINIX V2 30 char" }, 102 | { MINIX_SUPER_MAGIC, "MINIX" }, 103 | { MINIX_SUPER_MAGIC2, "MINIX 30 char" }, 104 | { MSDOS_SUPER_MAGIC, "MSDOS" }, 105 | { NCP_SUPER_MAGIC, "NCP" }, 106 | { NFS_SUPER_MAGIC, "NFS" }, 107 | { PROC_SUPER_MAGIC, "PROC" }, 108 | { SMB_SUPER_MAGIC, "SMB" }, 109 | { SYSV2_SUPER_MAGIC, "SYSV2" }, 110 | { SYSV4_SUPER_MAGIC, "SYSV4" }, 111 | { UFS_MAGIC, "UFS" }, 112 | { XENIX_SUPER_MAGIC, "XENIX" }, 113 | { _XIAFS_SUPER_MAGIC, "XIAFS" }, 114 | { 0, NULL }, 115 | }; 116 | static char unknown[100]; 117 | int i; 118 | 119 | for (i = 0; table[i].type != 0; i++) 120 | if (table[i].type == type) 121 | return table[i].name; 122 | 123 | sprintf(unknown, "unknown type: %#x", type); 124 | return unknown; 125 | } 126 | 127 | /* do_statfs --- Use statfs and print info */ 128 | 129 | void do_statfs(const struct mntent *fs) 130 | { 131 | struct statfs vfs; 132 | 133 | if (fs->mnt_fsname[0] != '/') /* skip nonreal filesystems */ 134 | return; 135 | 136 | if (statfs(fs->mnt_dir, & vfs) != 0) { 137 | fprintf(stderr, "%s: %s: statfs failed: %s\n", 138 | myname, fs->mnt_dir, strerror(errno)); 139 | errors++; 140 | return; 141 | } 142 | 143 | printf("%s, mounted on %s:\n", fs->mnt_dir, fs->mnt_fsname); 144 | 145 | printf("\tf_type: %s\n", type2str(vfs.f_type)); 146 | printf("\tf_bsize: %ld\n", vfs.f_bsize); 147 | printf("\tf_blocks: %ld\n", vfs.f_blocks); 148 | printf("\tf_bfree: %ld\n", vfs.f_bfree); 149 | printf("\tf_bavail: %ld\n", vfs.f_bavail); 150 | printf("\tf_files: %ld\n", vfs.f_files); 151 | printf("\tf_ffree: %ld\n", vfs.f_ffree); 152 | printf("\tf_namelen: %ld\n", vfs.f_namelen); 153 | } 154 | -------------------------------------------------------------------------------- /book/ch08/ch08-statvfs.c: -------------------------------------------------------------------------------- 1 | /* ch08-statvfs.c --- demonstrate statvfs */ 2 | 3 | /* NOTE: GNU/Linux specific! */ 4 | 5 | #include 6 | #include 7 | #include /* for getmntent(), et al. */ 8 | #include /* for getopt() */ 9 | #include 10 | #include 11 | 12 | void process(const char *filename); 13 | void do_statvfs(const struct mntent *fs); 14 | 15 | int errors = 0; 16 | char *myname; 17 | 18 | /* main --- process options */ 19 | 20 | int main(int argc, char **argv) 21 | { 22 | int c; 23 | char *file = "/etc/mtab"; /* default file to read */ 24 | 25 | myname = argv[0]; 26 | while ((c = getopt(argc, argv, "f:")) != -1) { 27 | switch (c) { 28 | case 'f': 29 | file = optarg; 30 | break; 31 | default: 32 | fprintf(stderr, "usage: %s [-f fstab-file]\n", argv[0]); 33 | exit(1); 34 | } 35 | } 36 | 37 | process(file); 38 | return (errors != 0); 39 | } 40 | 41 | /* process --- read struct mntent structures from file */ 42 | 43 | void process(const char *filename) 44 | { 45 | FILE *fp; 46 | struct mntent *fs; 47 | 48 | fp = setmntent(filename, "r"); /* read only */ 49 | if (fp == NULL) { 50 | fprintf(stderr, "%s: %s: could not open: %s\n", 51 | myname, filename, strerror(errno)); 52 | exit(1); 53 | } 54 | 55 | while ((fs = getmntent(fp)) != NULL) 56 | do_statvfs(fs); 57 | 58 | endmntent(fp); 59 | } 60 | 61 | /* do_statvfs --- Use statvfs and print info */ 62 | 63 | void do_statvfs(const struct mntent *fs) 64 | { 65 | struct statvfs vfs; 66 | 67 | if (fs->mnt_fsname[0] != '/') /* skip nonreal filesystems */ 68 | return; 69 | 70 | if (statvfs(fs->mnt_dir, & vfs) != 0) { 71 | fprintf(stderr, "%s: %s: statvfs failed: %s\n", 72 | myname, fs->mnt_dir, strerror(errno)); 73 | errors++; 74 | return; 75 | } 76 | 77 | printf("%s, mounted on %s:\n", fs->mnt_dir, fs->mnt_fsname); 78 | printf("\tf_bsize: %ld\n", (long) vfs.f_bsize); 79 | printf("\tf_frsize: %ld\n", (long) vfs.f_frsize); 80 | printf("\tf_blocks: %lu\n", (unsigned long) vfs.f_blocks); 81 | printf("\tf_bfree: %lu\n", (unsigned long) vfs.f_bfree); 82 | printf("\tf_bavail: %lu\n", (unsigned long) vfs.f_bavail); 83 | printf("\tf_files: %lu\n", (unsigned long) vfs.f_files); 84 | printf("\tf_ffree: %lu\n", (unsigned long) vfs.f_ffree); 85 | printf("\tf_favail: %lu\n", (unsigned long) vfs.f_favail); 86 | printf("\tf_fsid: %#lx\n", (unsigned long) vfs.f_fsid); 87 | 88 | printf("\tf_flag: "); 89 | if (vfs.f_flag == 0) 90 | printf("(none)\n"); 91 | else { 92 | if ((vfs.f_flag & ST_RDONLY) != 0) 93 | printf("ST_RDONLY "); 94 | if ((vfs.f_flag & ST_NOSUID) != 0) 95 | printf("ST_NOSUID"); 96 | printf("\n"); 97 | } 98 | 99 | printf("\tf_namemax: %#ld\n", (long)vfs.f_namemax); 100 | } 101 | -------------------------------------------------------------------------------- /book/ch09/ch09-atexit.c: -------------------------------------------------------------------------------- 1 | /* ch09-atexit.c --- demonstrate atexit(). 2 | Error checking omitted for brevity. */ 3 | 4 | /* 5 | * The callback functions here just answer roll call. 6 | * In a real application, they would do more. 7 | */ 8 | 9 | void callback1(void) { printf("callback1 called\n"); } 10 | void callback2(void) { printf("callback2 called\n"); } 11 | void callback3(void) { printf("callback3 called\n"); } 12 | 13 | /* main --- register functions and then exit */ 14 | 15 | int main(int argc, char **argv) 16 | { 17 | printf("registering callback1\n"); atexit(callback1); 18 | printf("registering callback2\n"); atexit(callback2); 19 | printf("registering callback3\n"); atexit(callback3); 20 | 21 | printf("exiting now\n"); 22 | exit(0); 23 | } 24 | -------------------------------------------------------------------------------- /book/ch09/ch09-pipedemo.c: -------------------------------------------------------------------------------- 1 | /* ch09-pipedemo.c --- demonstrate I/O with a pipe. */ 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | /* main --- create a pipe, write to it, and read from it. */ 8 | 9 | int main(int argc, char **argv) 10 | { 11 | static const char mesg[] = "Don't Panic!"; /* a famous message */ 12 | char buf[BUFSIZ]; 13 | ssize_t rcount, wcount; 14 | int pipefd[2]; 15 | size_t l; 16 | 17 | if (pipe(pipefd) < 0) { 18 | fprintf(stderr, "%s: pipe failed: %s\n", argv[0], 19 | strerror(errno)); 20 | exit(1); 21 | } 22 | 23 | printf("Read end = fd %d, write end = fd %d\n", 24 | pipefd[0], pipefd[1]); 25 | 26 | l = strlen(mesg); 27 | if ((wcount = write(pipefd[1], mesg, l)) != l) { 28 | fprintf(stderr, "%s: write failed: %s\n", argv[0], 29 | strerror(errno)); 30 | exit(1); 31 | } 32 | 33 | if ((rcount = read(pipefd[0], buf, BUFSIZ)) != wcount) { 34 | fprintf(stderr, "%s: read failed: %s\n", argv[0], 35 | strerror(errno)); 36 | exit(1); 37 | } 38 | 39 | buf[rcount] = '\0'; 40 | 41 | printf("Read <%s> from pipe\n", buf); 42 | (void) close(pipefd[0]); 43 | (void) close(pipefd[1]); 44 | 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /book/ch09/ch09-pipeline.c: -------------------------------------------------------------------------------- 1 | /* ch09-pipeline.c --- fork two processes into their own pipeline. 2 | Minimal error checking for brevity. */ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | int pipefd[2]; 11 | 12 | extern void left_child(void), right_child(void); 13 | 14 | /* main --- fork children, wait for them to finish */ 15 | 16 | int main(int argc, char **argv) 17 | { 18 | pid_t left_pid, right_pid; 19 | pid_t ret; 20 | int status; 21 | 22 | if (pipe(pipefd) < 0) { /* create pipe, very first thing */ 23 | perror("pipe"); 24 | exit(1); 25 | } 26 | 27 | if ((left_pid = fork()) < 0) { /* fork left-hand child */ 28 | perror("fork"); 29 | exit(1); 30 | } else if (left_pid == 0) 31 | left_child(); 32 | 33 | if ((right_pid = fork()) < 0) { /* fork right-hand child */ 34 | perror("fork"); 35 | exit(1); 36 | } else if (right_pid == 0) 37 | right_child(); 38 | 39 | close(pipefd[0]); /* close parent's copy of pipe */ 40 | close(pipefd[1]); 41 | 42 | while ((ret = wait(& status)) > 0) { /* wait for children */ 43 | if (ret == left_pid) 44 | printf("left child terminated, status: %x\n", status); 45 | else if (ret == right_pid) 46 | printf("right child terminated, status: %x\n", status); 47 | else 48 | printf("yow! unknown child %d terminated, status %x\n", 49 | ret, status); 50 | } 51 | 52 | return 0; 53 | } 54 | 55 | /* left_child --- do the work for the left child */ 56 | 57 | void left_child(void) 58 | { 59 | static char *left_argv[] = { "echo", "hi", "there", NULL }; 60 | 61 | close(pipefd[0]); 62 | close(1); 63 | dup(pipefd[1]); 64 | close(pipefd[1]); 65 | 66 | execvp("echo", left_argv); 67 | _exit(errno == ENOENT ? 127 : 126); 68 | } 69 | 70 | /* right_child --- do the work for the right child */ 71 | 72 | void right_child(void) 73 | { 74 | static char *right_argv[] = { "sed", "s/hi/hello/g", NULL }; 75 | 76 | close(pipefd[1]); 77 | close(0); 78 | dup(pipefd[0]); 79 | close(pipefd[0]); 80 | 81 | execvp("sed", right_argv); 82 | _exit(errno == ENOENT ? 127 : 126); 83 | } 84 | -------------------------------------------------------------------------------- /book/ch09/ch09-reparent.c: -------------------------------------------------------------------------------- 1 | /* ch09-reparent.c --- show that getppid() can change values */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | /* main --- do the work */ 9 | 10 | int main(int argc, char **argv) 11 | { 12 | pid_t pid, old_ppid, new_ppid; 13 | pid_t child, parent; 14 | 15 | parent = getpid(); /* before fork() */ 16 | 17 | if ((child = fork()) < 0) { 18 | fprintf(stderr, "%s: fork of child failed: %s\n", 19 | argv[0], strerror(errno)); 20 | exit(1); 21 | } else if (child == 0) { 22 | old_ppid = getppid(); 23 | sleep(2); /* see Chapter 10 */ 24 | new_ppid = getppid(); 25 | } else { 26 | sleep(1); 27 | exit(0); /* parent exits after fork() */ 28 | } 29 | 30 | /* only the child executes this */ 31 | printf("Original parent: %d\n", parent); 32 | printf("Child: %d\n", getpid()); 33 | printf("Child's old ppid: %d\n", old_ppid); 34 | printf("Child's new ppid: %d\n", new_ppid); 35 | 36 | exit(0); 37 | } 38 | -------------------------------------------------------------------------------- /book/ch09/ch09-run.c: -------------------------------------------------------------------------------- 1 | /* ch09-run.c --- run a program with a different name and any arguments */ 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | /* main --- adjust argv and run named program */ 8 | 9 | int main(int argc, char **argv) 10 | { 11 | char *path; 12 | 13 | if (argc < 3) { 14 | fprintf(stderr, "usage: %s path arg0 [ arg ... ]\n", argv[0]); 15 | exit(1); 16 | } 17 | 18 | path = argv[1]; 19 | 20 | execv(path, argv + 2); /* skip argv[0] and argv[1] */ 21 | 22 | fprintf(stderr, "%s: execv() failed: %s\n", argv[0], 23 | strerror(errno)); 24 | exit(1); 25 | } 26 | -------------------------------------------------------------------------------- /book/ch10/.ch11-catchcont.c.swp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perusio/linux-programming-by-example/4878093a8485d28cf5958a5e5b005e18fb3709c4/book/ch10/.ch11-catchcont.c.swp -------------------------------------------------------------------------------- /book/ch10/ch10-catchint.c: -------------------------------------------------------------------------------- 1 | /* ch10-catchint.c --- catch a SIGINT, at least once. */ 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | /* handler --- simple signal handler. */ 8 | 9 | void handler(int signum) 10 | { 11 | char buf[200], *cp; 12 | int offset; 13 | 14 | /* Jump through hoops to avoid fprintf(). */ 15 | strcpy(buf, "handler: caught signal "); 16 | cp = buf + strlen(buf); /* cp points at terminating '\0' */ 17 | if (signum > 100) /* unlikely */ 18 | offset = 3; 19 | else if (signum > 10) 20 | offset = 2; 21 | else 22 | offset = 1; 23 | cp += offset; 24 | 25 | *cp-- = '\0'; /* terminate string */ 26 | while (signum > 0) { /* work backwards, filling in digits */ 27 | *cp-- = (signum % 10) + '0'; 28 | signum /= 10; 29 | } 30 | strcat(buf, "\n"); 31 | (void) write(2, buf, strlen(buf)); 32 | } 33 | 34 | /* main --- set up signal handling and go into infinite loop */ 35 | 36 | int main(void) 37 | { 38 | (void) signal(SIGINT, handler); 39 | 40 | for (;;) 41 | pause(); /* wait for a signal, see later in the chapter */ 42 | 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /book/ch10/ch10-reap1.c: -------------------------------------------------------------------------------- 1 | /* ch10-reap1.c --- demonstrate SIGCHLD management, using a loop */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #define MAX_KIDS 42 11 | #define NOT_USED -1 12 | 13 | pid_t kids[MAX_KIDS]; 14 | size_t nkids = 0; 15 | 16 | /* format_num --- helper function since can't use [sf]printf() */ 17 | 18 | const char *format_num(int num) 19 | { 20 | #define NUMSIZ 30 21 | static char buf[NUMSIZ]; 22 | int i; 23 | 24 | if (num <= 0) { 25 | strcpy(buf, "0"); 26 | return buf; 27 | } 28 | 29 | i = NUMSIZ - 1; 30 | buf[i--] = '\0'; 31 | 32 | /* Generate digits backwards into string. */ 33 | do { 34 | buf[i--] = (num % 10) + '0'; 35 | num /= 10; 36 | } while (num > 0); 37 | 38 | return & buf[i+1]; 39 | } 40 | 41 | /* childhandler --- catch SIGCHLD, reap all available children */ 42 | 43 | void childhandler(int sig) 44 | { 45 | int status, ret; 46 | int i; 47 | char buf[100]; 48 | static const char entered[] = "Entered childhandler\n"; 49 | static const char exited[] = "Exited childhandler\n"; 50 | 51 | write(1, entered, strlen(entered)); 52 | for (i = 0; i < nkids; i++) { 53 | if (kids[i] == NOT_USED) 54 | continue; 55 | 56 | retry: 57 | if ((ret = waitpid(kids[i], & status, WNOHANG)) == kids[i]) { 58 | strcpy(buf, "\treaped process "); 59 | strcat(buf, format_num(ret)); 60 | strcat(buf, "\n"); 61 | write(1, buf, strlen(buf)); 62 | kids[i] = NOT_USED; 63 | } else if (ret == 0) { 64 | strcpy(buf, "\tpid "); 65 | strcat(buf, format_num(kids[i])); 66 | strcat(buf, " not available yet\n"); 67 | write(1, buf, strlen(buf)); 68 | } else if (ret == -1 && errno == EINTR) { 69 | write(1, "\tretrying\n", 10); 70 | goto retry; 71 | } else { 72 | strcpy(buf, "\twaitpid() failed: "); 73 | strcat(buf, strerror(errno)); 74 | strcat(buf, "\n"); 75 | write(1, buf, strlen(buf)); 76 | } 77 | } 78 | write(1, exited, strlen(exited)); 79 | } 80 | 81 | /* main --- set up child-related information and signals, create children */ 82 | 83 | int main(int argc, char **argv) 84 | { 85 | struct sigaction sa; 86 | sigset_t childset, emptyset; 87 | int i; 88 | 89 | for (i = 0; i < nkids; i++) 90 | kids[i] = NOT_USED; 91 | 92 | sigemptyset(& emptyset); 93 | 94 | sa.sa_flags = SA_NOCLDSTOP; 95 | sa.sa_handler = childhandler; 96 | sigfillset(& sa.sa_mask); /* block everything when handler runs */ 97 | sigaction(SIGCHLD, & sa, NULL); 98 | 99 | sigemptyset(& childset); 100 | sigaddset(& childset, SIGCHLD); 101 | 102 | sigprocmask(SIG_SETMASK, & childset, NULL); /* block it in main code */ 103 | 104 | for (nkids = 0; nkids < 5; nkids++) { 105 | if ((kids[nkids] = fork()) == 0) { 106 | sleep(3); 107 | _exit(0); 108 | } 109 | } 110 | 111 | sleep(5); /* give the kids a chance to terminate */ 112 | 113 | printf("waiting for signal\n"); 114 | sigsuspend(& emptyset); 115 | 116 | return 0; 117 | } 118 | -------------------------------------------------------------------------------- /book/ch10/ch10-reap2.c: -------------------------------------------------------------------------------- 1 | /* ch10-reap2.c --- demonstrate SIGCHLD management, one signal per child */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #define MAX_KIDS 42 11 | #define NOT_USED -1 12 | 13 | pid_t kids[MAX_KIDS]; 14 | size_t nkids = 0; 15 | size_t kidsleft = 0; /* <<< Added */ 16 | 17 | /* format_num --- helper function since can't use [sf]printf() */ 18 | 19 | const char *format_num(int num) 20 | { 21 | #define NUMSIZ 30 22 | static char buf[NUMSIZ]; 23 | int i; 24 | 25 | if (num <= 0) { 26 | strcpy(buf, "0"); 27 | return buf; 28 | } 29 | 30 | i = NUMSIZ - 1; 31 | buf[i--] = '\0'; 32 | 33 | /* Generate digits backwards into string. */ 34 | do { 35 | buf[i--] = (num % 10) + '0'; 36 | num /= 10; 37 | } while (num > 0); 38 | 39 | return & buf[i+1]; 40 | } 41 | 42 | /* childhandler --- catch SIGCHLD, reap all available children */ 43 | 44 | void childhandler(int sig) 45 | { 46 | int status, ret; 47 | int i; 48 | char buf[100]; 49 | static const char entered[] = "Entered childhandler\n"; 50 | static const char exited[] = "Exited childhandler\n"; 51 | 52 | write(1, entered, strlen(entered)); 53 | for (i = 0; i < nkids; i++) { 54 | if (kids[i] == NOT_USED) 55 | continue; 56 | 57 | retry: 58 | if ((ret = waitpid(kids[i], & status, WNOHANG)) == kids[i]) { 59 | strcpy(buf, "\treaped process "); 60 | strcat(buf, format_num(ret)); 61 | strcat(buf, "\n"); 62 | write(1, buf, strlen(buf)); 63 | kids[i] = NOT_USED; 64 | kidsleft--; /* <<< Added */ 65 | } else if (ret == 0) { 66 | strcpy(buf, "\tpid "); 67 | strcat(buf, format_num(kids[i])); 68 | strcat(buf, " not available yet\n"); 69 | write(1, buf, strlen(buf)); 70 | } else if (ret == -1 && errno == EINTR) { 71 | write(1, "\tretrying\n", 10); 72 | goto retry; 73 | } else { 74 | strcpy(buf, "\twaitpid() failed: "); 75 | strcat(buf, strerror(errno)); 76 | strcat(buf, "\n"); 77 | write(1, buf, strlen(buf)); 78 | } 79 | } 80 | write(1, exited, strlen(exited)); 81 | } 82 | 83 | /* main --- set up child-related information and signals, create children */ 84 | 85 | int main(int argc, char **argv) 86 | { 87 | struct sigaction sa; 88 | sigset_t childset, emptyset; 89 | int i; 90 | 91 | for (i = 0; i < nkids; i++) 92 | kids[i] = NOT_USED; 93 | 94 | sigemptyset(& emptyset); 95 | 96 | sa.sa_flags = SA_NOCLDSTOP; 97 | sa.sa_handler = childhandler; 98 | sigfillset(& sa.sa_mask); /* block everything when handler runs */ 99 | sigaction(SIGCHLD, & sa, NULL); 100 | 101 | sigemptyset(& childset); 102 | sigaddset(& childset, SIGCHLD); 103 | 104 | /* sigprocmask(SIG_SETMASK, & childset, NULL); /* block it in main code */ 105 | 106 | for (nkids = 0; nkids < 5; nkids++) { 107 | if ((kids[nkids] = fork()) == 0) { 108 | sleep(3); 109 | _exit(0); 110 | } 111 | kidsleft++; /* <<< Added */ 112 | } 113 | 114 | /* sleep(5); /* give the kids a chance to terminate */ 115 | 116 | while (kidsleft > 0) { /* <<< Added */ 117 | printf("waiting for signals\n"); 118 | sigsuspend(& emptyset); 119 | } /* <<< Added */ 120 | 121 | return 0; 122 | } 123 | -------------------------------------------------------------------------------- /book/ch10/ch10-status.c: -------------------------------------------------------------------------------- 1 | /* ch10-status.c --- demonstrate SIGCHLD management, use 3 argument handler */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | void manage(siginfo_t *si); 11 | 12 | /* format_num --- helper function since can't use [sf]printf() */ 13 | 14 | const char *format_num(int num) 15 | { 16 | #define NUMSIZ 30 17 | static char buf[NUMSIZ]; 18 | int i; 19 | 20 | if (num <= 0) { 21 | strcpy(buf, "0"); 22 | return buf; 23 | } 24 | 25 | i = NUMSIZ - 1; 26 | buf[i--] = '\0'; 27 | 28 | /* Generate digits backwards into string. */ 29 | do { 30 | buf[i--] = (num % 10) + '0'; 31 | num /= 10; 32 | } while (num > 0); 33 | 34 | return & buf[i+1]; 35 | } 36 | 37 | /* childhandler --- catch SIGCHLD, reap just one child */ 38 | 39 | void childhandler(int sig, siginfo_t *si, void *context) 40 | { 41 | int status, ret; 42 | int i; 43 | char buf[100]; 44 | static const char entered[] = "Entered childhandler\n"; 45 | static const char exited[] = "Exited childhandler\n"; 46 | 47 | write(1, entered, strlen(entered)); 48 | retry: 49 | if ((ret = waitpid(si->si_pid, & status, WNOHANG)) == si->si_pid) { 50 | strcpy(buf, "\treaped process "); 51 | strcat(buf, format_num(si->si_pid)); 52 | strcat(buf, "\n"); 53 | write(1, buf, strlen(buf)); 54 | manage(si); /* deal with what happened to it */ 55 | } else if (ret > 0) { 56 | strcpy(buf, "\treaped unexpected pid "); 57 | strcat(buf, format_num(ret)); 58 | strcat(buf, "\n"); 59 | write(1, buf, strlen(buf)); 60 | goto retry; /* why not? */ 61 | } else if (ret == 0) { 62 | strcpy(buf, "\tpid "); 63 | strcat(buf, format_num(si->si_pid)); 64 | strcat(buf, " changed status\n"); 65 | write(1, buf, strlen(buf)); 66 | manage(si); /* deal with what happened to it */ 67 | } else if (ret == -1 && errno == EINTR) { 68 | write(1, "\tretrying\n", 10); 69 | goto retry; 70 | } else { 71 | strcpy(buf, "\twaitpid() failed: "); 72 | strcat(buf, strerror(errno)); 73 | strcat(buf, "\n"); 74 | write(1, buf, strlen(buf)); 75 | } 76 | 77 | write(1, exited, strlen(exited)); 78 | } 79 | 80 | /* child --- what to do in the child */ 81 | 82 | void child(void) 83 | { 84 | raise(SIGCONT); /* should be ignored */ 85 | raise(SIGSTOP); /* go to sleep, parent wakes us back up */ 86 | printf("\t---> child restarted <---\n"); 87 | exit(42); /* normal exit, let parent get value */ 88 | } 89 | 90 | /* main --- set up child-related information and signals, create child */ 91 | 92 | int main(int argc, char **argv) 93 | { 94 | pid_t kid; 95 | struct sigaction sa; 96 | sigset_t childset, emptyset; 97 | 98 | sigemptyset(& emptyset); 99 | 100 | sa.sa_flags = SA_SIGINFO; 101 | sa.sa_sigaction = childhandler; 102 | sigfillset(& sa.sa_mask); /* block everything when handler runs */ 103 | sigaction(SIGCHLD, & sa, NULL); 104 | 105 | sigemptyset(& childset); 106 | sigaddset(& childset, SIGCHLD); 107 | 108 | sigprocmask(SIG_SETMASK, & childset, NULL); /* block it in main code */ 109 | 110 | if ((kid = fork()) == 0) 111 | child(); 112 | 113 | /* parent executes here */ 114 | for (;;) { 115 | printf("waiting for signals\n"); 116 | sigsuspend(& emptyset); 117 | } 118 | 119 | return 0; 120 | } 121 | 122 | /* manage --- deal with different things that could happen to child */ 123 | 124 | void manage(siginfo_t *si) 125 | { 126 | char buf[100]; 127 | 128 | switch (si->si_code) { 129 | case CLD_STOPPED: 130 | write(1, "\tchild stopped, restarting\n", 27); 131 | kill(si->si_pid, SIGCONT); 132 | break; 133 | 134 | case CLD_CONTINUED: /* not sent on Linux */ 135 | write(1, "\tchild continued\n", 17); 136 | break; 137 | 138 | case CLD_EXITED: 139 | strcpy(buf, "\tchild exited with status "); 140 | strcat(buf, format_num(si->si_status)); 141 | strcat(buf, "\n"); 142 | write(1, buf, strlen(buf)); 143 | exit(0); /* we're done */ 144 | break; 145 | 146 | case CLD_DUMPED: 147 | write(1, "\tchild dumped\n", 14); 148 | break; 149 | 150 | case CLD_KILLED: 151 | write(1, "\tchild killed\n", 14); 152 | break; 153 | 154 | case CLD_TRAPPED: 155 | write(1, "\tchild trapped\n", 15); 156 | break; 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /book/ch12/ch12-assert.c: -------------------------------------------------------------------------------- 1 | /* ch12-assert.c --- demonstrate assertions */ 2 | 3 | #include 4 | #include 5 | 6 | /* lsearch --- return index in array of value, or -1 if not found */ 7 | 8 | int lsearch(int *array, size_t size, int value) 9 | { 10 | size_t i; 11 | 12 | assert(array != NULL); 13 | assert(size > 0); 14 | for (i = 0; i < size; i++) 15 | if (array[i] == value) 16 | return i; 17 | 18 | assert(i == size); 19 | 20 | return -1; 21 | } 22 | 23 | /* main --- test out assertions */ 24 | 25 | int main(void) 26 | { 27 | #define NELEMS 4 28 | static int array[NELEMS] = { 1, 17, 42, 91 }; 29 | int index; 30 | 31 | index = lsearch(array, NELEMS, 21); 32 | assert(index == -1); 33 | 34 | index = lsearch(array, NELEMS, 17); 35 | assert(index == 1); 36 | 37 | index = lsearch(NULL, NELEMS, 10); /* won't return */ 38 | 39 | printf("index = %d\n", index); 40 | 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /book/ch12/ch12-devrandom.c: -------------------------------------------------------------------------------- 1 | /* ch12-devrandom.c --- generate die rolls, using /dev/urandom. */ 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | char *die_faces[] = { /* ASCII graphics rule! */ 8 | " ", 9 | " * ", /* 1 */ 10 | " ", 11 | 12 | " ", 13 | " * * ", /* 2 */ 14 | " ", 15 | 16 | " ", 17 | " * * * ", /* 3 */ 18 | " ", 19 | 20 | " * * ", 21 | " ", /* 4 */ 22 | " * * ", 23 | 24 | " * * ", 25 | " * ", /* 5 */ 26 | " * * ", 27 | 28 | " * * * ", 29 | " ", /* 6 */ 30 | " * * * ", 31 | }; 32 | 33 | /* myrandom --- return data from /dev/urandom as unsigned long */ 34 | 35 | unsigned long myrandom(void) 36 | { 37 | static int fd = -1; 38 | unsigned long data; 39 | 40 | if (fd == -1) 41 | fd = open("/dev/urandom", O_RDONLY); 42 | 43 | if (fd == -1 || read(fd, & data, sizeof data) <= 0) 44 | return random(); /* fall back */ 45 | 46 | return data; 47 | } 48 | 49 | /* main --- print N different die faces */ 50 | 51 | int main(int argc, char **argv) 52 | { 53 | int nfaces; 54 | int i, j, k; 55 | 56 | if (argc != 2) { 57 | fprintf(stderr, "usage: %s number-die-faces\n", argv[0]); 58 | exit(1); 59 | } 60 | 61 | nfaces = atoi(argv[1]); 62 | 63 | if (nfaces <= 0) { 64 | fprintf(stderr, "usage: %s number-die-faces\n", argv[0]); 65 | fprintf(stderr, "\tUse a positive number!\n"); 66 | exit(1); 67 | } 68 | 69 | for (i = 1; i <= nfaces; i++) { 70 | j = myrandom() % 6; /* force to range 0 <= j <= 5 */ 71 | printf("+-------+\n"); 72 | for (k = 0; k < 3; k++) 73 | printf("|%s|\n", die_faces[(j * 3) + k]); 74 | printf("+-------+\n"); 75 | putchar('\n'); 76 | } 77 | 78 | return 0; 79 | } 80 | -------------------------------------------------------------------------------- /book/ch12/ch12-glob.c: -------------------------------------------------------------------------------- 1 | /* ch12-glob.c --- demonstrate glob(). */ 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | char *myname; 8 | 9 | /* globerr --- print error message for glob() */ 10 | 11 | int globerr(const char *path, int eerrno) 12 | { 13 | fprintf(stderr, "%s: %s: %s\n", myname, path, strerror(eerrno)); 14 | return 0; /* let glob() keep going */ 15 | } 16 | 17 | /* main() --- expand command-line wildcards and print results */ 18 | 19 | int main(int argc, char **argv) 20 | { 21 | int i; 22 | int flags = 0; 23 | glob_t results; 24 | int ret; 25 | 26 | if (argc == 1) { 27 | fprintf(stderr, "usage: %s wildcard ...\n", argv[0]); 28 | exit(1); 29 | } 30 | 31 | myname = argv[0]; /* for globerr() */ 32 | 33 | for (i = 1; i < argc; i++) { 34 | flags |= (i > 1 ? GLOB_APPEND : 0); 35 | ret = glob(argv[i], flags, globerr, & results); 36 | if (ret != 0) { 37 | fprintf(stderr, "%s: problem with %s (%s), stopping early\n", 38 | myname, argv[i], 39 | /* ugly: */ (ret == GLOB_ABORTED ? "filesystem problem" : 40 | ret == GLOB_NOMATCH ? "no match of pattern" : 41 | ret == GLOB_NOSPACE ? "no dynamic memory" : 42 | "unknown problem")); 43 | break; 44 | } 45 | } 46 | 47 | for (i = 0; i < results.gl_pathc; i++) 48 | printf("%s\n", results.gl_pathv[i]); 49 | 50 | globfree(& results); 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /book/ch12/ch12-grep.c: -------------------------------------------------------------------------------- 1 | /* ch12-grep.c --- Simple version of grep using POSIX R.E. functions. */ 2 | 3 | #define _GNU_SOURCE 1 /* for getline() */ 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | char *myname; /* for error messages */ 11 | int ignore_case = 0; /* -i option: ignore case */ 12 | int extended = 0; /* -E option: use extended RE's */ 13 | int errors = 0; /* number of errors */ 14 | 15 | regex_t pattern; /* pattern to match */ 16 | 17 | void compile_pattern(const char *pat); 18 | void process(const char *name, FILE *fp); 19 | void usage(void); 20 | 21 | /* main --- process options, open files */ 22 | 23 | int main(int argc, char **argv) 24 | { 25 | int c; 26 | int i; 27 | FILE *fp; 28 | 29 | myname = argv[0]; 30 | while ((c = getopt(argc, argv, ":iE")) != -1) { 31 | switch (c) { 32 | case 'i': 33 | ignore_case = 1; 34 | break; 35 | case 'E': 36 | extended = 1; 37 | break; 38 | case '?': 39 | usage(); 40 | break; 41 | } 42 | } 43 | 44 | if (optind == argc) /* sanity check */ 45 | usage(); 46 | 47 | compile_pattern(argv[optind]); /* compile the pattern */ 48 | if (errors) /* compile failed */ 49 | return 1; 50 | else 51 | optind++; 52 | 53 | if (optind == argc) /* no files, default to stdin */ 54 | process("standard input", stdin); 55 | else { 56 | /* loop over files */ 57 | for (i = optind; i < argc; i++) { 58 | if (strcmp(argv[i], "-") == 0) 59 | process("standard input", stdin); 60 | else if ((fp = fopen(argv[i], "r")) != NULL) { 61 | process(argv[i], fp); 62 | fclose(fp); 63 | } else { 64 | fprintf(stderr, "%s: %s: could not open: %s\n", 65 | argv[0], argv[i], strerror(errno)); 66 | errors++; 67 | } 68 | } 69 | } 70 | 71 | regfree(& pattern); 72 | return errors != 0; 73 | } 74 | 75 | /* compile_pattern --- compile the pattern */ 76 | 77 | void compile_pattern(const char *pat) 78 | { 79 | int flags = REG_NOSUB; /* don't need where-matched info */ 80 | int ret; 81 | #define MSGBUFSIZE 512 /* arbitrary */ 82 | char error[MSGBUFSIZE]; 83 | 84 | if (ignore_case) 85 | flags |= REG_ICASE; 86 | if (extended) 87 | flags |= REG_EXTENDED; 88 | 89 | ret = regcomp(& pattern, pat, flags); 90 | if (ret != 0) { 91 | (void) regerror(ret, & pattern, error, sizeof error); 92 | fprintf(stderr, "%s: pattern `%s': %s\n", myname, pat, error); 93 | errors++; 94 | } 95 | } 96 | 97 | /* process --- read lines of text and match against the pattern */ 98 | 99 | void process(const char *name, FILE *fp) 100 | { 101 | char *buf = NULL; 102 | size_t size = 0; 103 | char error[MSGBUFSIZE]; 104 | int ret; 105 | 106 | while (getline(& buf, &size, fp) != -1) { 107 | ret = regexec(& pattern, buf, 0, NULL, 0); 108 | if (ret != 0) { 109 | if (ret != REG_NOMATCH) { 110 | (void) regerror(ret, & pattern, error, sizeof error); 111 | fprintf(stderr, "%s: file %s: %s\n", myname, name, error); 112 | free(buf); 113 | errors++; 114 | return; 115 | } 116 | } else 117 | printf("%s: %s", name, buf); /* print matching lines */ 118 | } 119 | free(buf); 120 | } 121 | 122 | /* usage --- print usage message and exit */ 123 | 124 | void usage(void) 125 | { 126 | fprintf(stderr, "usage: %s [-i] [-E] pattern [ files ... ]\n", myname); 127 | exit(1); 128 | } 129 | -------------------------------------------------------------------------------- /book/ch12/ch12-memleak.c: -------------------------------------------------------------------------------- 1 | /* ch12-memleak.c --- demonstrate memory leaks with setjmp()/longjmp(). */ 2 | 3 | #include 4 | #include /* for definition of ptrdiff_t on GLIBC */ 5 | #include 6 | #include 7 | 8 | jmp_buf env; 9 | 10 | void f1(void), f2(void); 11 | 12 | /* main --- leak memory with setjmp() and longjmp() */ 13 | 14 | int main(void) 15 | { 16 | char *start_break; 17 | char *current_break; 18 | ptrdiff_t diff; 19 | 20 | start_break = sbrk((ptrdiff_t) 0); 21 | 22 | if (setjmp(env) == 0) /* first time */ 23 | printf("setjmp called\n"); 24 | 25 | current_break = sbrk((ptrdiff_t) 0); 26 | 27 | diff = current_break - start_break; 28 | printf("memsize = %ld\n", (long) diff); 29 | 30 | f1(); 31 | 32 | return 0; 33 | } 34 | 35 | /* f1 --- allocate some memory, make a nested call */ 36 | 37 | void f1(void) 38 | { 39 | char *p = malloc(1024); 40 | 41 | f2(); 42 | } 43 | 44 | /* f2 --- allocate some memory, make longjmp */ 45 | 46 | void f2(void) 47 | { 48 | char *p = malloc(1024); 49 | 50 | longjmp(env, 1); 51 | } 52 | -------------------------------------------------------------------------------- /book/ch12/ch12-mkstemp.c: -------------------------------------------------------------------------------- 1 | /* ch12-mkstemp.c --- demonstrate mkstemp(). 2 | Error checking omitted for brevity */ 3 | 4 | #include 5 | #include /* for open flags */ 6 | #include /* for PATH_MAX */ 7 | 8 | int main(void) 9 | { 10 | static char template[] = "/tmp/myfileXXXXXX"; 11 | char fname[PATH_MAX]; 12 | static char mesg[] = 13 | "Here's lookin' at you, kid!\n"; /* beats "hello, world" */ 14 | int fd; 15 | char buf[BUFSIZ]; 16 | int n; 17 | 18 | strcpy(fname, template); /* Copy template */ 19 | fd = mkstemp(fname); /* Create and open temp file */ 20 | printf("Filename is %s\n", fname); /* Print it for information */ 21 | 22 | write(fd, mesg, strlen(mesg)); /* Write something to file */ 23 | 24 | lseek(fd, 0L, SEEK_SET); /* Rewind to front */ 25 | n = read(fd, buf, sizeof(buf)); /* Read data back; NOT '\0' terminated! */ 26 | printf("Got back: %.*s", n, buf); /* Print it out for verification */ 27 | 28 | close(fd); /* Close file */ 29 | unlink(fname); /* Remove it */ 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /book/ch12/ch12-mktemp.c: -------------------------------------------------------------------------------- 1 | /* ch12-mktemp.c --- demonstrate naive use of mktemp(). 2 | Error checking omitted for brevity */ 3 | 4 | #include 5 | #include /* for open flags */ 6 | #include /* for PATH_MAX */ 7 | 8 | int main(void) 9 | { 10 | static char template[] = "/tmp/myfileXXXXXX"; 11 | char fname[PATH_MAX]; 12 | static char mesg[] = 13 | "Here's lookin' at you, kid!\n"; /* beats "hello, world" */ 14 | int fd; 15 | 16 | strcpy(fname, template); 17 | mktemp(fname); 18 | 19 | /* RACE CONDITION WINDOW OPENS */ 20 | 21 | printf("Filename is %s\n", fname); 22 | 23 | /* RACE CONDITION WINDOW LASTS TO HERE */ 24 | 25 | fd = open(fname, O_CREAT|O_RDWR|O_TRUNC, 0600); 26 | write(fd, mesg, strlen(mesg)); 27 | close(fd); 28 | 29 | /* unlink(fname); */ 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /book/ch12/ch12-rand.c: -------------------------------------------------------------------------------- 1 | /* ch12-rand.c --- generate die rolls, using rand(). */ 2 | 3 | #include 4 | #include 5 | 6 | char *die_faces[] = { /* ASCII graphics rule! */ 7 | " ", 8 | " * ", /* 1 */ 9 | " ", 10 | 11 | " ", 12 | " * * ", /* 2 */ 13 | " ", 14 | 15 | " ", 16 | " * * * ", /* 3 */ 17 | " ", 18 | 19 | " * * ", 20 | " ", /* 4 */ 21 | " * * ", 22 | 23 | " * * ", 24 | " * ", /* 5 */ 25 | " * * ", 26 | 27 | " * * * ", 28 | " ", /* 6 */ 29 | " * * * ", 30 | }; 31 | 32 | /* main --- print N different die faces */ 33 | 34 | int main(int argc, char **argv) 35 | { 36 | int nfaces; 37 | int i, j, k; 38 | 39 | if (argc != 2) { 40 | fprintf(stderr, "usage: %s number-die-faces\n", argv[0]); 41 | exit(1); 42 | } 43 | 44 | nfaces = atoi(argv[1]); 45 | 46 | if (nfaces <= 0) { 47 | fprintf(stderr, "usage: %s number-die-faces\n", argv[0]); 48 | fprintf(stderr, "\tUse a positive number!\n"); 49 | exit(1); 50 | } 51 | 52 | for (i = 1; i <= nfaces; i++) { 53 | j = rand() % 6; /* force to range 0 <= j <= 5 */ 54 | printf("+-------+\n"); 55 | for (k = 0; k < 3; k++) 56 | printf("|%s|\n", die_faces[(j * 3) + k]); 57 | printf("+-------+\n\n"); 58 | } 59 | 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /book/ch12/ch12-random.c: -------------------------------------------------------------------------------- 1 | /* ch12-random.c --- generate die rolls, using random(). */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | char *die_faces[] = { /* ASCII graphics rule! */ 9 | " ", 10 | " * ", /* 1 */ 11 | " ", 12 | 13 | " ", 14 | " * * ", /* 2 */ 15 | " ", 16 | 17 | " ", 18 | " * * * ", /* 3 */ 19 | " ", 20 | 21 | " * * ", 22 | " ", /* 4 */ 23 | " * * ", 24 | 25 | " * * ", 26 | " * ", /* 5 */ 27 | " * * ", 28 | 29 | " * * * ", 30 | " ", /* 6 */ 31 | " * * * ", 32 | }; 33 | 34 | /* main --- print N different die faces */ 35 | 36 | int main(int argc, char **argv) 37 | { 38 | int nfaces; 39 | int i, j, k; 40 | char state[256]; 41 | time_t now; 42 | 43 | if (argc != 2) { 44 | fprintf(stderr, "usage: %s number-die-faces\n", argv[0]); 45 | exit(1); 46 | } 47 | 48 | nfaces = atoi(argv[1]); 49 | 50 | if (nfaces <= 0) { 51 | fprintf(stderr, "usage: %s number-die-faces\n", argv[0]); 52 | fprintf(stderr, "\tUse a positive number!\n"); 53 | exit(1); 54 | } 55 | 56 | (void) time(& now); /* seed with time of day and PID */ 57 | (void) initstate((unsigned int) (now + getpid()), state, sizeof state); 58 | (void) setstate(state); 59 | 60 | for (i = 1; i <= nfaces; i++) { 61 | j = random() % 6; /* force to range 0 <= j <= 5 */ 62 | printf("+-------+\n"); 63 | for (k = 0; k < 3; k++) 64 | printf("|%s|\n", die_faces[(j * 3) + k]); 65 | printf("+-------+\n\n"); 66 | } 67 | 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /book/ch12/ch12-setjmp.c: -------------------------------------------------------------------------------- 1 | /* ch12-setjmp.c --- demonstrate setjmp()/longjmp() and volatile. */ 2 | 3 | #include 4 | #include 5 | 6 | jmp_buf env; 7 | 8 | /* comeback --- do a longjmp */ 9 | 10 | void comeback(void) 11 | { 12 | longjmp(env, 1); 13 | printf("This line is never printed\n"); 14 | } 15 | 16 | /* main --- call setjmp, fiddle with vars, print values */ 17 | 18 | int main(void) 19 | { 20 | int i = 5; 21 | volatile int j = 6; 22 | 23 | if (setjmp(env) == 0) { /* first time */ 24 | i++; 25 | j++; 26 | printf("first time: i = %d, j = %d\n", i, j); 27 | comeback(); 28 | } else /* second time */ 29 | printf("second time: i = %d, j = %d\n", i, j); 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /book/ch12/ch12-tmpfile.c: -------------------------------------------------------------------------------- 1 | /* ch12-tmpfile.c --- demonstrate tmpfile(). 2 | Error checking omitted for brevity */ 3 | 4 | #include 5 | 6 | int main(void) 7 | { 8 | static char mesg[] = 9 | "Here's lookin' at you, kid!"; /* beats "hello, world" */ 10 | FILE *fp; 11 | char buf[BUFSIZ]; 12 | 13 | fp = tmpfile(); /* Get temp file */ 14 | fprintf(fp, "%s", mesg); /* Write to it */ 15 | fflush(fp); /* Force it out */ 16 | 17 | rewind(fp); /* Move to front */ 18 | fgets(buf, sizeof buf, fp); /* Read contents */ 19 | 20 | printf("Got back <%s>\n", buf); /* Print retrieved data */ 21 | 22 | fclose(fp); /* Close file, goes away */ 23 | return 0; /* All done */ 24 | } 25 | -------------------------------------------------------------------------------- /book/ch13/ch13-compare.c: -------------------------------------------------------------------------------- 1 | /* ch13-compare.c --- demonstrate strcmp() vs. strcoll() */ 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | int main(void) 8 | { 9 | #define STRBUFSIZE 1024 10 | char locale[STRBUFSIZE], curloc[STRBUFSIZE]; 11 | char left[STRBUFSIZE], right[STRBUFSIZE]; 12 | char buf[BUFSIZ]; 13 | int count; 14 | 15 | setlocale(LC_ALL, ""); /* set to env locale */ 16 | strcpy(curloc, setlocale(LC_ALL, NULL)); /* save it */ 17 | 18 | printf("--> "); fflush(stdout); 19 | while (fgets(buf, sizeof buf, stdin) != NULL) { 20 | locale[0] = '\0'; 21 | count = sscanf(buf, "%s %s %s", left, right, locale); 22 | if (count < 2) 23 | break; 24 | 25 | if (*locale) { 26 | setlocale(LC_ALL, locale); 27 | strcpy(curloc, locale); 28 | } 29 | 30 | printf("%s: strcmp(\"%s\", \"%s\") is %d\n", curloc, left, 31 | right, strcmp(left, right)); 32 | printf("%s: strcoll(\"%s\", \"%s\") is %d\n", curloc, left, 33 | right, strcoll(left, right)); 34 | 35 | printf("\n--> "); fflush(stdout); 36 | } 37 | 38 | exit(0); 39 | } 40 | -------------------------------------------------------------------------------- /book/ch13/ch13-echodate.c: -------------------------------------------------------------------------------- 1 | /* ch13-echodate.c --- demonstrate translations */ 2 | 3 | #include 4 | #include 5 | #include 6 | #define ENABLE_NLS 1 7 | #include "gettext.h" 8 | #define _(msgid) gettext(msgid) 9 | #define N_(msgid) msgid 10 | 11 | int main(void) 12 | { 13 | struct tm tm; 14 | time_t then; 15 | 16 | setlocale(LC_ALL, ""); 17 | bindtextdomain("echodate", "."); 18 | textdomain("echodate"); 19 | 20 | printf("%s", _("Enter a Date/time as YYYY/MM/DD HH:MM:SS : ")); 21 | scanf("%d/%d/%d %d:%d:%d", 22 | & tm.tm_year, & tm.tm_mon, & tm.tm_mday, 23 | & tm.tm_hour, & tm.tm_min, & tm.tm_sec); 24 | 25 | /* Error checking on values omitted for brevity. */ 26 | tm.tm_year -= 1900; 27 | tm.tm_mon -= 1; 28 | 29 | tm.tm_isdst = -1; /* Don't know about DST */ 30 | 31 | then = mktime(& tm); 32 | 33 | printf(_("Got: %s"), ctime(& then)); 34 | exit(0); 35 | } 36 | -------------------------------------------------------------------------------- /book/ch13/ch13-lconv.c: -------------------------------------------------------------------------------- 1 | /* ch13-lconv.c --- show some of the components of the struct lconv */ 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | int main(void) 8 | { 9 | struct lconv l; 10 | int i; 11 | 12 | setlocale(LC_ALL, ""); 13 | l = *localeconv(); 14 | 15 | printf("decimal_point = [%s]\n", l.decimal_point); 16 | printf("thousands_sep = [%s]\n", l.thousands_sep); 17 | 18 | for (i = 0; l.grouping[i] != 0 && l.grouping[i] != CHAR_MAX; i++) 19 | printf("grouping[%d] = [%d]\n", i, l.grouping[i]); 20 | 21 | printf("int_curr_symbol = [%s]\n", l.int_curr_symbol); 22 | printf("currency_symbol = [%s]\n", l.currency_symbol); 23 | printf("mon_decimal_point = [%s]\n", l.mon_decimal_point); 24 | printf("mon_thousands_sep = [%s]\n", l.mon_thousands_sep); 25 | printf("positive_sign = [%s]\n", l.positive_sign); 26 | printf("negative_sign = [%s]\n", l.negative_sign); 27 | } 28 | -------------------------------------------------------------------------------- /book/ch13/ch13-quoteflag.c: -------------------------------------------------------------------------------- 1 | /* ch13-quoteflag.c --- demonstrate printf's quote flag */ 2 | 3 | #include 4 | #include 5 | 6 | int main(void) 7 | { 8 | setlocale(LC_ALL, ""); /* Have to do this, or it won't work */ 9 | printf("%'d\n", 1234567); 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /book/ch13/ch13-strfmon.c: -------------------------------------------------------------------------------- 1 | /* ch13-strfmon.c --- demonstrate strfmon() */ 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | int main(void) 8 | { 9 | char buf[BUFSIZ]; 10 | double val = 1234.567; 11 | 12 | setlocale(LC_ALL, ""); 13 | strfmon(buf, sizeof buf, "You owe me %n (%i)\n", val, val); 14 | 15 | fputs(buf, stdout); 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /book/ch13/ch13-strings.c: -------------------------------------------------------------------------------- 1 | /* ch13-strings.c --- demonstrate strcmp() vs. strcoll() */ 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | int main(void) 8 | { 9 | setlocale(LC_ALL, ""); 10 | 11 | printf("Result of strcmp(\"\\\"\", \"/\") is %d\n", strcmp("\"", "/")); 12 | printf("Result of strcoll(\"\\\"\", \"/\") is %d\n", strcoll("\"", "/")); 13 | exit(0); 14 | } 15 | -------------------------------------------------------------------------------- /book/ch13/ch13-times.c: -------------------------------------------------------------------------------- 1 | /* ch13-times.c --- demonstrate locale-based times */ 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | int main(void) 8 | { 9 | char buf[100]; 10 | time_t now; 11 | struct tm *curtime; 12 | 13 | setlocale(LC_ALL, ""); 14 | time(& now); 15 | curtime = localtime(& now); 16 | (void) strftime(buf, sizeof buf, 17 | "It is now %A, %B %d, %Y, %I:%M %p", curtime); 18 | 19 | printf("%s\n", buf); 20 | 21 | printf("ctime() says: %s", ctime(& now)); 22 | exit(0); 23 | } 24 | -------------------------------------------------------------------------------- /book/ch13/echodate.pot: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | #, fuzzy 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: PACKAGE VERSION\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "POT-Creation-Date: 2003-07-14 18:46-0700\n" 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 13 | "Last-Translator: FULL NAME \n" 14 | "Language-Team: LANGUAGE \n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=CHARSET\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | 19 | #: ch13-echodate.c:19 20 | msgid "Enter a Date/time as YYYY/MM/DD HH:MM:SS : " 21 | msgstr "" 22 | 23 | #: ch13-echodate.c:32 24 | #, c-format 25 | msgid "Got: %s" 26 | msgstr "" 27 | -------------------------------------------------------------------------------- /book/ch13/gettext.h: -------------------------------------------------------------------------------- 1 | /* Convenience header for conditional use of GNU . 2 | Copyright (C) 1995-1998, 2000-2002 Free Software Foundation, Inc. 3 | 4 | This program is free software; you can redistribute it and/or modify it 5 | under the terms of the GNU Library General Public License as published 6 | by the Free Software Foundation; either version 2, or (at your option) 7 | any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Library General Public License for more details. 13 | 14 | You should have received a copy of the GNU Library General Public 15 | License along with this program; if not, write to the Free Software 16 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 17 | USA. */ 18 | 19 | #ifndef _LIBGETTEXT_H 20 | #define _LIBGETTEXT_H 1 21 | 22 | /* NLS can be disabled through the configure --disable-nls option. */ 23 | #if ENABLE_NLS 24 | 25 | /* ADR: Need this so gcc -g without -O works. */ 26 | #ifdef HAVE_LOCALE_H 27 | #include 28 | #endif /* HAVE_LOCALE_H */ 29 | 30 | /* Get declarations of GNU message catalog functions. */ 31 | # include 32 | 33 | #else 34 | 35 | /* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which 36 | chokes if dcgettext is defined as a macro. So include it now, to make 37 | later inclusions of a NOP. We don't include 38 | as well because people using "gettext.h" will not include , 39 | and also including would fail on SunOS 4, whereas 40 | is OK. */ 41 | #if defined(__sun) 42 | # include 43 | #endif 44 | 45 | /* Disabled NLS. 46 | The casts to 'const char *' serve the purpose of producing warnings 47 | for invalid uses of the value returned from these functions. 48 | On pre-ANSI systems without 'const', the config.h file is supposed to 49 | contain "#define const". */ 50 | /* ADR: BOGUS. Remove const. 19 Feb 2002 */ 51 | # define gettext(Msgid) ((char *) (Msgid)) 52 | # define dgettext(Domainname, Msgid) ((char *) (Msgid)) 53 | # define dcgettext(Domainname, Msgid, Category) ((char *) (Msgid)) 54 | # define ngettext(Msgid1, Msgid2, N) \ 55 | ((N) == 1 ? (char *) (Msgid1) : (char *) (Msgid2)) 56 | # define dngettext(Domainname, Msgid1, Msgid2, N) \ 57 | ((N) == 1 ? (char *) (Msgid1) : (char *) (Msgid2)) 58 | # define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ 59 | ((N) == 1 ? (char *) (Msgid1) : (char *) (Msgid2)) 60 | # define textdomain(Domainname) ((char *) (Domainname)) 61 | # define bindtextdomain(Domainname, Dirname) ((char *) (Dirname)) 62 | # define bind_textdomain_codeset(Domainname, Codeset) ((char *) (Codeset)) 63 | 64 | #endif 65 | 66 | /* A pseudo function call that serves as a marker for the automated 67 | extraction of messages, but does not call gettext(). The run-time 68 | translation is done at a different place in the code. 69 | The argument, String, should be a literal string. Concatenated strings 70 | and other string expressions won't work. 71 | The macro's expansion is not parenthesized, so that it is suitable as 72 | initializer for static 'char[]' or 'const char[]' variables. */ 73 | #define gettext_noop(String) String 74 | 75 | #endif /* _LIBGETTEXT_H */ 76 | -------------------------------------------------------------------------------- /book/ch13/piglat.po: -------------------------------------------------------------------------------- 1 | # echodate translations into pig Latin 2 | # Copyright (C) 2004 Prentice Hall 3 | # This file is distributed under the same license as the echodate package. 4 | # Arnold Robbins 2004 5 | # 6 | #, fuzzy 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: echodate 1.0\n" 10 | "Report-Msgid-Bugs-To: arnold@example.com\n" 11 | "POT-Creation-Date: 2003-07-14 18:46-0700\n" 12 | "PO-Revision-Date: 2003-07-14 19:00+8\n" 13 | "Last-Translator: Arnold Robbins \n" 14 | "Language-Team: Pig Latin \n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=ASCII\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | 19 | #: ch13-echodate.c:19 20 | msgid "Enter a Date/time as YYYY/MM/DD HH:MM:SS : " 21 | msgstr "Enteray A Ateday/imetay asay YYYY/MM/DD HH:MM:SS : " 22 | 23 | #: ch13-echodate.c:32 24 | #, c-format 25 | msgid "Got: %s" 26 | msgstr "Otgay: %s" 27 | -------------------------------------------------------------------------------- /book/ch14/ch14-lockall.c: -------------------------------------------------------------------------------- 1 | /* ch14-lockall.c --- Demonstrate mandatory locking. */ 2 | 3 | #include /* for fprintf(), stderr, BUFSIZ */ 4 | #include /* declare errno */ 5 | #include /* for flags for open() */ 6 | #include /* declare strerror() */ 7 | #include /* for ssize_t */ 8 | #include 9 | #include /* for mode_t */ 10 | 11 | int 12 | main(int argc, char **argv) 13 | { 14 | int fd; 15 | int i, j; 16 | mode_t rw_mode; 17 | static char message[] = "hello, world\n"; 18 | struct flock lock; 19 | 20 | if (argc != 2) { 21 | fprintf(stderr, "usage: %s file\n", argv[0]); 22 | exit(1); 23 | } 24 | 25 | rw_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; /* 0644 */ 26 | fd = open(argv[1], O_RDWR|O_TRUNC|O_CREAT|O_EXCL, rw_mode); 27 | if (fd < 0) { 28 | fprintf(stderr, "%s: %s: cannot open for read/write: %s\n", 29 | argv[0], argv[1], strerror(errno)); 30 | (void) close(fd); 31 | return 1; 32 | } 33 | 34 | if (write(fd, message, strlen(message)) != strlen(message)) { 35 | fprintf(stderr, "%s: %s: cannot write: %s\n", 36 | argv[0], argv[1], strerror(errno)); 37 | (void) close(fd); 38 | return 1; 39 | } 40 | 41 | rw_mode |= S_ISGID; /* add mandatory lock bit */ 42 | 43 | if (fchmod(fd, rw_mode) < 0) { 44 | fprintf(stderr, "%s: %s: cannot change mode to %o: %s\n", 45 | argv[0], argv[1], rw_mode, strerror(errno)); 46 | (void) close(fd); 47 | return 1; 48 | } 49 | 50 | /* lock the file */ 51 | memset(& lock, '\0', sizeof(lock)); 52 | lock.l_whence = SEEK_SET; 53 | lock.l_start = 0; 54 | lock.l_len = 0; /* whole-file lock */ 55 | lock.l_type = F_WRLCK; /* write lock */ 56 | 57 | if (fcntl(fd, F_SETLK, & lock) < 0) { 58 | fprintf(stderr, "%s: %s: cannot lock the file: %s\n", 59 | argv[0], argv[1], strerror(errno)); 60 | (void) close(fd); 61 | return 1; 62 | } 63 | 64 | pause(); 65 | 66 | (void) close(fd); 67 | 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /book/ch14/ch14-timers.c: -------------------------------------------------------------------------------- 1 | /* ch14-timers.c ---- demonstrate interval timers */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | /* handler --- handle SIGALRM */ 9 | 10 | void handler(int signo) 11 | { 12 | static const char msg[] = "\n*** Timer expired, you lose ***\n"; 13 | 14 | assert(signo == SIGALRM); 15 | 16 | write(2, msg, sizeof(msg) - 1); 17 | exit(1); 18 | } 19 | 20 | /* main --- set up timer, read data with timeout */ 21 | 22 | int main(void) 23 | { 24 | struct itimerval tval; 25 | char string[BUFSIZ]; 26 | 27 | timerclear(& tval.it_interval); /* zero interval means no reset of timer */ 28 | timerclear(& tval.it_value); 29 | 30 | tval.it_value.tv_sec = 10; /* 10 second timeout */ 31 | 32 | (void) signal(SIGALRM, handler); 33 | 34 | printf("You have ten seconds to enter\nyour name, rank, and serial number: "); 35 | 36 | (void) setitimer(ITIMER_REAL, & tval, NULL); 37 | if (fgets(string, sizeof string, stdin) != NULL) { 38 | (void) setitimer(ITIMER_REAL, NULL, NULL); /* turn off timer */ 39 | /* process rest of data, diagnostic print for illustration */ 40 | printf("I'm glad you are being cooperative.\n"); 41 | } else 42 | printf("\nEOF, eh? We won't give up so easily!\n"); 43 | 44 | exit(0); 45 | } 46 | -------------------------------------------------------------------------------- /book/ch14/ch14-tsearch.c: -------------------------------------------------------------------------------- 1 | /* ch14-tsearch.c --- demonstrate tree management */ 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | struct employee { 8 | char lastname[30]; 9 | char firstname[30]; 10 | long emp_id; 11 | time_t start_date; 12 | }; 13 | 14 | /* emp_name_id_compare --- compare by name, then by ID */ 15 | 16 | int emp_name_id_compare(const void *e1p, const void *e2p) 17 | { 18 | const struct employee *e1, *e2; 19 | int last, first; 20 | 21 | e1 = (const struct employee *) e1p; 22 | e2 = (const struct employee *) e2p; 23 | 24 | if ((last = strcmp(e1->lastname, e2->lastname)) != 0) 25 | return last; 26 | 27 | /* same last name, check first name */ 28 | if ((first = strcmp(e1->firstname, e2->firstname)) != 0) 29 | return first; 30 | 31 | /* same first name, check ID numbers */ 32 | if (e1->emp_id < e2->emp_id) 33 | return -1; 34 | else if (e1->emp_id == e2->emp_id) 35 | return 0; 36 | else 37 | return 1; 38 | } 39 | 40 | /* print_emp --- print an employee structure during a tree walk */ 41 | 42 | void print_emp(const void *nodep, const VISIT which, const int depth) 43 | { 44 | struct employee *e = *((struct employee **) nodep); 45 | 46 | switch (which) { 47 | case leaf: 48 | case postorder: 49 | printf("Depth: %d. Employee:\n", depth); 50 | printf("\t%s, %s\t%d\t%s\n", e->lastname, e->firstname, 51 | e->emp_id, ctime(& e->start_date)); 52 | break; 53 | default: 54 | break; 55 | } 56 | } 57 | 58 | /* main --- demonstrate maintaining data in binary tree */ 59 | 60 | int main(void) 61 | { 62 | #define NPRES 10 63 | struct employee presidents[NPRES]; 64 | int i, npres; 65 | char buf[BUFSIZ]; 66 | void *root = NULL; 67 | 68 | /* Very simple code to read data: */ 69 | for (npres = 0; npres < NPRES && fgets(buf, BUFSIZ, stdin) != NULL; 70 | npres++) { 71 | sscanf(buf, "%s %s %ld %ld\n", 72 | presidents[npres].lastname, 73 | presidents[npres].firstname, 74 | & presidents[npres].emp_id, 75 | & presidents[npres].start_date); 76 | } 77 | 78 | for (i = 0; i < npres; i++) 79 | (void) tsearch(& presidents[i], & root, emp_name_id_compare); 80 | 81 | twalk(root, print_emp); 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /book/ch14/presdata.txt: -------------------------------------------------------------------------------- 1 | Bush George 43 980013600 2 | Clinton William 42 727552800 3 | Bush George 41 601322400 4 | Reagan Ronald 40 348861600 5 | Carter James 39 222631200 6 | -------------------------------------------------------------------------------- /book/ch15/ch15-abort.c: -------------------------------------------------------------------------------- 1 | /* ch15-abort.c --- produce a core dump */ 2 | 3 | #include 4 | #include 5 | 6 | /* recurse --- build up some function calls */ 7 | 8 | void recurse(void) 9 | { 10 | static int i; 11 | 12 | if (++i == 3) 13 | abort(); 14 | else 15 | recurse(); 16 | } 17 | 18 | int main(int argc, char **argv) 19 | { 20 | recurse(); 21 | } 22 | -------------------------------------------------------------------------------- /book/ch15/ch15-badmem1.c: -------------------------------------------------------------------------------- 1 | /* ch15-badmem1.c --- do bad things with memory */ 2 | 3 | #include 4 | #include 5 | 6 | int main(int argc, char **argv) 7 | { 8 | char *p; 9 | int i; 10 | 11 | p = malloc(30); 12 | 13 | strcpy(p, "not 30 bytes"); 14 | printf("p = <%s>\n", p); 15 | 16 | if (argc == 2) { 17 | if (strcmp(argv[1], "-b") == 0) 18 | p[42] = 'a'; /* touch outside the bounds */ 19 | else if (strcmp(argv[1], "-f") == 0) { 20 | free(p); /* free memory and then use it */ 21 | p[0] = 'b'; 22 | } 23 | } 24 | 25 | /* free(p); */ 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /book/ch15/ch15-badmem2.c: -------------------------------------------------------------------------------- 1 | /* ch15-badmem2.c --- do bad things with memory, use dmalloc.h */ 2 | 3 | #include 4 | #include 5 | 6 | #include "dmalloc.h" 7 | 8 | int main(int argc, char **argv) 9 | { 10 | char *p; 11 | int i; 12 | 13 | p = malloc(30); 14 | 15 | strcpy(p, "not 30 bytes"); 16 | printf("p = <%s>\n", p); 17 | 18 | if (argc == 2) { 19 | if (strcmp(argv[1], "-b") == 0) 20 | p[42] = 'a'; /* touch outside the bounds */ 21 | else if (strcmp(argv[1], "-f") == 0) { 22 | free(p); /* free memory and then use it */ 23 | p[0] = 'b'; 24 | } 25 | } 26 | 27 | /* free(p); */ 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /book/ch15/ch15-badmem3.c: -------------------------------------------------------------------------------- 1 | /* ch15-badmem3.c --- do bad things with nondynamic memory */ 2 | 3 | #include 4 | #include 5 | 6 | int main(int argc, char **argv) 7 | { 8 | int a_var; /* Both of these are uninitialized */ 9 | int b_var; 10 | 11 | /* Valgrind won't flag this; see text. */ 12 | a_var = b_var; 13 | 14 | /* Use uninitialized memory; this is flagged. */ 15 | printf("a_var = %d\n", a_var); 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /book/ch15/ch15-union.c: -------------------------------------------------------------------------------- 1 | /* ch15-union.c --- brief demo of union usage. */ 2 | 3 | #include 4 | 5 | int main(void) 6 | { 7 | union i_f { 8 | int i; 9 | float f; 10 | } u; 11 | 12 | u.f = 12.34; /* Assign a floating point value */ 13 | printf("%f also looks like %#x\n", u.f, u.i); 14 | exit(0); 15 | } 16 | -------------------------------------------------------------------------------- /gnu/README: -------------------------------------------------------------------------------- 1 | Tue Feb 3 15:21:03 IST 2004 2 | ============================ 3 | 4 | Provided here are copies of just the files quoted in: 5 | 6 | Linux Programming By Example: The Fundamentals 7 | 8 | by Arnold Robbins, Copyright (C) 2004, Prentice Hall. 9 | 10 | The original distributions may be obtained in full from the Free Software 11 | Foundation's FTP site, at the following URLs: 12 | 13 | Coreutils 5.0: ftp://ftp.gnu.org/gnu/coreutils/coreutils-5.0.tar.gz 14 | Gawk 3.0.6 ftp://ftp.gnu.org/gnu/gawk/gawk-3.0.6.tar.gz 15 | Gawk 3.1.3 ftp://ftp.gnu.org/gnu/gawk/gawk-3.1.3.tar.gz 16 | Gawk 3.1.4 ftp://ftp.gnu.org/gnu/gawk/gawk-3.1.4.tar.gz 17 | Make 3.80: ftp://ftp.gnu.org/gnu/make/make-3.80.tar.gz 18 | GLIBC 2.3.2 ftp://ftp.gnu.org/gnu/glibc/glibc-2.3.2.tar.gz 19 | 20 | The `getopt' directory contains the source for the GNU getopt() and 21 | getopt_long() functions, copied from the gawk 3.1.3 distribution. 22 | 23 | You may also find the source for the current version of these utilities 24 | in your GNU/Linux distribution. 25 | -------------------------------------------------------------------------------- /gnu/coreutils-5.0/lib/safe-read.c: -------------------------------------------------------------------------------- 1 | /* An interface to read and write that retries after interrupts. 2 | Copyright (C) 1993, 1994, 1998, 2002 Free Software Foundation, Inc. 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2, or (at your option) 7 | any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software Foundation, 16 | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 17 | 18 | #if HAVE_CONFIG_H 19 | # include 20 | #endif 21 | 22 | /* Get ssize_t. */ 23 | #include 24 | #if HAVE_UNISTD_H 25 | # include 26 | #endif 27 | 28 | #include 29 | #ifndef errno 30 | extern int errno; 31 | #endif 32 | 33 | #ifdef EINTR 34 | # define IS_EINTR(x) ((x) == EINTR) 35 | #else 36 | # define IS_EINTR(x) 0 37 | #endif 38 | 39 | #include 40 | 41 | #ifndef CHAR_BIT 42 | # define CHAR_BIT 8 43 | #endif 44 | 45 | /* The extra casts work around common compiler bugs. */ 46 | #define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) 47 | /* The outer cast is needed to work around a bug in Cray C 5.0.3.0. 48 | It is necessary at least when t == time_t. */ 49 | #define TYPE_MINIMUM(t) ((t) (TYPE_SIGNED (t) \ 50 | ? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) : (t) 0)) 51 | #define TYPE_MAXIMUM(t) ((t) (~ (t) 0 - TYPE_MINIMUM (t))) 52 | 53 | #ifndef INT_MAX 54 | # define INT_MAX TYPE_MAXIMUM (int) 55 | #endif 56 | 57 | #ifdef SAFE_WRITE 58 | # include "safe-write.h" 59 | # define safe_rw safe_write 60 | # define rw write 61 | #else 62 | # include "safe-read.h" 63 | # define safe_rw safe_read 64 | # define rw read 65 | # undef const 66 | # define const /* empty */ 67 | #endif 68 | 69 | /* Read(write) up to COUNT bytes at BUF from(to) descriptor FD, retrying if 70 | interrupted. Return the actual number of bytes read(written), zero for EOF, 71 | or SAFE_READ_ERROR(SAFE_WRITE_ERROR) upon error. */ 72 | size_t 73 | safe_rw (int fd, void const *buf, size_t count) 74 | { 75 | ssize_t result; 76 | 77 | /* POSIX limits COUNT to SSIZE_MAX, but we limit it further, requiring 78 | that COUNT <= INT_MAX, to avoid triggering a bug in Tru64 5.1. 79 | When decreasing COUNT, keep the file pointer block-aligned. 80 | Note that in any case, read(write) may succeed, yet read(write) 81 | fewer than COUNT bytes, so the caller must be prepared to handle 82 | partial results. */ 83 | if (count > INT_MAX) 84 | count = INT_MAX & ~8191; 85 | 86 | do 87 | { 88 | result = rw (fd, buf, count); 89 | } 90 | while (result < 0 && IS_EINTR (errno)); 91 | 92 | return (size_t) result; 93 | } 94 | -------------------------------------------------------------------------------- /gnu/coreutils-5.0/lib/safe-write.c: -------------------------------------------------------------------------------- 1 | /* An interface to write that retries after interrupts. 2 | Copyright (C) 2002 Free Software Foundation, Inc. 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2, or (at your option) 7 | any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software Foundation, 16 | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 17 | 18 | #define SAFE_WRITE 19 | #include "safe-read.c" 20 | -------------------------------------------------------------------------------- /gnu/coreutils-5.0/lib/utime.c: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 1998, 2001-2002 Free Software Foundation, Inc. 2 | 3 | This program is free software; you can redistribute it and/or modify it 4 | under the terms of the GNU General Public License as published by the 5 | Free Software Foundation; either version 2, or (at your option) any 6 | later version. 7 | 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with this program; if not, write to the Free Software Foundation, 15 | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 16 | 17 | /* derived from a function in touch.c */ 18 | 19 | #ifdef HAVE_CONFIG_H 20 | # include 21 | #endif 22 | #undef utime 23 | 24 | #include 25 | 26 | #ifdef HAVE_UTIME_H 27 | # include 28 | #endif 29 | 30 | #include "full-write.h" 31 | #include "safe-read.h" 32 | 33 | /* Some systems (even some that do have ) don't declare this 34 | structure anywhere. */ 35 | #ifndef HAVE_STRUCT_UTIMBUF 36 | struct utimbuf 37 | { 38 | long actime; 39 | long modtime; 40 | }; 41 | #endif 42 | 43 | /* Emulate utime (file, NULL) for systems (like 4.3BSD) that do not 44 | interpret it to set the access and modification times of FILE to 45 | the current time. Return 0 if successful, -1 if not. */ 46 | 47 | static int 48 | utime_null (const char *file) 49 | { 50 | #if HAVE_UTIMES_NULL 51 | return utimes (file, 0); 52 | #else 53 | int fd; 54 | char c; 55 | int status = 0; 56 | struct stat sb; 57 | 58 | fd = open (file, O_RDWR); 59 | if (fd < 0 60 | || fstat (fd, &sb) < 0 61 | || safe_read (fd, &c, sizeof c) == SAFE_READ_ERROR 62 | || lseek (fd, (off_t) 0, SEEK_SET) < 0 63 | || full_write (fd, &c, sizeof c) != sizeof c 64 | /* Maybe do this -- it's necessary on SunOS4.1.3 with some combination 65 | of patches, but that system doesn't use this code: it has utimes. 66 | || fsync (fd) < 0 67 | */ 68 | || (st.st_size == 0 && ftruncate (fd, st.st_size) < 0) 69 | || close (fd) < 0) 70 | status = -1; 71 | return status; 72 | #endif 73 | } 74 | 75 | int 76 | rpl_utime (const char *file, const struct utimbuf *times) 77 | { 78 | if (times) 79 | return utime (file, times); 80 | 81 | return utime_null (file); 82 | } 83 | -------------------------------------------------------------------------------- /gnu/coreutils-5.0/lib/xreadlink.c: -------------------------------------------------------------------------------- 1 | /* xreadlink.c -- readlink wrapper to return the link name in malloc'd storage 2 | 3 | Copyright 2001 Free Software Foundation, Inc. 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 2, or (at your option) 8 | any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program; see the file COPYING. 17 | If not, write to the Free Software Foundation, 18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 19 | 20 | /* Written by Jim Meyering */ 21 | 22 | #if HAVE_CONFIG_H 23 | # include 24 | #endif 25 | 26 | #include 27 | #include 28 | #ifndef errno 29 | extern int errno; 30 | #endif 31 | 32 | #if HAVE_LIMITS_H 33 | # include 34 | #endif 35 | #if HAVE_SYS_TYPES_H 36 | # include 37 | #endif 38 | #if HAVE_STDLIB_H 39 | # include 40 | #endif 41 | #if HAVE_UNISTD_H 42 | # include 43 | #endif 44 | 45 | #ifndef SIZE_MAX 46 | # define SIZE_MAX ((size_t) -1) 47 | #endif 48 | #ifndef SSIZE_MAX 49 | # define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2)) 50 | #endif 51 | 52 | #include "xalloc.h" 53 | #include "xreadlink.h" 54 | 55 | /* Call readlink to get the symbolic link value of FILENAME. 56 | Return a pointer to that NUL-terminated string in malloc'd storage. 57 | If readlink fails, return NULL (caller may use errno to diagnose). 58 | If realloc fails, or if the link value is longer than SIZE_MAX :-), 59 | give a diagnostic and exit. */ 60 | 61 | char * 62 | xreadlink (char const *filename) 63 | { 64 | /* The initial buffer size for the link value. A power of 2 65 | detects arithmetic overflow earlier, but is not required. */ 66 | size_t buf_size = 128; 67 | 68 | while (1) 69 | { 70 | char *buffer = xmalloc (buf_size); 71 | ssize_t link_length = readlink (filename, buffer, buf_size); 72 | 73 | if (link_length < 0) 74 | { 75 | int saved_errno = errno; 76 | free (buffer); 77 | errno = saved_errno; 78 | return NULL; 79 | } 80 | 81 | if ((size_t) link_length < buf_size) 82 | { 83 | buffer[link_length] = 0; 84 | return buffer; 85 | } 86 | 87 | free (buffer); 88 | buf_size *= 2; 89 | if (SSIZE_MAX < buf_size || (SIZE_MAX / 2 < SSIZE_MAX && buf_size == 0)) 90 | xalloc_die (); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /gnu/coreutils-5.0/src/env.c: -------------------------------------------------------------------------------- 1 | /* env - run a program in a modified environment 2 | Copyright (C) 1986, 1991-2003 Free Software Foundation, Inc. 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2, or (at your option) 7 | any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software Foundation, 16 | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 17 | 18 | /* Richard Mlynarik and David MacKenzie */ 19 | 20 | /* Options: 21 | - 22 | -i 23 | --ignore-environment 24 | Construct a new environment from scratch; normally the 25 | environment is inherited from the parent process, except as 26 | modified by other options. 27 | 28 | -u variable 29 | --unset=variable 30 | Unset variable VARIABLE (remove it from the environment). 31 | If VARIABLE was not set, does nothing. 32 | 33 | variable=value (an arg containing a "=" character) 34 | Set the environment variable VARIABLE to value VALUE. VALUE 35 | may be of zero length ("variable="). Setting a variable to a 36 | zero-length value is different from unsetting it. 37 | 38 | -- 39 | Indicate that the following argument is the program 40 | to invoke. This is necessary when the program's name 41 | begins with "-" or contains a "=". 42 | 43 | The first remaining argument specifies a program to invoke; 44 | it is searched for according to the specification of the PATH 45 | environment variable. Any arguments following that are 46 | passed as arguments to that program. 47 | 48 | If no command name is specified following the environment 49 | specifications, the resulting environment is printed. 50 | This is like specifying a command name of "printenv". 51 | 52 | Examples: 53 | 54 | If the environment passed to "env" is 55 | { LOGNAME=rms EDITOR=emacs PATH=.:/gnubin:/hacks } 56 | 57 | env - foo 58 | runs "foo" in a null environment. 59 | 60 | env foo 61 | runs "foo" in the environment 62 | { LOGNAME=rms EDITOR=emacs PATH=.:/gnubin:/hacks } 63 | 64 | env DISPLAY=gnu:0 nemacs 65 | runs "nemacs" in the environment 66 | { LOGNAME=rms EDITOR=emacs PATH=.:/gnubin:/hacks DISPLAY=gnu:0 } 67 | 68 | env - LOGNAME=foo /hacks/hack bar baz 69 | runs the "hack" program on arguments "bar" and "baz" in an 70 | environment in which the only variable is "LOGNAME". Note that 71 | the "-" option clears out the PATH variable, so one should be 72 | careful to specify in which directory to find the program to 73 | call. 74 | 75 | env -u EDITOR LOGNAME=foo PATH=/energy -- e=mc2 bar baz 76 | runs the program "/energy/e=mc2" with environment 77 | { LOGNAME=foo PATH=/energy } 78 | */ 79 | 80 | #include 81 | #include 82 | #include 83 | #include 84 | #include 85 | 86 | #include "system.h" 87 | #include "error.h" 88 | #include "closeout.h" 89 | 90 | /* The official name of this program (e.g., no `g' prefix). */ 91 | #define PROGRAM_NAME "env" 92 | 93 | #define AUTHORS N_ ("Richard Mlynarik and David MacKenzie") 94 | 95 | int putenv (); 96 | 97 | extern char **environ; 98 | 99 | /* The name by which this program was run. */ 100 | char *program_name; 101 | 102 | static struct option const longopts[] = 103 | { 104 | {"ignore-environment", no_argument, NULL, 'i'}, 105 | {"unset", required_argument, NULL, 'u'}, 106 | {GETOPT_HELP_OPTION_DECL}, 107 | {GETOPT_VERSION_OPTION_DECL}, 108 | {NULL, 0, NULL, 0} 109 | }; 110 | 111 | void 112 | usage (int status) 113 | { 114 | if (status != 0) 115 | fprintf (stderr, _("Try `%s --help' for more information.\n"), 116 | program_name); 117 | else 118 | { 119 | printf (_("\ 120 | Usage: %s [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]\n"), 121 | program_name); 122 | fputs (_("\ 123 | Set each NAME to VALUE in the environment and run COMMAND.\n\ 124 | \n\ 125 | -i, --ignore-environment start with an empty environment\n\ 126 | -u, --unset=NAME remove variable from the environment\n\ 127 | "), stdout); 128 | fputs (HELP_OPTION_DESCRIPTION, stdout); 129 | fputs (VERSION_OPTION_DESCRIPTION, stdout); 130 | fputs (_("\ 131 | \n\ 132 | A mere - implies -i. If no COMMAND, print the resulting environment.\n\ 133 | "), stdout); 134 | printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT); 135 | } 136 | exit (status); 137 | } 138 | 139 | int 140 | main (register int argc, register char **argv, char **envp) 141 | { 142 | char *dummy_environ[1]; 143 | int optc; 144 | int ignore_environment = 0; 145 | 146 | program_name = argv[0]; 147 | setlocale (LC_ALL, ""); 148 | bindtextdomain (PACKAGE, LOCALEDIR); 149 | textdomain (PACKAGE); 150 | 151 | atexit (close_stdout); 152 | 153 | while ((optc = getopt_long (argc, argv, "+iu:", longopts, NULL)) != -1) 154 | { 155 | switch (optc) 156 | { 157 | case 0: 158 | break; 159 | case 'i': 160 | ignore_environment = 1; 161 | break; 162 | case 'u': 163 | break; 164 | case_GETOPT_HELP_CHAR; 165 | case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); 166 | default: 167 | usage (2); 168 | } 169 | } 170 | 171 | if (optind != argc && !strcmp (argv[optind], "-")) 172 | ignore_environment = 1; 173 | 174 | environ = dummy_environ; 175 | environ[0] = NULL; 176 | 177 | if (!ignore_environment) 178 | for (; *envp; envp++) 179 | putenv (*envp); 180 | 181 | optind = 0; /* Force GNU getopt to re-initialize. */ 182 | while ((optc = getopt_long (argc, argv, "+iu:", longopts, NULL)) != -1) 183 | if (optc == 'u') 184 | putenv (optarg); /* Requires GNU putenv. */ 185 | 186 | if (optind != argc && !strcmp (argv[optind], "-")) 187 | ++optind; 188 | 189 | while (optind < argc && strchr (argv[optind], '=')) 190 | putenv (argv[optind++]); 191 | 192 | /* If no program is specified, print the environment and exit. */ 193 | if (optind == argc) 194 | { 195 | while (*environ) 196 | puts (*environ++); 197 | exit (EXIT_SUCCESS); 198 | } 199 | 200 | execvp (argv[optind], &argv[optind]); 201 | 202 | { 203 | int exit_status = (errno == ENOENT ? 127 : 126); 204 | error (0, errno, "%s", argv[optind]); 205 | exit (exit_status); 206 | } 207 | } 208 | -------------------------------------------------------------------------------- /gnu/coreutils-5.0/src/link.c: -------------------------------------------------------------------------------- 1 | /* link utility for GNU. 2 | Copyright (C) 2001-2002 Free Software Foundation, Inc. 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2, or (at your option) 7 | any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software Foundation, 16 | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 17 | 18 | /* Written by Michael Stone */ 19 | 20 | /* Implementation overview: 21 | 22 | Simply call the system 'link' function */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include "system.h" 31 | #include "error.h" 32 | #include "long-options.h" 33 | #include "quote.h" 34 | 35 | /* The official name of this program (e.g., no `g' prefix). */ 36 | #define PROGRAM_NAME "link" 37 | 38 | #define AUTHORS "Michael Stone" 39 | 40 | /* Name this program was run with. */ 41 | char *program_name; 42 | 43 | void 44 | usage (int status) 45 | { 46 | if (status != 0) 47 | fprintf (stderr, _("Try `%s --help' for more information.\n"), 48 | program_name); 49 | else 50 | { 51 | printf (_("\ 52 | Usage: %s FILE1 FILE2\n\ 53 | or: %s OPTION\n"), program_name, program_name); 54 | fputs (_("Call the link function to create a link named FILE2\ 55 | to an existing FILE1.\n\n"), 56 | stdout); 57 | fputs (HELP_OPTION_DESCRIPTION, stdout); 58 | fputs (VERSION_OPTION_DESCRIPTION, stdout); 59 | printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT); 60 | } 61 | exit (status); 62 | } 63 | 64 | int 65 | main (int argc, char **argv) 66 | { 67 | program_name = argv[0]; 68 | setlocale (LC_ALL, ""); 69 | bindtextdomain (PACKAGE, LOCALEDIR); 70 | textdomain (PACKAGE); 71 | 72 | atexit (close_stdout); 73 | 74 | parse_long_options (argc, argv, PROGRAM_NAME, GNU_PACKAGE, VERSION, 75 | AUTHORS, usage); 76 | 77 | /* The above handles --help and --version. 78 | Since there is no other invocation of getopt, handle `--' here. */ 79 | if (1 < argc && STREQ (argv[1], "--")) 80 | { 81 | --argc; 82 | ++argv; 83 | } 84 | 85 | if (argc < 3) 86 | { 87 | error (0, 0, _("too few arguments")); 88 | usage (EXIT_FAILURE); 89 | } 90 | 91 | if (3 < argc) 92 | { 93 | error (0, 0, _("too many arguments")); 94 | usage (EXIT_FAILURE); 95 | } 96 | 97 | if (link (argv[1], argv[2]) != 0) 98 | error (EXIT_FAILURE, errno, _("cannot create link %s to %s"), 99 | quote_n (0, argv[2]), quote_n (1, argv[1])); 100 | 101 | exit (EXIT_SUCCESS); 102 | } 103 | -------------------------------------------------------------------------------- /gnu/coreutils-5.0/src/pathchk.c: -------------------------------------------------------------------------------- 1 | /* pathchk -- check whether pathnames are valid or portable 2 | Copyright (C) 1991-2003 Free Software Foundation, Inc. 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2, or (at your option) 7 | any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software Foundation, 16 | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 17 | 18 | /* Usage: pathchk [-p] [--portability] path... 19 | 20 | For each PATH, print a message if any of these conditions are false: 21 | * all existing leading directories in PATH have search (execute) permission 22 | * strlen (PATH) <= PATH_MAX 23 | * strlen (each_directory_in_PATH) <= NAME_MAX 24 | 25 | Exit status: 26 | 0 All PATH names passed all of the tests. 27 | 1 An error occurred. 28 | 29 | Options: 30 | -p, --portability Instead of performing length checks on the 31 | underlying filesystem, test the length of the 32 | pathname and its components against the POSIX 33 | minimum limits for portability, _POSIX_NAME_MAX 34 | and _POSIX_PATH_MAX in 2.9.2. Also check that 35 | the pathname contains no character not in the 36 | portable filename character set. 37 | 38 | David MacKenzie 39 | and Jim Meyering */ 40 | 41 | #include 42 | #include 43 | #include 44 | #include 45 | 46 | #include 47 | #ifndef errno 48 | extern int errno; 49 | #endif 50 | 51 | #include "system.h" 52 | #include "error.h" 53 | #include "long-options.h" 54 | #include "closeout.h" 55 | 56 | /* The official name of this program (e.g., no `g' prefix). */ 57 | #define PROGRAM_NAME "pathchk" 58 | 59 | #define AUTHORS N_ ("David MacKenzie and Jim Meyering") 60 | 61 | #define NEED_PATHCONF_WRAPPER 0 62 | #if HAVE_PATHCONF 63 | # ifndef PATH_MAX 64 | # define PATH_MAX_FOR(p) pathconf_wrapper ((p), _PC_PATH_MAX) 65 | # define NEED_PATHCONF_WRAPPER 1 66 | # endif /* not PATH_MAX */ 67 | # ifndef NAME_MAX 68 | # define NAME_MAX_FOR(p) pathconf_wrapper ((p), _PC_NAME_MAX); 69 | # undef NEED_PATHCONF_WRAPPER 70 | # define NEED_PATHCONF_WRAPPER 1 71 | # endif /* not NAME_MAX */ 72 | 73 | #else 74 | 75 | # include 76 | # ifndef PATH_MAX 77 | # ifdef MAXPATHLEN 78 | # define PATH_MAX MAXPATHLEN 79 | # else /* not MAXPATHLEN */ 80 | # define PATH_MAX _POSIX_PATH_MAX 81 | # endif /* not MAXPATHLEN */ 82 | # endif /* not PATH_MAX */ 83 | 84 | # ifndef NAME_MAX 85 | # ifdef MAXNAMLEN 86 | # define NAME_MAX MAXNAMLEN 87 | # else /* not MAXNAMLEN */ 88 | # define NAME_MAX _POSIX_NAME_MAX 89 | # endif /* not MAXNAMLEN */ 90 | # endif /* not NAME_MAX */ 91 | 92 | #endif 93 | 94 | #ifndef _POSIX_PATH_MAX 95 | # define _POSIX_PATH_MAX 255 96 | #endif 97 | #ifndef _POSIX_NAME_MAX 98 | # define _POSIX_NAME_MAX 14 99 | #endif 100 | 101 | #ifndef PATH_MAX_FOR 102 | # define PATH_MAX_FOR(p) PATH_MAX 103 | #endif 104 | #ifndef NAME_MAX_FOR 105 | # define NAME_MAX_FOR(p) NAME_MAX 106 | #endif 107 | 108 | static int validate_path (char *path, int portability); 109 | 110 | /* The name this program was run with. */ 111 | char *program_name; 112 | 113 | static struct option const longopts[] = 114 | { 115 | {"portability", no_argument, NULL, 'p'}, 116 | {NULL, 0, NULL, 0} 117 | }; 118 | 119 | #if NEED_PATHCONF_WRAPPER 120 | /* Distinguish between the cases when pathconf fails and when it reports there 121 | is no limit (the latter is the case for PATH_MAX on the Hurd). When there 122 | is no limit, return LONG_MAX. Otherwise, return pathconf's return value. */ 123 | 124 | static long int 125 | pathconf_wrapper (const char *filename, int param) 126 | { 127 | long int ret; 128 | 129 | errno = 0; 130 | ret = pathconf (filename, param); 131 | if (ret < 0 && errno == 0) 132 | return LONG_MAX; 133 | 134 | return ret; 135 | } 136 | #endif 137 | 138 | void 139 | usage (int status) 140 | { 141 | if (status != 0) 142 | fprintf (stderr, _("Try `%s --help' for more information.\n"), 143 | program_name); 144 | else 145 | { 146 | printf (_("Usage: %s [OPTION]... NAME...\n"), program_name); 147 | fputs (_("\ 148 | Diagnose unportable constructs in NAME.\n\ 149 | \n\ 150 | -p, --portability check for all POSIX systems, not only this one\n\ 151 | "), stdout); 152 | fputs (HELP_OPTION_DESCRIPTION, stdout); 153 | fputs (VERSION_OPTION_DESCRIPTION, stdout); 154 | printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT); 155 | } 156 | exit (status); 157 | } 158 | 159 | int 160 | main (int argc, char **argv) 161 | { 162 | int exit_status = 0; 163 | int check_portability = 0; 164 | int optc; 165 | 166 | program_name = argv[0]; 167 | setlocale (LC_ALL, ""); 168 | bindtextdomain (PACKAGE, LOCALEDIR); 169 | textdomain (PACKAGE); 170 | 171 | atexit (close_stdout); 172 | 173 | parse_long_options (argc, argv, PROGRAM_NAME, GNU_PACKAGE, VERSION, 174 | AUTHORS, usage); 175 | 176 | while ((optc = getopt_long (argc, argv, "p", longopts, NULL)) != -1) 177 | { 178 | switch (optc) 179 | { 180 | case 0: 181 | break; 182 | 183 | case 'p': 184 | check_portability = 1; 185 | break; 186 | 187 | default: 188 | usage (EXIT_FAILURE); 189 | } 190 | } 191 | 192 | if (optind == argc) 193 | { 194 | error (0, 0, _("too few arguments")); 195 | usage (EXIT_FAILURE); 196 | } 197 | 198 | for (; optind < argc; ++optind) 199 | exit_status |= validate_path (argv[optind], check_portability); 200 | 201 | exit (exit_status); 202 | } 203 | 204 | /* Each element is nonzero if the corresponding ASCII character is 205 | in the POSIX portable character set, and zero if it is not. 206 | In addition, the entry for `/' is nonzero to simplify checking. */ 207 | static char const portable_chars[256] = 208 | { 209 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0-15 */ 210 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 16-31 */ 211 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, /* 32-47 */ 212 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 48-63 */ 213 | 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 64-79 */ 214 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 80-95 */ 215 | 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 96-111 */ 216 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 112-127 */ 217 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 218 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 219 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 221 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 222 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 223 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 225 | }; 226 | 227 | /* If PATH contains only portable characters, return 1, else 0. */ 228 | 229 | static int 230 | portable_chars_only (const char *path) 231 | { 232 | const char *p; 233 | 234 | for (p = path; *p; ++p) 235 | if (portable_chars[(unsigned char) *p] == 0) 236 | { 237 | error (0, 0, _("path `%s' contains nonportable character `%c'"), 238 | path, *p); 239 | return 0; 240 | } 241 | return 1; 242 | } 243 | 244 | /* Return 1 if PATH is a usable leading directory, 0 if not, 245 | 2 if it doesn't exist. */ 246 | 247 | static int 248 | dir_ok (const char *path) 249 | { 250 | struct stat stats; 251 | 252 | if (stat (path, &stats)) 253 | return 2; 254 | 255 | if (!S_ISDIR (stats.st_mode)) 256 | { 257 | error (0, 0, _("`%s' is not a directory"), path); 258 | return 0; 259 | } 260 | 261 | /* Use access to test for search permission because 262 | testing permission bits of st_mode can lose with new 263 | access control mechanisms. Of course, access loses if you're 264 | running setuid. */ 265 | if (access (path, X_OK) != 0) 266 | { 267 | if (errno == EACCES) 268 | error (0, 0, _("directory `%s' is not searchable"), path); 269 | else 270 | error (0, errno, "%s", path); 271 | return 0; 272 | } 273 | 274 | return 1; 275 | } 276 | 277 | /* Make sure that 278 | strlen (PATH) <= PATH_MAX 279 | && strlen (each-existing-directory-in-PATH) <= NAME_MAX 280 | 281 | If PORTABILITY is nonzero, compare against _POSIX_PATH_MAX and 282 | _POSIX_NAME_MAX instead, and make sure that PATH contains no 283 | characters not in the POSIX portable filename character set, which 284 | consists of A-Z, a-z, 0-9, ., _, -. 285 | 286 | Make sure that all leading directories along PATH that exist have 287 | `x' permission. 288 | 289 | Return 0 if all of these tests are successful, 1 if any fail. */ 290 | 291 | static int 292 | validate_path (char *path, int portability) 293 | { 294 | long int path_max; 295 | int last_elem; /* Nonzero if checking last element of path. */ 296 | int exists IF_LINT (= 0); /* 2 if the path element exists. */ 297 | char *slash; 298 | char *parent; /* Last existing leading directory so far. */ 299 | 300 | if (portability && !portable_chars_only (path)) 301 | return 1; 302 | 303 | if (*path == '\0') 304 | return 0; 305 | 306 | /* Figure out the parent of the first element in PATH. */ 307 | parent = xstrdup (*path == '/' ? "/" : "."); 308 | 309 | slash = path; 310 | last_elem = 0; 311 | while (1) 312 | { 313 | long int name_max; 314 | long int length; /* Length of partial path being checked. */ 315 | char *start; /* Start of path element being checked. */ 316 | 317 | /* Find the end of this element of the path. 318 | Then chop off the rest of the path after this element. */ 319 | while (*slash == '/') 320 | slash++; 321 | start = slash; 322 | slash = strchr (slash, '/'); 323 | if (slash != NULL) 324 | *slash = '\0'; 325 | else 326 | { 327 | last_elem = 1; 328 | slash = strchr (start, '\0'); 329 | } 330 | 331 | if (!last_elem) 332 | { 333 | exists = dir_ok (path); 334 | if (exists == 0) 335 | { 336 | free (parent); 337 | return 1; 338 | } 339 | } 340 | 341 | length = slash - start; 342 | /* Since we know that `parent' is a directory, it's ok to call 343 | pathconf with it as the argument. (If `parent' isn't a directory 344 | or doesn't exist, the behavior of pathconf is undefined.) 345 | But if `parent' is a directory and is on a remote file system, 346 | it's likely that pathconf can't give us a reasonable value 347 | and will return -1. (NFS and tempfs are not POSIX . . .) 348 | In that case, we have no choice but to assume the pessimal 349 | POSIX minimums. */ 350 | name_max = portability ? _POSIX_NAME_MAX : NAME_MAX_FOR (parent); 351 | if (name_max < 0) 352 | name_max = _POSIX_NAME_MAX; 353 | if (length > name_max) 354 | { 355 | error (0, 0, _("name `%s' has length %ld; exceeds limit of %ld"), 356 | start, length, name_max); 357 | free (parent); 358 | return 1; 359 | } 360 | 361 | if (last_elem) 362 | break; 363 | 364 | if (exists == 1) 365 | { 366 | free (parent); 367 | parent = xstrdup (path); 368 | } 369 | 370 | *slash++ = '/'; 371 | } 372 | 373 | /* `parent' is now the last existing leading directory in the whole path, 374 | so it's ok to call pathconf with it as the argument. */ 375 | path_max = portability ? _POSIX_PATH_MAX : PATH_MAX_FOR (parent); 376 | if (path_max < 0) 377 | path_max = _POSIX_PATH_MAX; 378 | free (parent); 379 | if (strlen (path) > (size_t) path_max) 380 | { 381 | error (0, 0, _("path `%s' has length %d; exceeds limit of %ld"), 382 | path, strlen (path), path_max); 383 | return 1; 384 | } 385 | 386 | return 0; 387 | } 388 | -------------------------------------------------------------------------------- /gnu/coreutils-5.0/src/sort.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perusio/linux-programming-by-example/4878093a8485d28cf5958a5e5b005e18fb3709c4/gnu/coreutils-5.0/src/sort.c -------------------------------------------------------------------------------- /gnu/coreutils-5.0/src/sys2.h: -------------------------------------------------------------------------------- 1 | /* WARNING -- this file is temporary. It is shared between the 2 | sh-utils, fileutils, and textutils packages. Once I find a little 3 | more time, I'll merge the remaining things in system.h and everything 4 | in this file will go back there. */ 5 | 6 | #ifndef S_IFMT 7 | # define S_IFMT 0170000 8 | #endif 9 | 10 | #if STAT_MACROS_BROKEN 11 | # undef S_ISBLK 12 | # undef S_ISCHR 13 | # undef S_ISDIR 14 | # undef S_ISDOOR 15 | # undef S_ISFIFO 16 | # undef S_ISLNK 17 | # undef S_ISNAM 18 | # undef S_ISMPB 19 | # undef S_ISMPC 20 | # undef S_ISNWK 21 | # undef S_ISREG 22 | # undef S_ISSOCK 23 | #endif 24 | 25 | 26 | #ifndef S_ISBLK 27 | # ifdef S_IFBLK 28 | # define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) 29 | # else 30 | # define S_ISBLK(m) 0 31 | # endif 32 | #endif 33 | 34 | #ifndef S_ISCHR 35 | # ifdef S_IFCHR 36 | # define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) 37 | # else 38 | # define S_ISCHR(m) 0 39 | # endif 40 | #endif 41 | 42 | #ifndef S_ISDIR 43 | # ifdef S_IFDIR 44 | # define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) 45 | # else 46 | # define S_ISDIR(m) 0 47 | # endif 48 | #endif 49 | 50 | #ifndef S_ISDOOR /* Solaris 2.5 and up */ 51 | # ifdef S_IFDOOR 52 | # define S_ISDOOR(m) (((m) & S_IFMT) == S_IFDOOR) 53 | # else 54 | # define S_ISDOOR(m) 0 55 | # endif 56 | #endif 57 | 58 | #ifndef S_ISFIFO 59 | # ifdef S_IFIFO 60 | # define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) 61 | # else 62 | # define S_ISFIFO(m) 0 63 | # endif 64 | #endif 65 | 66 | #ifndef S_ISLNK 67 | # ifdef S_IFLNK 68 | # define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) 69 | # else 70 | # define S_ISLNK(m) 0 71 | # endif 72 | #endif 73 | 74 | #ifndef S_ISMPB /* V7 */ 75 | # ifdef S_IFMPB 76 | # define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB) 77 | # define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC) 78 | # else 79 | # define S_ISMPB(m) 0 80 | # define S_ISMPC(m) 0 81 | # endif 82 | #endif 83 | 84 | #ifndef S_ISNAM /* Xenix */ 85 | # ifdef S_IFNAM 86 | # define S_ISNAM(m) (((m) & S_IFMT) == S_IFNAM) 87 | # else 88 | # define S_ISNAM(m) 0 89 | # endif 90 | #endif 91 | 92 | #ifndef S_ISNWK /* HP/UX */ 93 | # ifdef S_IFNWK 94 | # define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK) 95 | # else 96 | # define S_ISNWK(m) 0 97 | # endif 98 | #endif 99 | 100 | #ifndef S_ISREG 101 | # ifdef S_IFREG 102 | # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) 103 | # else 104 | # define S_ISREG(m) 0 105 | # endif 106 | #endif 107 | 108 | #ifndef S_ISSOCK 109 | # ifdef S_IFSOCK 110 | # define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) 111 | # else 112 | # define S_ISSOCK(m) 0 113 | # endif 114 | #endif 115 | 116 | 117 | #ifndef S_TYPEISSEM 118 | # ifdef S_INSEM 119 | # define S_TYPEISSEM(p) (S_ISNAM ((p)->st_mode) && (p)->st_rdev == S_INSEM) 120 | # else 121 | # define S_TYPEISSEM(p) 0 122 | # endif 123 | #endif 124 | 125 | #ifndef S_TYPEISSHM 126 | # ifdef S_INSHD 127 | # define S_TYPEISSHM(p) (S_ISNAM ((p)->st_mode) && (p)->st_rdev == S_INSHD) 128 | # else 129 | # define S_TYPEISSHM(p) 0 130 | # endif 131 | #endif 132 | 133 | #ifndef S_TYPEISMQ 134 | # define S_TYPEISMQ(p) 0 135 | #endif 136 | 137 | 138 | /* If any of the following are undefined, 139 | define them to their de facto standard values. */ 140 | #if !S_ISUID 141 | # define S_ISUID 04000 142 | #endif 143 | #if !S_ISGID 144 | # define S_ISGID 02000 145 | #endif 146 | 147 | /* S_ISVTX is a common extension to POSIX. */ 148 | #ifndef S_ISVTX 149 | # define S_ISVTX 01000 150 | #endif 151 | 152 | #if !S_IRUSR && S_IREAD 153 | # define S_IRUSR S_IREAD 154 | #endif 155 | #if !S_IRUSR 156 | # define S_IRUSR 00400 157 | #endif 158 | #if !S_IRGRP 159 | # define S_IRGRP (S_IRUSR >> 3) 160 | #endif 161 | #if !S_IROTH 162 | # define S_IROTH (S_IRUSR >> 6) 163 | #endif 164 | 165 | #if !S_IWUSR && S_IWRITE 166 | # define S_IWUSR S_IWRITE 167 | #endif 168 | #if !S_IWUSR 169 | # define S_IWUSR 00200 170 | #endif 171 | #if !S_IWGRP 172 | # define S_IWGRP (S_IWUSR >> 3) 173 | #endif 174 | #if !S_IWOTH 175 | # define S_IWOTH (S_IWUSR >> 6) 176 | #endif 177 | 178 | #if !S_IXUSR && S_IEXEC 179 | # define S_IXUSR S_IEXEC 180 | #endif 181 | #if !S_IXUSR 182 | # define S_IXUSR 00100 183 | #endif 184 | #if !S_IXGRP 185 | # define S_IXGRP (S_IXUSR >> 3) 186 | #endif 187 | #if !S_IXOTH 188 | # define S_IXOTH (S_IXUSR >> 6) 189 | #endif 190 | 191 | #if !S_IRWXU 192 | # define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR) 193 | #endif 194 | #if !S_IRWXG 195 | # define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP) 196 | #endif 197 | #if !S_IRWXO 198 | # define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH) 199 | #endif 200 | 201 | /* S_IXUGO is a common extension to POSIX. */ 202 | #if !S_IXUGO 203 | # define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH) 204 | #endif 205 | 206 | #ifndef S_IRWXUGO 207 | # define S_IRWXUGO (S_IRWXU | S_IRWXG | S_IRWXO) 208 | #endif 209 | 210 | /* All the mode bits that can be affected by chmod. */ 211 | #define CHMOD_MODE_BITS \ 212 | (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO) 213 | 214 | #ifdef ST_MTIM_NSEC 215 | # define ST_TIME_CMP_NS(a, b, ns) ((a).ns < (b).ns ? -1 : (a).ns > (b).ns) 216 | #else 217 | # define ST_TIME_CMP_NS(a, b, ns) 0 218 | #endif 219 | #define ST_TIME_CMP(a, b, s, ns) \ 220 | ((a).s < (b).s ? -1 : (a).s > (b).s ? 1 : ST_TIME_CMP_NS(a, b, ns)) 221 | #define ATIME_CMP(a, b) ST_TIME_CMP (a, b, st_atime, st_atim.ST_MTIM_NSEC) 222 | #define CTIME_CMP(a, b) ST_TIME_CMP (a, b, st_ctime, st_ctim.ST_MTIM_NSEC) 223 | #define MTIME_CMP(a, b) ST_TIME_CMP (a, b, st_mtime, st_mtim.ST_MTIM_NSEC) 224 | 225 | #ifndef RETSIGTYPE 226 | # define RETSIGTYPE void 227 | #endif 228 | 229 | #if __GNUC__ 230 | # ifndef alloca 231 | # define alloca __builtin_alloca 232 | # endif 233 | #else 234 | # if HAVE_ALLOCA_H 235 | # include 236 | # else 237 | # ifdef _AIX 238 | # pragma alloca 239 | # else 240 | # ifdef _WIN32 241 | # include 242 | # include 243 | # else 244 | # ifndef alloca 245 | char *alloca (); 246 | # endif 247 | # endif 248 | # endif 249 | # endif 250 | #endif 251 | 252 | #ifdef __DJGPP__ 253 | /* We need the declaration of setmode. */ 254 | # include 255 | /* We need the declaration of __djgpp_set_ctrl_c. */ 256 | # include 257 | #endif 258 | 259 | #if HAVE_STDINT_H 260 | # include 261 | #endif 262 | 263 | #if HAVE_INTTYPES_H 264 | # include /* for the definition of UINTMAX_MAX */ 265 | #endif 266 | 267 | #if !defined PRIdMAX || PRI_MACROS_BROKEN 268 | # undef PRIdMAX 269 | # define PRIdMAX (sizeof (uintmax_t) == sizeof (long) ? "ld" : "lld") 270 | #endif 271 | #if !defined PRIoMAX || PRI_MACROS_BROKEN 272 | # undef PRIoMAX 273 | # define PRIoMAX (sizeof (uintmax_t) == sizeof (long) ? "lo" : "llo") 274 | #endif 275 | #if !defined PRIuMAX || PRI_MACROS_BROKEN 276 | # undef PRIuMAX 277 | # define PRIuMAX (sizeof (uintmax_t) == sizeof (long) ? "lu" : "llu") 278 | #endif 279 | #if !defined PRIxMAX || PRI_MACROS_BROKEN 280 | # undef PRIxMAX 281 | # define PRIxMAX (sizeof (uintmax_t) == sizeof (long) ? "lx" : "llx") 282 | #endif 283 | 284 | #include 285 | 286 | /* Jim Meyering writes: 287 | 288 | "... Some ctype macros are valid only for character codes that 289 | isascii says are ASCII (SGI's IRIX-4.0.5 is one such system --when 290 | using /bin/cc or gcc but without giving an ansi option). So, all 291 | ctype uses should be through macros like ISPRINT... If 292 | STDC_HEADERS is defined, then autoconf has verified that the ctype 293 | macros don't need to be guarded with references to isascii. ... 294 | Defining isascii to 1 should let any compiler worth its salt 295 | eliminate the && through constant folding." 296 | 297 | Bruno Haible adds: 298 | 299 | "... Furthermore, isupper(c) etc. have an undefined result if c is 300 | outside the range -1 <= c <= 255. One is tempted to write isupper(c) 301 | with c being of type `char', but this is wrong if c is an 8-bit 302 | character >= 128 which gets sign-extended to a negative value. 303 | The macro ISUPPER protects against this as well." */ 304 | 305 | #if STDC_HEADERS || (!defined (isascii) && !HAVE_ISASCII) 306 | # define IN_CTYPE_DOMAIN(c) 1 307 | #else 308 | # define IN_CTYPE_DOMAIN(c) isascii(c) 309 | #endif 310 | 311 | #ifdef isblank 312 | # define ISBLANK(c) (IN_CTYPE_DOMAIN (c) && isblank (c)) 313 | #else 314 | # define ISBLANK(c) ((c) == ' ' || (c) == '\t') 315 | #endif 316 | #ifdef isgraph 317 | # define ISGRAPH(c) (IN_CTYPE_DOMAIN (c) && isgraph (c)) 318 | #else 319 | # define ISGRAPH(c) (IN_CTYPE_DOMAIN (c) && isprint (c) && !isspace (c)) 320 | #endif 321 | 322 | /* This is defined in on at least Solaris2.6 systems. */ 323 | #undef ISPRINT 324 | 325 | #define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint (c)) 326 | #define ISALNUM(c) (IN_CTYPE_DOMAIN (c) && isalnum (c)) 327 | #define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c)) 328 | #define ISCNTRL(c) (IN_CTYPE_DOMAIN (c) && iscntrl (c)) 329 | #define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower (c)) 330 | #define ISPUNCT(c) (IN_CTYPE_DOMAIN (c) && ispunct (c)) 331 | #define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c)) 332 | #define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper (c)) 333 | #define ISXDIGIT(c) (IN_CTYPE_DOMAIN (c) && isxdigit (c)) 334 | #define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c)) 335 | 336 | #if STDC_HEADERS 337 | # define TOLOWER(Ch) tolower (Ch) 338 | # define TOUPPER(Ch) toupper (Ch) 339 | #else 340 | # define TOLOWER(Ch) (ISUPPER (Ch) ? tolower (Ch) : (Ch)) 341 | # define TOUPPER(Ch) (ISLOWER (Ch) ? toupper (Ch) : (Ch)) 342 | #endif 343 | 344 | /* ISDIGIT differs from ISDIGIT_LOCALE, as follows: 345 | - Its arg may be any int or unsigned int; it need not be an unsigned char. 346 | - It's guaranteed to evaluate its argument exactly once. 347 | - It's typically faster. 348 | POSIX says that only '0' through '9' are digits. Prefer ISDIGIT to 349 | ISDIGIT_LOCALE unless it's important to use the locale's definition 350 | of `digit' even when the host does not conform to POSIX. */ 351 | #define ISDIGIT(c) ((unsigned) (c) - '0' <= 9) 352 | 353 | /* Take care of NLS matters. */ 354 | 355 | #if HAVE_LOCALE_H 356 | # include 357 | #else 358 | # define setlocale(Category, Locale) /* empty */ 359 | #endif 360 | 361 | #include "gettext.h" 362 | 363 | #define _(msgid) gettext (msgid) 364 | #define N_(msgid) msgid 365 | 366 | #ifndef HAVE_SETLOCALE 367 | # define HAVE_SETLOCALE 0 368 | #endif 369 | 370 | #define STREQ(a, b) (strcmp ((a), (b)) == 0) 371 | 372 | #if !HAVE_DECL_FREE 373 | void free (); 374 | #endif 375 | 376 | #if !HAVE_DECL_MALLOC 377 | char *malloc (); 378 | #endif 379 | 380 | #if !HAVE_DECL_MEMCHR 381 | char *memchr (); 382 | #endif 383 | 384 | #if !HAVE_DECL_REALLOC 385 | char *realloc (); 386 | #endif 387 | 388 | #if !HAVE_DECL_STPCPY 389 | # ifndef stpcpy 390 | char *stpcpy (); 391 | # endif 392 | #endif 393 | 394 | #if !HAVE_DECL_STRNDUP 395 | char *strndup (); 396 | #endif 397 | 398 | #if !HAVE_DECL_STRSTR 399 | char *strstr (); 400 | #endif 401 | 402 | #if !HAVE_DECL_GETENV 403 | char *getenv (); 404 | #endif 405 | 406 | #if !HAVE_DECL_LSEEK 407 | off_t lseek (); 408 | #endif 409 | 410 | /* This is needed on some AIX systems. */ 411 | #if !HAVE_DECL_STRTOUL 412 | unsigned long strtoul (); 413 | #endif 414 | 415 | /* This is needed on some AIX systems. */ 416 | #if !HAVE_DECL_STRTOULL && HAVE_UNSIGNED_LONG_LONG 417 | unsigned long long strtoull (); 418 | #endif 419 | 420 | #if !HAVE_DECL_GETLOGIN 421 | char *getlogin (); 422 | #endif 423 | 424 | #if !HAVE_DECL_TTYNAME 425 | char *ttyname (); 426 | #endif 427 | 428 | #if !HAVE_DECL_GETEUID 429 | uid_t geteuid (); 430 | #endif 431 | 432 | #if !HAVE_DECL_GETPWUID 433 | struct passwd *getpwuid (); 434 | #endif 435 | 436 | #if !HAVE_DECL_GETGRGID 437 | struct group *getgrgid (); 438 | #endif 439 | 440 | #if !HAVE_DECL_GETUID 441 | uid_t getuid (); 442 | #endif 443 | 444 | #include "xalloc.h" 445 | 446 | #if ! defined HAVE_MEMPCPY && ! defined mempcpy 447 | /* Be CAREFUL that there are no side effects in N. */ 448 | # define mempcpy(D, S, N) ((void *) ((char *) memcpy (D, S, N) + (N))) 449 | #endif 450 | 451 | /* Include automatically-generated macros for unlocked I/O. */ 452 | #include "unlocked-io.h" 453 | 454 | #define SAME_INODE(Stat_buf_1, Stat_buf_2) \ 455 | ((Stat_buf_1).st_ino == (Stat_buf_2).st_ino \ 456 | && (Stat_buf_1).st_dev == (Stat_buf_2).st_dev) 457 | 458 | #define DOT_OR_DOTDOT(Basename) \ 459 | (Basename[0] == '.' && (Basename[1] == '\0' \ 460 | || (Basename[1] == '.' && Basename[2] == '\0'))) 461 | 462 | #if SETVBUF_REVERSED 463 | # define SETVBUF(Stream, Buffer, Type, Size) \ 464 | setvbuf (Stream, Type, Buffer, Size) 465 | #else 466 | # define SETVBUF(Stream, Buffer, Type, Size) \ 467 | setvbuf (Stream, Buffer, Type, Size) 468 | #endif 469 | 470 | /* Factor out some of the common --help and --version processing code. */ 471 | 472 | /* These enum values cannot possibly conflict with the option values 473 | ordinarily used by commands, including CHAR_MAX + 1, etc. Avoid 474 | CHAR_MIN - 1, as it may equal -1, the getopt end-of-options value. */ 475 | enum 476 | { 477 | GETOPT_HELP_CHAR = (CHAR_MIN - 2), 478 | GETOPT_VERSION_CHAR = (CHAR_MIN - 3) 479 | }; 480 | 481 | #define GETOPT_HELP_OPTION_DECL \ 482 | "help", no_argument, 0, GETOPT_HELP_CHAR 483 | #define GETOPT_VERSION_OPTION_DECL \ 484 | "version", no_argument, 0, GETOPT_VERSION_CHAR 485 | 486 | #define case_GETOPT_HELP_CHAR \ 487 | case GETOPT_HELP_CHAR: \ 488 | usage (EXIT_SUCCESS); \ 489 | break; 490 | 491 | #define HELP_OPTION_DESCRIPTION \ 492 | _(" --help display this help and exit\n") 493 | #define VERSION_OPTION_DESCRIPTION \ 494 | _(" --version output version information and exit\n") 495 | 496 | #include "closeout.h" 497 | #include "version-etc.h" 498 | 499 | #define case_GETOPT_VERSION_CHAR(Program_name, Authors) \ 500 | case GETOPT_VERSION_CHAR: \ 501 | version_etc (stdout, Program_name, PACKAGE, VERSION, Authors); \ 502 | exit (EXIT_SUCCESS); \ 503 | break; 504 | 505 | #ifndef MAX 506 | # define MAX(a, b) ((a) > (b) ? (a) : (b)) 507 | #endif 508 | 509 | #ifndef MIN 510 | # define MIN(a,b) (((a) < (b)) ? (a) : (b)) 511 | #endif 512 | 513 | #ifndef CHAR_BIT 514 | # define CHAR_BIT 8 515 | #endif 516 | 517 | /* The extra casts work around common compiler bugs. */ 518 | #define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) 519 | /* The outer cast is needed to work around a bug in Cray C 5.0.3.0. 520 | It is necessary at least when t == time_t. */ 521 | #define TYPE_MINIMUM(t) ((t) (TYPE_SIGNED (t) \ 522 | ? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) : (t) 0)) 523 | #define TYPE_MAXIMUM(t) ((t) (~ (t) 0 - TYPE_MINIMUM (t))) 524 | 525 | /* Upper bound on the string length of an integer converted to string. 526 | 302 / 1000 is ceil (log10 (2.0)). Subtract 1 for the sign bit; 527 | add 1 for integer division truncation; add 1 more for a minus sign. */ 528 | #define INT_STRLEN_BOUND(t) ((sizeof (t) * CHAR_BIT - 1) * 302 / 1000 + 2) 529 | 530 | #ifndef CHAR_MIN 531 | # define CHAR_MIN TYPE_MINIMUM (char) 532 | #endif 533 | 534 | #ifndef CHAR_MAX 535 | # define CHAR_MAX TYPE_MAXIMUM (char) 536 | #endif 537 | 538 | #ifndef SCHAR_MIN 539 | # define SCHAR_MIN (-1 - SCHAR_MAX) 540 | #endif 541 | 542 | #ifndef SCHAR_MAX 543 | # define SCHAR_MAX (CHAR_MAX == UCHAR_MAX ? CHAR_MAX / 2 : CHAR_MAX) 544 | #endif 545 | 546 | #ifndef UCHAR_MAX 547 | # define UCHAR_MAX TYPE_MAXIMUM (unsigned char) 548 | #endif 549 | 550 | #ifndef SHRT_MIN 551 | # define SHRT_MIN TYPE_MINIMUM (short int) 552 | #endif 553 | 554 | #ifndef SHRT_MAX 555 | # define SHRT_MAX TYPE_MAXIMUM (short int) 556 | #endif 557 | 558 | #ifndef INT_MAX 559 | # define INT_MAX TYPE_MAXIMUM (int) 560 | #endif 561 | 562 | #ifndef INT_MIN 563 | # define INT_MIN TYPE_MINIMUM (int) 564 | #endif 565 | 566 | #ifndef UINT_MAX 567 | # define UINT_MAX TYPE_MAXIMUM (unsigned int) 568 | #endif 569 | 570 | #ifndef LONG_MAX 571 | # define LONG_MAX TYPE_MAXIMUM (long) 572 | #endif 573 | 574 | #ifndef ULONG_MAX 575 | # define ULONG_MAX TYPE_MAXIMUM (unsigned long) 576 | #endif 577 | 578 | #ifndef SIZE_MAX 579 | # define SIZE_MAX TYPE_MAXIMUM (size_t) 580 | #endif 581 | 582 | #ifndef SSIZE_MAX 583 | # define SSIZE_MAX TYPE_MAXIMUM (ssize_t) 584 | #endif 585 | 586 | #ifndef UINTMAX_MAX 587 | # define UINTMAX_MAX TYPE_MAXIMUM (uintmax_t) 588 | #endif 589 | 590 | #ifndef OFF_T_MIN 591 | # define OFF_T_MIN TYPE_MINIMUM (off_t) 592 | #endif 593 | 594 | #ifndef OFF_T_MAX 595 | # define OFF_T_MAX TYPE_MAXIMUM (off_t) 596 | #endif 597 | 598 | #ifndef UID_T_MAX 599 | # define UID_T_MAX TYPE_MAXIMUM (uid_t) 600 | #endif 601 | 602 | #ifndef GID_T_MAX 603 | # define GID_T_MAX TYPE_MAXIMUM (gid_t) 604 | #endif 605 | 606 | #ifndef PID_T_MAX 607 | # define PID_T_MAX TYPE_MAXIMUM (pid_t) 608 | #endif 609 | 610 | #ifndef CHAR_BIT 611 | # define CHAR_BIT 8 612 | #endif 613 | 614 | /* Use this to suppress gcc's `...may be used before initialized' warnings. */ 615 | #ifdef lint 616 | # define IF_LINT(Code) Code 617 | #else 618 | # define IF_LINT(Code) /* empty */ 619 | #endif 620 | 621 | #ifndef __attribute__ 622 | # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__ 623 | # define __attribute__(x) 624 | # endif 625 | #endif 626 | 627 | #ifndef ATTRIBUTE_NORETURN 628 | # define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__)) 629 | #endif 630 | 631 | #ifndef ATTRIBUTE_UNUSED 632 | # define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) 633 | #endif 634 | 635 | #if defined strdupa 636 | # define ASSIGN_STRDUPA(DEST, S) \ 637 | do { DEST = strdupa(S); } while (0) 638 | #else 639 | # define ASSIGN_STRDUPA(DEST, S) \ 640 | do \ 641 | { \ 642 | const char *s_ = (S); \ 643 | size_t len_ = strlen (s_) + 1; \ 644 | char *tmp_dest_ = (char *) alloca (len_); \ 645 | DEST = memcpy (tmp_dest_, (s_), len_); \ 646 | } \ 647 | while (0) 648 | #endif 649 | 650 | #ifndef EOVERFLOW 651 | # define EOVERFLOW EINVAL 652 | #endif 653 | 654 | #if ! HAVE_FSEEKO && ! defined fseeko 655 | # define fseeko(s, o, w) ((o) == (long) (o) \ 656 | ? fseek (s, o, w) \ 657 | : (errno = EOVERFLOW, -1)) 658 | #endif 659 | -------------------------------------------------------------------------------- /gnu/coreutils-5.0/src/wc.c: -------------------------------------------------------------------------------- 1 | /* wc - print the number of bytes, words, and lines in files 2 | Copyright (C) 85, 91, 1995-2002 Free Software Foundation, Inc. 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2, or (at your option) 7 | any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software Foundation, 16 | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 17 | 18 | /* Written by Paul Rubin, phr@ocf.berkeley.edu 19 | and David MacKenzie, djm@gnu.ai.mit.edu. */ 20 | 21 | #include 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | /* Get mbstate_t, mbrtowc(), wcwidth(). */ 28 | #if HAVE_WCHAR_H 29 | # include 30 | #endif 31 | 32 | /* Get iswprint(), iswspace(). */ 33 | #if HAVE_WCTYPE_H 34 | # include 35 | #endif 36 | #if !defined iswprint && !HAVE_ISWPRINT 37 | # define iswprint(wc) 1 38 | #endif 39 | #if !defined iswspace && !HAVE_ISWSPACE 40 | # define iswspace(wc) \ 41 | ((wc) == (unsigned char) (wc) && ISSPACE ((unsigned char) (wc))) 42 | #endif 43 | 44 | /* Include this after wctype.h so that we `#undef' ISPRINT 45 | (from Solaris's euc.h, from widec.h, from wctype.h) before 46 | redefining and using it. */ 47 | #include "system.h" 48 | 49 | #include "closeout.h" 50 | #include "error.h" 51 | #include "inttostr.h" 52 | #include "safe-read.h" 53 | 54 | /* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 55 | #if HAVE_MBRTOWC && defined mbstate_t 56 | # define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 57 | #endif 58 | 59 | #ifndef HAVE_DECL_WCWIDTH 60 | "this configure-time declaration test was not run" 61 | #endif 62 | #if !HAVE_DECL_WCWIDTH 63 | extern int wcwidth (); 64 | #endif 65 | 66 | /* If wcwidth() doesn't exist, assume all printable characters have 67 | width 1. */ 68 | #if !defined wcwidth && !HAVE_WCWIDTH 69 | # define wcwidth(wc) ((wc) == 0 ? 0 : iswprint (wc) ? 1 : -1) 70 | #endif 71 | 72 | /* The official name of this program (e.g., no `g' prefix). */ 73 | #define PROGRAM_NAME "wc" 74 | 75 | #define AUTHORS N_ ("Paul Rubin and David MacKenzie") 76 | 77 | /* Size of atomic reads. */ 78 | #define BUFFER_SIZE (16 * 1024) 79 | 80 | /* The name this program was run with. */ 81 | char *program_name; 82 | 83 | /* Cumulative number of lines, words, chars and bytes in all files so far. 84 | max_line_length is the maximum over all files processed so far. */ 85 | static uintmax_t total_lines; 86 | static uintmax_t total_words; 87 | static uintmax_t total_chars; 88 | static uintmax_t total_bytes; 89 | static uintmax_t max_line_length; 90 | 91 | /* Which counts to print. */ 92 | static int print_lines, print_words, print_chars, print_bytes; 93 | static int print_linelength; 94 | 95 | /* Nonzero if we have ever read the standard input. */ 96 | static int have_read_stdin; 97 | 98 | /* The error code to return to the system. */ 99 | static int exit_status; 100 | 101 | /* If nonzero, do not line up columns but instead separate numbers by 102 | a single space as specified in Single Unix Specification and POSIX. */ 103 | static int posixly_correct; 104 | 105 | static struct option const longopts[] = 106 | { 107 | {"bytes", no_argument, NULL, 'c'}, 108 | {"chars", no_argument, NULL, 'm'}, 109 | {"lines", no_argument, NULL, 'l'}, 110 | {"words", no_argument, NULL, 'w'}, 111 | {"max-line-length", no_argument, NULL, 'L'}, 112 | {GETOPT_HELP_OPTION_DECL}, 113 | {GETOPT_VERSION_OPTION_DECL}, 114 | {NULL, 0, NULL, 0} 115 | }; 116 | 117 | void 118 | usage (int status) 119 | { 120 | if (status != 0) 121 | fprintf (stderr, _("Try `%s --help' for more information.\n"), 122 | program_name); 123 | else 124 | { 125 | printf (_("\ 126 | Usage: %s [OPTION]... [FILE]...\n\ 127 | "), 128 | program_name); 129 | fputs (_("\ 130 | Print byte, word, and newline counts for each FILE, and a total line if\n\ 131 | more than one FILE is specified. With no FILE, or when FILE is -,\n\ 132 | read standard input.\n\ 133 | -c, --bytes print the byte counts\n\ 134 | -m, --chars print the character counts\n\ 135 | -l, --lines print the newline counts\n\ 136 | "), stdout); 137 | fputs (_("\ 138 | -L, --max-line-length print the length of the longest line\n\ 139 | -w, --words print the word counts\n\ 140 | "), stdout); 141 | fputs (HELP_OPTION_DESCRIPTION, stdout); 142 | fputs (VERSION_OPTION_DESCRIPTION, stdout); 143 | printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT); 144 | } 145 | exit (status == 0 ? EXIT_SUCCESS : EXIT_FAILURE); 146 | } 147 | 148 | static void 149 | write_counts (uintmax_t lines, 150 | uintmax_t words, 151 | uintmax_t chars, 152 | uintmax_t bytes, 153 | uintmax_t linelength, 154 | const char *file) 155 | { 156 | char buf[INT_BUFSIZE_BOUND (uintmax_t)]; 157 | char const *space = ""; 158 | char const *format_int = (posixly_correct ? "%s" : "%7s"); 159 | char const *format_sp_int = (posixly_correct ? "%s%s" : "%s%7s"); 160 | 161 | if (print_lines) 162 | { 163 | printf (format_int, umaxtostr (lines, buf)); 164 | space = " "; 165 | } 166 | if (print_words) 167 | { 168 | printf (format_sp_int, space, umaxtostr (words, buf)); 169 | space = " "; 170 | } 171 | if (print_chars) 172 | { 173 | printf (format_sp_int, space, umaxtostr (chars, buf)); 174 | space = " "; 175 | } 176 | if (print_bytes) 177 | { 178 | printf (format_sp_int, space, umaxtostr (bytes, buf)); 179 | space = " "; 180 | } 181 | if (print_linelength) 182 | { 183 | printf (format_sp_int, space, umaxtostr (linelength, buf)); 184 | } 185 | if (*file) 186 | printf (" %s", file); 187 | putchar ('\n'); 188 | } 189 | 190 | static void 191 | wc (int fd, const char *file) 192 | { 193 | char buf[BUFFER_SIZE + 1]; 194 | size_t bytes_read; 195 | uintmax_t lines, words, chars, bytes, linelength; 196 | int count_bytes, count_chars, count_complicated; 197 | 198 | lines = words = chars = bytes = linelength = 0; 199 | 200 | /* If in the current locale, chars are equivalent to bytes, we prefer 201 | counting bytes, because that's easier. */ 202 | #if HAVE_MBRTOWC && (MB_LEN_MAX > 1) 203 | if (MB_CUR_MAX > 1) 204 | { 205 | count_bytes = print_bytes; 206 | count_chars = print_chars; 207 | } 208 | else 209 | #endif 210 | { 211 | count_bytes = print_bytes + print_chars; 212 | count_chars = 0; 213 | } 214 | count_complicated = print_words + print_linelength; 215 | 216 | /* We need binary input, since `wc' relies on `lseek' and byte counts. */ 217 | SET_BINARY (fd); 218 | 219 | /* When counting only bytes, save some line- and word-counting 220 | overhead. If FD is a `regular' Unix file, using lseek is enough 221 | to get its `size' in bytes. Otherwise, read blocks of BUFFER_SIZE 222 | bytes at a time until EOF. Note that the `size' (number of bytes) 223 | that wc reports is smaller than stats.st_size when the file is not 224 | positioned at its beginning. That's why the lseek calls below are 225 | necessary. For example the command 226 | `(dd ibs=99k skip=1 count=0; ./wc -c) < /etc/group' 227 | should make wc report `0' bytes. */ 228 | 229 | if (count_bytes && !count_chars && !print_lines && !count_complicated) 230 | { 231 | off_t current_pos, end_pos; 232 | struct stat stats; 233 | 234 | if (fstat (fd, &stats) == 0 && S_ISREG (stats.st_mode) 235 | && (current_pos = lseek (fd, (off_t) 0, SEEK_CUR)) != -1 236 | && (end_pos = lseek (fd, (off_t) 0, SEEK_END)) != -1) 237 | { 238 | off_t diff; 239 | /* Be careful here. The current position may actually be 240 | beyond the end of the file. As in the example above. */ 241 | bytes = (diff = end_pos - current_pos) < 0 ? 0 : diff; 242 | } 243 | else 244 | { 245 | while ((bytes_read = safe_read (fd, buf, BUFFER_SIZE)) > 0) 246 | { 247 | if (bytes_read == SAFE_READ_ERROR) 248 | { 249 | error (0, errno, "%s", file); 250 | exit_status = 1; 251 | break; 252 | } 253 | bytes += bytes_read; 254 | } 255 | } 256 | } 257 | else if (!count_chars && !count_complicated) 258 | { 259 | /* Use a separate loop when counting only lines or lines and bytes -- 260 | but not chars or words. */ 261 | while ((bytes_read = safe_read (fd, buf, BUFFER_SIZE)) > 0) 262 | { 263 | register char *p = buf; 264 | 265 | if (bytes_read == SAFE_READ_ERROR) 266 | { 267 | error (0, errno, "%s", file); 268 | exit_status = 1; 269 | break; 270 | } 271 | 272 | while ((p = memchr (p, '\n', (buf + bytes_read) - p))) 273 | { 274 | ++p; 275 | ++lines; 276 | } 277 | bytes += bytes_read; 278 | } 279 | } 280 | #if HAVE_MBRTOWC && (MB_LEN_MAX > 1) 281 | # define SUPPORT_OLD_MBRTOWC 1 282 | else if (MB_CUR_MAX > 1) 283 | { 284 | int in_word = 0; 285 | uintmax_t linepos = 0; 286 | mbstate_t state; 287 | uintmax_t last_error_line = 0; 288 | int last_error_errno = 0; 289 | # if SUPPORT_OLD_MBRTOWC 290 | /* Back-up the state before each multibyte character conversion and 291 | move the last incomplete character of the buffer to the front 292 | of the buffer. This is needed because we don't know whether 293 | the `mbrtowc' function updates the state when it returns -2, - 294 | this is the ISO C 99 and glibc-2.2 behaviour - or not - amended 295 | ANSI C, glibc-2.1 and Solaris 2.7 behaviour. We don't have an 296 | autoconf test for this, yet. */ 297 | size_t prev = 0; /* number of bytes carried over from previous round */ 298 | # else 299 | const size_t prev = 0; 300 | # endif 301 | 302 | memset (&state, 0, sizeof (mbstate_t)); 303 | while ((bytes_read = safe_read (fd, buf + prev, BUFFER_SIZE - prev)) > 0) 304 | { 305 | const char *p; 306 | # if SUPPORT_OLD_MBRTOWC 307 | mbstate_t backup_state; 308 | # endif 309 | if (bytes_read == SAFE_READ_ERROR) 310 | { 311 | error (0, errno, "%s", file); 312 | exit_status = 1; 313 | break; 314 | } 315 | 316 | bytes += bytes_read; 317 | p = buf; 318 | bytes_read += prev; 319 | do 320 | { 321 | wchar_t wide_char; 322 | size_t n; 323 | 324 | # if SUPPORT_OLD_MBRTOWC 325 | backup_state = state; 326 | # endif 327 | n = mbrtowc (&wide_char, p, bytes_read, &state); 328 | if (n == (size_t) -2) 329 | { 330 | # if SUPPORT_OLD_MBRTOWC 331 | state = backup_state; 332 | # endif 333 | break; 334 | } 335 | if (n == (size_t) -1) 336 | { 337 | /* Signal repeated errors only once per line. */ 338 | if (!(lines + 1 == last_error_line 339 | && errno == last_error_errno)) 340 | { 341 | char line_number_buf[INT_BUFSIZE_BOUND (uintmax_t)]; 342 | last_error_line = lines + 1; 343 | last_error_errno = errno; 344 | error (0, errno, "%s:%s", file, 345 | umaxtostr (last_error_line, line_number_buf)); 346 | } 347 | p++; 348 | bytes_read--; 349 | } 350 | else 351 | { 352 | if (n == 0) 353 | { 354 | wide_char = 0; 355 | n = 1; 356 | } 357 | p += n; 358 | bytes_read -= n; 359 | chars++; 360 | switch (wide_char) 361 | { 362 | case '\n': 363 | lines++; 364 | /* Fall through. */ 365 | case '\r': 366 | case '\f': 367 | if (linepos > linelength) 368 | linelength = linepos; 369 | linepos = 0; 370 | goto mb_word_separator; 371 | case '\t': 372 | linepos += 8 - (linepos % 8); 373 | goto mb_word_separator; 374 | case ' ': 375 | linepos++; 376 | /* Fall through. */ 377 | case '\v': 378 | mb_word_separator: 379 | if (in_word) 380 | { 381 | in_word = 0; 382 | words++; 383 | } 384 | break; 385 | default: 386 | if (iswprint (wide_char)) 387 | { 388 | int width = wcwidth (wide_char); 389 | if (width > 0) 390 | linepos += width; 391 | if (iswspace (wide_char)) 392 | goto mb_word_separator; 393 | in_word = 1; 394 | } 395 | break; 396 | } 397 | } 398 | } 399 | while (bytes_read > 0); 400 | 401 | # if SUPPORT_OLD_MBRTOWC 402 | if (bytes_read > 0) 403 | { 404 | if (bytes_read == BUFFER_SIZE) 405 | { 406 | /* Encountered a very long redundant shift sequence. */ 407 | p++; 408 | bytes_read--; 409 | } 410 | memmove (buf, p, bytes_read); 411 | } 412 | prev = bytes_read; 413 | # endif 414 | } 415 | if (linepos > linelength) 416 | linelength = linepos; 417 | if (in_word) 418 | words++; 419 | } 420 | #endif 421 | else 422 | { 423 | int in_word = 0; 424 | uintmax_t linepos = 0; 425 | 426 | while ((bytes_read = safe_read (fd, buf, BUFFER_SIZE)) > 0) 427 | { 428 | const char *p = buf; 429 | if (bytes_read == SAFE_READ_ERROR) 430 | { 431 | error (0, errno, "%s", file); 432 | exit_status = 1; 433 | break; 434 | } 435 | 436 | bytes += bytes_read; 437 | do 438 | { 439 | switch (*p++) 440 | { 441 | case '\n': 442 | lines++; 443 | /* Fall through. */ 444 | case '\r': 445 | case '\f': 446 | if (linepos > linelength) 447 | linelength = linepos; 448 | linepos = 0; 449 | goto word_separator; 450 | case '\t': 451 | linepos += 8 - (linepos % 8); 452 | goto word_separator; 453 | case ' ': 454 | linepos++; 455 | /* Fall through. */ 456 | case '\v': 457 | word_separator: 458 | if (in_word) 459 | { 460 | in_word = 0; 461 | words++; 462 | } 463 | break; 464 | default: 465 | if (ISPRINT ((unsigned char) p[-1])) 466 | { 467 | linepos++; 468 | if (ISSPACE ((unsigned char) p[-1])) 469 | goto word_separator; 470 | in_word = 1; 471 | } 472 | break; 473 | } 474 | } 475 | while (--bytes_read); 476 | } 477 | if (linepos > linelength) 478 | linelength = linepos; 479 | if (in_word) 480 | words++; 481 | } 482 | 483 | if (count_chars < print_chars) 484 | chars = bytes; 485 | 486 | write_counts (lines, words, chars, bytes, linelength, file); 487 | total_lines += lines; 488 | total_words += words; 489 | total_chars += chars; 490 | total_bytes += bytes; 491 | if (linelength > max_line_length) 492 | max_line_length = linelength; 493 | } 494 | 495 | static void 496 | wc_file (const char *file) 497 | { 498 | if (STREQ (file, "-")) 499 | { 500 | have_read_stdin = 1; 501 | wc (0, file); 502 | } 503 | else 504 | { 505 | int fd = open (file, O_RDONLY); 506 | if (fd == -1) 507 | { 508 | error (0, errno, "%s", file); 509 | exit_status = 1; 510 | return; 511 | } 512 | wc (fd, file); 513 | if (close (fd)) 514 | { 515 | error (0, errno, "%s", file); 516 | exit_status = 1; 517 | } 518 | } 519 | } 520 | 521 | int 522 | main (int argc, char **argv) 523 | { 524 | int optc; 525 | int nfiles; 526 | 527 | program_name = argv[0]; 528 | setlocale (LC_ALL, ""); 529 | bindtextdomain (PACKAGE, LOCALEDIR); 530 | textdomain (PACKAGE); 531 | 532 | atexit (close_stdout); 533 | 534 | exit_status = 0; 535 | posixly_correct = (getenv ("POSIXLY_CORRECT") != NULL); 536 | print_lines = print_words = print_chars = print_bytes = print_linelength = 0; 537 | total_lines = total_words = total_chars = total_bytes = max_line_length = 0; 538 | 539 | while ((optc = getopt_long (argc, argv, "clLmw", longopts, NULL)) != -1) 540 | switch (optc) 541 | { 542 | case 0: 543 | break; 544 | 545 | case 'c': 546 | print_bytes = 1; 547 | break; 548 | 549 | case 'm': 550 | print_chars = 1; 551 | break; 552 | 553 | case 'l': 554 | print_lines = 1; 555 | break; 556 | 557 | case 'w': 558 | print_words = 1; 559 | break; 560 | 561 | case 'L': 562 | print_linelength = 1; 563 | break; 564 | 565 | case_GETOPT_HELP_CHAR; 566 | 567 | case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); 568 | 569 | default: 570 | usage (EXIT_FAILURE); 571 | } 572 | 573 | if (print_lines + print_words + print_chars + print_bytes + print_linelength 574 | == 0) 575 | print_lines = print_words = print_bytes = 1; 576 | 577 | nfiles = argc - optind; 578 | 579 | if (nfiles == 0) 580 | { 581 | have_read_stdin = 1; 582 | wc (0, ""); 583 | } 584 | else 585 | { 586 | for (; optind < argc; ++optind) 587 | wc_file (argv[optind]); 588 | 589 | if (nfiles > 1) 590 | write_counts (total_lines, total_words, total_chars, total_bytes, 591 | max_line_length, _("total")); 592 | } 593 | 594 | if (have_read_stdin && close (STDIN_FILENO) != 0) 595 | error (EXIT_FAILURE, errno, "-"); 596 | 597 | exit (exit_status == 0 ? EXIT_SUCCESS : EXIT_FAILURE); 598 | } 599 | -------------------------------------------------------------------------------- /gnu/gawk-3.1.3/posix/gawkmisc.c: -------------------------------------------------------------------------------- 1 | /* gawkmisc.c --- miscellaneous gawk routines that are OS specific. 2 | 3 | Copyright (C) 1986, 1988, 1989, 1991 - 1998, 2001 - 2003 the Free Software Foundation, Inc. 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 2, or (at your option) 8 | any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program; if not, write to the Free Software Foundation, 17 | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 18 | 19 | char quote = '\''; 20 | char *defpath = DEFPATH; 21 | char envsep = ':'; 22 | 23 | #ifndef INVALID_HANDLE 24 | /* FIXME: is this value for INVALID_HANDLE correct? */ 25 | #define INVALID_HANDLE -1 26 | #endif 27 | 28 | /* gawk_name --- pull out the "gawk" part from how the OS called us */ 29 | 30 | char * 31 | gawk_name(filespec) 32 | const char *filespec; 33 | { 34 | char *p; 35 | 36 | /* "path/name" -> "name" */ 37 | p = strrchr(filespec, '/'); 38 | return (p == NULL ? (char *) filespec : p + 1); 39 | } 40 | 41 | /* os_arg_fixup --- fixup the command line */ 42 | 43 | void 44 | os_arg_fixup(argcp, argvp) 45 | int *argcp; 46 | char ***argvp; 47 | { 48 | /* no-op */ 49 | return; 50 | } 51 | 52 | /* os_devopen --- open special per-OS devices */ 53 | 54 | int 55 | os_devopen(name, flag) 56 | const char *name; 57 | int flag; 58 | { 59 | /* no-op */ 60 | return INVALID_HANDLE; 61 | } 62 | 63 | /* optimal_bufsize --- determine optimal buffer size */ 64 | 65 | /* 66 | * Enhance this for debugging purposes, as follows: 67 | * 68 | * Always stat the file, stat buffer is used by higher-level code. 69 | * 70 | * if (AWKBUFSIZE == "exact") 71 | * return the file size 72 | * else if (AWKBUFSIZE == a number) 73 | * always return that number 74 | * else 75 | * if the size is < default_blocksize 76 | * return the size 77 | * else 78 | * return default_blocksize 79 | * end if 80 | * endif 81 | * 82 | * Hair comes in an effort to only deal with AWKBUFSIZE 83 | * once, the first time this routine is called, instead of 84 | * every time. Performance, dontyaknow. 85 | */ 86 | 87 | size_t 88 | optimal_bufsize(fd, stb) 89 | int fd; 90 | struct stat *stb; 91 | { 92 | char *val; 93 | static size_t env_val = 0; 94 | static short first = TRUE; 95 | static short exact = FALSE; 96 | 97 | /* force all members to zero in case OS doesn't use all of them. */ 98 | memset(stb, '\0', sizeof(struct stat)); 99 | 100 | /* always stat, in case stb is used by higher level code. */ 101 | if (fstat(fd, stb) == -1) 102 | fatal("can't stat fd %d (%s)", fd, strerror(errno)); 103 | 104 | if (first) { 105 | first = FALSE; 106 | 107 | if ((val = getenv("AWKBUFSIZE")) != NULL) { 108 | if (strcmp(val, "exact") == 0) 109 | exact = TRUE; 110 | else if (ISDIGIT(*val)) { 111 | for (; *val && ISDIGIT(*val); val++) 112 | env_val = (env_val * 10) + *val - '0'; 113 | 114 | return env_val; 115 | } 116 | } 117 | } else if (! exact && env_val > 0) 118 | return env_val; 119 | /* else 120 | fall through */ 121 | 122 | /* 123 | * System V.n, n < 4, doesn't have the file system block size in the 124 | * stat structure. So we have to make some sort of reasonable 125 | * guess. We use stdio's BUFSIZ, since that is what it was 126 | * meant for in the first place. 127 | */ 128 | #ifdef HAVE_ST_BLKSIZE 129 | #define DEFBLKSIZE (stb->st_blksize > 0 ? stb->st_blksize : BUFSIZ) 130 | #else 131 | #define DEFBLKSIZE BUFSIZ 132 | #endif 133 | 134 | if (S_ISREG(stb->st_mode) /* regular file */ 135 | && 0 < stb->st_size /* non-zero size */ 136 | && (stb->st_size < DEFBLKSIZE /* small file */ 137 | || exact)) /* or debugging */ 138 | return stb->st_size; /* use file size */ 139 | 140 | return DEFBLKSIZE; 141 | } 142 | 143 | /* ispath --- return true if path has directory components */ 144 | 145 | int 146 | ispath(file) 147 | const char *file; 148 | { 149 | return (strchr(file, '/') != NULL); 150 | } 151 | 152 | /* isdirpunct --- return true if char is a directory separator */ 153 | 154 | int 155 | isdirpunct(c) 156 | int c; 157 | { 158 | return (c == '/'); 159 | } 160 | 161 | /* os_close_on_exec --- set close on exec flag, print warning if fails */ 162 | 163 | void 164 | os_close_on_exec(fd, name, what, dir) 165 | int fd; 166 | const char *name, *what, *dir; 167 | { 168 | if (fd <= 2) /* sanity */ 169 | return; 170 | 171 | if (fcntl(fd, F_SETFD, 1) < 0) 172 | warning(_("%s %s `%s': could not set close-on-exec: (fcntl: %s)"), 173 | what, dir, name, strerror(errno)); 174 | } 175 | 176 | /* os_isdir --- is this an fd on a directory? */ 177 | 178 | #if ! defined(S_ISDIR) && defined(S_IFDIR) 179 | #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) 180 | #endif 181 | 182 | int 183 | os_isdir(fd) 184 | int fd; 185 | { 186 | struct stat sbuf; 187 | 188 | return (fstat(fd, &sbuf) == 0 && S_ISDIR(sbuf.st_mode)); 189 | } 190 | 191 | /* os_is_setuid --- true if running setuid root */ 192 | 193 | int 194 | os_is_setuid() 195 | { 196 | long uid, euid; 197 | 198 | uid = getuid(); 199 | euid = geteuid(); 200 | 201 | return (euid == 0 && euid != uid); 202 | } 203 | 204 | /* os_setbinmode --- set binary mode on file */ 205 | 206 | int 207 | os_setbinmode (fd, mode) 208 | int fd, mode; 209 | { 210 | return 0; 211 | } 212 | 213 | /* os_restore_mode --- restore the original mode of the console device */ 214 | 215 | void 216 | os_restore_mode (fd) 217 | int fd; 218 | { 219 | /* no-op */ 220 | return; 221 | } 222 | 223 | #ifdef __CYGWIN__ 224 | #include 225 | 226 | extern int _fmode; 227 | void 228 | cygwin_premain0 (int argc, char **argv, struct per_process *myself) 229 | { 230 | static struct __cygwin_perfile pf[] = 231 | { 232 | {"", O_RDONLY | O_TEXT}, 233 | /*{"", O_WRONLY | O_BINARY},*/ 234 | {NULL, 0} 235 | }; 236 | cygwin_internal (CW_PERFILE, pf); 237 | } 238 | #endif 239 | -------------------------------------------------------------------------------- /gnu/gawk-3.1.4/README: -------------------------------------------------------------------------------- 1 | Tue Feb 3 15:21:03 IST 2004 2 | ============================ 3 | 4 | This file is a development snapshot, it is not the final version of builtin.c 5 | from the gawk 3.1.4 release. It does contain the code quoted in the book. 6 | 7 | You may wish to retrieve the final gawk 3.1.4 distribution from the Free 8 | Software Foundation's web site. 9 | -------------------------------------------------------------------------------- /gnu/getopt/getopt.h: -------------------------------------------------------------------------------- 1 | /* Declarations for getopt. 2 | Copyright (C) 1989-1994, 1996-1999, 2001 Free Software Foundation, Inc. 3 | This file is part of the GNU C Library. 4 | 5 | The GNU C Library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | The GNU C Library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with the GNU C Library; if not, write to the Free 17 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 18 | 02111-1307 USA. */ 19 | 20 | #ifndef _GETOPT_H 21 | 22 | #ifndef __need_getopt 23 | # define _GETOPT_H 1 24 | #endif 25 | 26 | /* If __GNU_LIBRARY__ is not already defined, either we are being used 27 | standalone, or this is the first header included in the source file. 28 | If we are being used with glibc, we need to include , but 29 | that does not exist if we are standalone. So: if __GNU_LIBRARY__ is 30 | not defined, include , which will pull in for us 31 | if it's from glibc. (Why ctype.h? It's guaranteed to exist and it 32 | doesn't flood the namespace with stuff the way some other headers do.) */ 33 | #if !defined __GNU_LIBRARY__ 34 | # include 35 | #endif 36 | 37 | #ifdef __cplusplus 38 | extern "C" { 39 | #endif 40 | 41 | /* For communication from `getopt' to the caller. 42 | When `getopt' finds an option that takes an argument, 43 | the argument value is returned here. 44 | Also, when `ordering' is RETURN_IN_ORDER, 45 | each non-option ARGV-element is returned here. */ 46 | 47 | extern char *optarg; 48 | 49 | /* Index in ARGV of the next element to be scanned. 50 | This is used for communication to and from the caller 51 | and for communication between successive calls to `getopt'. 52 | 53 | On entry to `getopt', zero means this is the first call; initialize. 54 | 55 | When `getopt' returns -1, this is the index of the first of the 56 | non-option elements that the caller should itself scan. 57 | 58 | Otherwise, `optind' communicates from one call to the next 59 | how much of ARGV has been scanned so far. */ 60 | 61 | extern int optind; 62 | 63 | /* Callers store zero here to inhibit the error message `getopt' prints 64 | for unrecognized options. */ 65 | 66 | extern int opterr; 67 | 68 | /* Set to an option character which was unrecognized. */ 69 | 70 | extern int optopt; 71 | 72 | #ifndef __need_getopt 73 | /* Describe the long-named options requested by the application. 74 | The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector 75 | of `struct option' terminated by an element containing a name which is 76 | zero. 77 | 78 | The field `has_arg' is: 79 | no_argument (or 0) if the option does not take an argument, 80 | required_argument (or 1) if the option requires an argument, 81 | optional_argument (or 2) if the option takes an optional argument. 82 | 83 | If the field `flag' is not NULL, it points to a variable that is set 84 | to the value given in the field `val' when the option is found, but 85 | left unchanged if the option is not found. 86 | 87 | To have a long-named option do something other than set an `int' to 88 | a compiled-in constant, such as set a value from `optarg', set the 89 | option's `flag' field to zero and its `val' field to a nonzero 90 | value (the equivalent single-letter option character, if there is 91 | one). For long options that have a zero `flag' field, `getopt' 92 | returns the contents of the `val' field. */ 93 | 94 | struct option 95 | { 96 | # if (defined __STDC__ && __STDC__) || defined __cplusplus 97 | const char *name; 98 | # else 99 | char *name; 100 | # endif 101 | /* has_arg can't be an enum because some compilers complain about 102 | type mismatches in all the code that assumes it is an int. */ 103 | int has_arg; 104 | int *flag; 105 | int val; 106 | }; 107 | 108 | /* Names for the values of the `has_arg' field of `struct option'. */ 109 | 110 | # define no_argument 0 111 | # define required_argument 1 112 | # define optional_argument 2 113 | #endif /* need getopt */ 114 | 115 | 116 | /* Get definitions and prototypes for functions to process the 117 | arguments in ARGV (ARGC of them, minus the program name) for 118 | options given in OPTS. 119 | 120 | Return the option character from OPTS just read. Return -1 when 121 | there are no more options. For unrecognized options, or options 122 | missing arguments, `optopt' is set to the option letter, and '?' is 123 | returned. 124 | 125 | The OPTS string is a list of characters which are recognized option 126 | letters, optionally followed by colons, specifying that that letter 127 | takes an argument, to be placed in `optarg'. 128 | 129 | If a letter in OPTS is followed by two colons, its argument is 130 | optional. This behavior is specific to the GNU `getopt'. 131 | 132 | The argument `--' causes premature termination of argument 133 | scanning, explicitly telling `getopt' that there are no more 134 | options. 135 | 136 | If OPTS begins with `--', then non-option arguments are treated as 137 | arguments to the option '\0'. This behavior is specific to the GNU 138 | `getopt'. */ 139 | 140 | #if (defined __STDC__ && __STDC__) || defined __cplusplus 141 | # ifdef __GNU_LIBRARY__ 142 | /* Many other libraries have conflicting prototypes for getopt, with 143 | differences in the consts, in stdlib.h. To avoid compilation 144 | errors, only prototype getopt for the GNU C library. */ 145 | extern int getopt (int ___argc, char *const *___argv, const char *__shortopts); 146 | # else /* not __GNU_LIBRARY__ */ 147 | extern int getopt (); 148 | # endif /* __GNU_LIBRARY__ */ 149 | 150 | # ifndef __need_getopt 151 | extern int getopt_long (int ___argc, char *const *___argv, 152 | const char *__shortopts, 153 | const struct option *__longopts, int *__longind); 154 | extern int getopt_long_only (int ___argc, char *const *___argv, 155 | const char *__shortopts, 156 | const struct option *__longopts, int *__longind); 157 | 158 | /* Internal only. Users should not call this directly. */ 159 | extern int _getopt_internal (int ___argc, char *const *___argv, 160 | const char *__shortopts, 161 | const struct option *__longopts, int *__longind, 162 | int __long_only); 163 | # endif 164 | #else /* not __STDC__ */ 165 | extern int getopt (); 166 | # ifndef __need_getopt 167 | extern int getopt_long (); 168 | extern int getopt_long_only (); 169 | 170 | extern int _getopt_internal (); 171 | # endif 172 | #endif /* __STDC__ */ 173 | 174 | #ifdef __cplusplus 175 | } 176 | #endif 177 | 178 | /* Make sure we later can get all the definitions and declarations. */ 179 | #undef __need_getopt 180 | 181 | #endif /* getopt.h */ 182 | -------------------------------------------------------------------------------- /gnu/getopt/getopt1.c: -------------------------------------------------------------------------------- 1 | /* getopt_long and getopt_long_only entry points for GNU getopt. 2 | Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98 3 | Free Software Foundation, Inc. 4 | This file is part of the GNU C Library. 5 | 6 | The GNU C Library is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU Lesser General Public 8 | License as published by the Free Software Foundation; either 9 | version 2.1 of the License, or (at your option) any later version. 10 | 11 | The GNU C Library is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with the GNU C Library; if not, write to the Free 18 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 19 | 02111-1307 USA. */ 20 | 21 | #ifdef HAVE_CONFIG_H 22 | #include 23 | #endif 24 | 25 | #include "getopt.h" 26 | 27 | #if !defined __STDC__ || !__STDC__ 28 | /* This is a separate conditional since some stdc systems 29 | reject `defined (const)'. */ 30 | #ifndef const 31 | #define const 32 | #endif 33 | #endif 34 | 35 | #include 36 | 37 | /* Comment out all this code if we are using the GNU C Library, and are not 38 | actually compiling the library itself. This code is part of the GNU C 39 | Library, but also included in many other GNU distributions. Compiling 40 | and linking in this code is a waste when using the GNU C library 41 | (especially if it is a shared library). Rather than having every GNU 42 | program understand `configure --with-gnu-libc' and omit the object files, 43 | it is simpler to just do this in the source for each such file. */ 44 | 45 | #define GETOPT_INTERFACE_VERSION 2 46 | #if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 47 | #include 48 | #if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION 49 | #define ELIDE_CODE 50 | #endif 51 | #endif 52 | 53 | #ifndef ELIDE_CODE 54 | 55 | 56 | /* This needs to come after some library #include 57 | to get __GNU_LIBRARY__ defined. */ 58 | #ifdef __GNU_LIBRARY__ 59 | #include 60 | #endif 61 | 62 | #ifndef NULL 63 | #define NULL 0 64 | #endif 65 | 66 | int 67 | getopt_long (argc, argv, options, long_options, opt_index) 68 | int argc; 69 | char *const *argv; 70 | const char *options; 71 | const struct option *long_options; 72 | int *opt_index; 73 | { 74 | return _getopt_internal (argc, argv, options, long_options, opt_index, 0); 75 | } 76 | 77 | /* Like getopt_long, but '-' as well as '--' can indicate a long option. 78 | If an option that starts with '-' (not '--') doesn't match a long option, 79 | but does match a short option, it is parsed as a short option 80 | instead. */ 81 | 82 | int 83 | getopt_long_only (argc, argv, options, long_options, opt_index) 84 | int argc; 85 | char *const *argv; 86 | const char *options; 87 | const struct option *long_options; 88 | int *opt_index; 89 | { 90 | return _getopt_internal (argc, argv, options, long_options, opt_index, 1); 91 | } 92 | 93 | 94 | #endif /* Not ELIDE_CODE. */ 95 | 96 | #ifdef TEST 97 | 98 | #include 99 | 100 | int 101 | main (argc, argv) 102 | int argc; 103 | char **argv; 104 | { 105 | int c; 106 | int digit_optind = 0; 107 | 108 | while (1) 109 | { 110 | int this_option_optind = optind ? optind : 1; 111 | int option_index = 0; 112 | static struct option long_options[] = 113 | { 114 | {"add", 1, 0, 0}, 115 | {"append", 0, 0, 0}, 116 | {"delete", 1, 0, 0}, 117 | {"verbose", 0, 0, 0}, 118 | {"create", 0, 0, 0}, 119 | {"file", 1, 0, 0}, 120 | {0, 0, 0, 0} 121 | }; 122 | 123 | c = getopt_long (argc, argv, "abc:d:0123456789", 124 | long_options, &option_index); 125 | if (c == -1) 126 | break; 127 | 128 | switch (c) 129 | { 130 | case 0: 131 | printf ("option %s", long_options[option_index].name); 132 | if (optarg) 133 | printf (" with arg %s", optarg); 134 | printf ("\n"); 135 | break; 136 | 137 | case '0': 138 | case '1': 139 | case '2': 140 | case '3': 141 | case '4': 142 | case '5': 143 | case '6': 144 | case '7': 145 | case '8': 146 | case '9': 147 | if (digit_optind != 0 && digit_optind != this_option_optind) 148 | printf ("digits occur in two different argv-elements.\n"); 149 | digit_optind = this_option_optind; 150 | printf ("option %c\n", c); 151 | break; 152 | 153 | case 'a': 154 | printf ("option a\n"); 155 | break; 156 | 157 | case 'b': 158 | printf ("option b\n"); 159 | break; 160 | 161 | case 'c': 162 | printf ("option c with value `%s'\n", optarg); 163 | break; 164 | 165 | case 'd': 166 | printf ("option d with value `%s'\n", optarg); 167 | break; 168 | 169 | case '?': 170 | break; 171 | 172 | default: 173 | printf ("?? getopt returned character code 0%o ??\n", c); 174 | } 175 | } 176 | 177 | if (optind < argc) 178 | { 179 | printf ("non-option ARGV-elements: "); 180 | while (optind < argc) 181 | printf ("%s ", argv[optind++]); 182 | printf ("\n"); 183 | } 184 | 185 | exit (0); 186 | } 187 | 188 | #endif /* TEST */ 189 | -------------------------------------------------------------------------------- /gnu/glibc-2.3.2/locale/locale.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 1991,92,95-99,2000,01,02 Free Software Foundation, Inc. 2 | This file is part of the GNU C Library. 3 | 4 | The GNU C Library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | The GNU C Library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with the GNU C Library; if not, write to the Free 16 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 17 | 02111-1307 USA. */ 18 | 19 | /* 20 | * ISO C99 Standard: 7.11 Localization 21 | */ 22 | 23 | #ifndef _LOCALE_H 24 | #define _LOCALE_H 1 25 | 26 | #include 27 | 28 | #define __need_NULL 29 | #include 30 | #include 31 | 32 | __BEGIN_DECLS 33 | 34 | /* These are the possibilities for the first argument to setlocale. 35 | The code assumes that the lowest LC_* symbol has the value zero. */ 36 | #define LC_CTYPE __LC_CTYPE 37 | #define LC_NUMERIC __LC_NUMERIC 38 | #define LC_TIME __LC_TIME 39 | #define LC_COLLATE __LC_COLLATE 40 | #define LC_MONETARY __LC_MONETARY 41 | #define LC_MESSAGES __LC_MESSAGES 42 | #define LC_ALL __LC_ALL 43 | #define LC_PAPER __LC_PAPER 44 | #define LC_NAME __LC_NAME 45 | #define LC_ADDRESS __LC_ADDRESS 46 | #define LC_TELEPHONE __LC_TELEPHONE 47 | #define LC_MEASUREMENT __LC_MEASUREMENT 48 | #define LC_IDENTIFICATION __LC_IDENTIFICATION 49 | 50 | 51 | /* Structure giving information about numeric and monetary notation. */ 52 | struct lconv 53 | { 54 | /* Numeric (non-monetary) information. */ 55 | 56 | char *decimal_point; /* Decimal point character. */ 57 | char *thousands_sep; /* Thousands separator. */ 58 | /* Each element is the number of digits in each group; 59 | elements with higher indices are farther left. 60 | An element with value CHAR_MAX means that no further grouping is done. 61 | An element with value 0 means that the previous element is used 62 | for all groups farther left. */ 63 | char *grouping; 64 | 65 | /* Monetary information. */ 66 | 67 | /* First three chars are a currency symbol from ISO 4217. 68 | Fourth char is the separator. Fifth char is '\0'. */ 69 | char *int_curr_symbol; 70 | char *currency_symbol; /* Local currency symbol. */ 71 | char *mon_decimal_point; /* Decimal point character. */ 72 | char *mon_thousands_sep; /* Thousands separator. */ 73 | char *mon_grouping; /* Like `grouping' element (above). */ 74 | char *positive_sign; /* Sign for positive values. */ 75 | char *negative_sign; /* Sign for negative values. */ 76 | char int_frac_digits; /* Int'l fractional digits. */ 77 | char frac_digits; /* Local fractional digits. */ 78 | /* 1 if currency_symbol precedes a positive value, 0 if succeeds. */ 79 | char p_cs_precedes; 80 | /* 1 iff a space separates currency_symbol from a positive value. */ 81 | char p_sep_by_space; 82 | /* 1 if currency_symbol precedes a negative value, 0 if succeeds. */ 83 | char n_cs_precedes; 84 | /* 1 iff a space separates currency_symbol from a negative value. */ 85 | char n_sep_by_space; 86 | /* Positive and negative sign positions: 87 | 0 Parentheses surround the quantity and currency_symbol. 88 | 1 The sign string precedes the quantity and currency_symbol. 89 | 2 The sign string follows the quantity and currency_symbol. 90 | 3 The sign string immediately precedes the currency_symbol. 91 | 4 The sign string immediately follows the currency_symbol. */ 92 | char p_sign_posn; 93 | char n_sign_posn; 94 | #ifdef __USE_ISOC99 95 | /* 1 if int_curr_symbol precedes a positive value, 0 if succeeds. */ 96 | char int_p_cs_precedes; 97 | /* 1 iff a space separates int_curr_symbol from a positive value. */ 98 | char int_p_sep_by_space; 99 | /* 1 if int_curr_symbol precedes a negative value, 0 if succeeds. */ 100 | char int_n_cs_precedes; 101 | /* 1 iff a space separates int_curr_symbol from a negative value. */ 102 | char int_n_sep_by_space; 103 | /* Positive and negative sign positions: 104 | 0 Parentheses surround the quantity and int_curr_symbol. 105 | 1 The sign string precedes the quantity and int_curr_symbol. 106 | 2 The sign string follows the quantity and int_curr_symbol. 107 | 3 The sign string immediately precedes the int_curr_symbol. 108 | 4 The sign string immediately follows the int_curr_symbol. */ 109 | char int_p_sign_posn; 110 | char int_n_sign_posn; 111 | #else 112 | char __int_p_cs_precedes; 113 | char __int_p_sep_by_space; 114 | char __int_n_cs_precedes; 115 | char __int_n_sep_by_space; 116 | char __int_p_sign_posn; 117 | char __int_n_sign_posn; 118 | #endif 119 | }; 120 | 121 | 122 | __BEGIN_NAMESPACE_STD 123 | 124 | /* Set and/or return the current locale. */ 125 | extern char *setlocale (int __category, __const char *__locale) __THROW; 126 | 127 | /* Return the numeric/monetary information for the current locale. */ 128 | extern struct lconv *localeconv (void) __THROW; 129 | 130 | __END_NAMESPACE_STD 131 | 132 | 133 | #ifdef __USE_GNU 134 | /* The concept of one static locale per category is not very well 135 | thought out. Many applications will need to process its data using 136 | information from several different locales. Another application is 137 | the implementation of the internationalization handling in the 138 | upcoming ISO C++ standard library. To support this another set of 139 | the functions using locale data exist which have an additional 140 | argument. 141 | 142 | Attention: all these functions are *not* standardized in any form. 143 | This is a proof-of-concept implementation. */ 144 | 145 | /* Get locale datatype definition. */ 146 | # include 147 | 148 | typedef __locale_t locale_t; 149 | 150 | /* Return a reference to a data structure representing a set of locale 151 | datasets. Unlike for the CATEGORY parameter for `setlocale' the 152 | CATEGORY_MASK parameter here uses a single bit for each category, 153 | made by OR'ing together LC_*_MASK bits above. */ 154 | extern __locale_t newlocale (int __category_mask, __const char *__locale, 155 | __locale_t __base) __THROW; 156 | 157 | /* These are the bits that can be set in the CATEGORY_MASK argument to 158 | `newlocale'. In the GNU implementation, LC_FOO_MASK has the value 159 | of (1 << LC_FOO), but this is not a part of the interface that 160 | callers can assume will be true. */ 161 | # define LC_CTYPE_MASK (1 << __LC_CTYPE) 162 | # define LC_NUMERIC_MASK (1 << __LC_NUMERIC) 163 | # define LC_TIME_MASK (1 << __LC_TIME) 164 | # define LC_COLLATE_MASK (1 << __LC_COLLATE) 165 | # define LC_MONETARY_MASK (1 << __LC_MONETARY) 166 | # define LC_MESSAGES_MASK (1 << __LC_MESSAGES) 167 | # define LC_PAPER_MASK (1 << __LC_PAPER) 168 | # define LC_NAME_MASK (1 << __LC_NAME) 169 | # define LC_ADDRESS_MASK (1 << __LC_ADDRESS) 170 | # define LC_TELEPHONE_MASK (1 << __LC_TELEPHONE) 171 | # define LC_MEASUREMENT_MASK (1 << __LC_MEASUREMENT) 172 | # define LC_IDENTIFICATION_MASK (1 << __LC_IDENTIFICATION) 173 | # define LC_ALL_MASK (LC_CTYPE_MASK \ 174 | | LC_NUMERIC_MASK \ 175 | | LC_TIME_MASK \ 176 | | LC_COLLATE_MASK \ 177 | | LC_MONETARY_MASK \ 178 | | LC_MESSAGES_MASK \ 179 | | LC_PAPER_MASK \ 180 | | LC_NAME_MASK \ 181 | | LC_ADDRESS_MASK \ 182 | | LC_TELEPHONE_MASK \ 183 | | LC_MEASUREMENT_MASK \ 184 | | LC_IDENTIFICATION_MASK \ 185 | ) 186 | 187 | /* Return a duplicate of the set of locale in DATASET. All usage 188 | counters are increased if necessary. */ 189 | extern __locale_t duplocale (__locale_t __dataset) __THROW; 190 | 191 | /* Free the data associated with a locale dataset previously returned 192 | by a call to `setlocale_r'. */ 193 | extern void freelocale (__locale_t __dataset) __THROW; 194 | 195 | /* Switch the current thread's locale to DATASET. 196 | If DATASET is null, instead just return the current setting. 197 | The special value LC_GLOBAL_LOCALE is the initial setting 198 | for all threads and can also be installed any time, meaning 199 | the thread uses the global settings controlled by `setlocale'. */ 200 | extern __locale_t uselocale (__locale_t __dataset) __THROW; 201 | 202 | /* This value can be passed to `uselocale' and may be returned by it. 203 | Passing this value to any other function has undefined behavior. */ 204 | # define LC_GLOBAL_LOCALE ((__locale_t) -1L) 205 | 206 | #endif 207 | 208 | __END_DECLS 209 | 210 | #endif /* locale.h */ 211 | -------------------------------------------------------------------------------- /gnu/glibc-2.3.2/time/sys/time.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 1991-1994,96,97,98,99,2000,01,02 2 | Free Software Foundation, Inc. 3 | This file is part of the GNU C Library. 4 | 5 | The GNU C Library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | The GNU C Library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with the GNU C Library; if not, write to the Free 17 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 18 | 02111-1307 USA. */ 19 | 20 | #ifndef _SYS_TIME_H 21 | #define _SYS_TIME_H 1 22 | 23 | #include 24 | 25 | #include 26 | #define __need_time_t 27 | #include 28 | #define __need_timeval 29 | #include 30 | 31 | #include 32 | 33 | #ifndef __suseconds_t_defined 34 | typedef __suseconds_t suseconds_t; 35 | # define __suseconds_t_defined 36 | #endif 37 | 38 | 39 | __BEGIN_DECLS 40 | 41 | #ifdef __USE_GNU 42 | /* Macros for converting between `struct timeval' and `struct timespec'. */ 43 | # define TIMEVAL_TO_TIMESPEC(tv, ts) { \ 44 | (ts)->tv_sec = (tv)->tv_sec; \ 45 | (ts)->tv_nsec = (tv)->tv_usec * 1000; \ 46 | } 47 | # define TIMESPEC_TO_TIMEVAL(tv, ts) { \ 48 | (tv)->tv_sec = (ts)->tv_sec; \ 49 | (tv)->tv_usec = (ts)->tv_nsec / 1000; \ 50 | } 51 | #endif 52 | 53 | 54 | #ifdef __USE_BSD 55 | /* Structure crudely representing a timezone. 56 | This is obsolete and should never be used. */ 57 | struct timezone 58 | { 59 | int tz_minuteswest; /* Minutes west of GMT. */ 60 | int tz_dsttime; /* Nonzero if DST is ever in effect. */ 61 | }; 62 | 63 | typedef struct timezone *__restrict __timezone_ptr_t; 64 | #else 65 | typedef void *__restrict __timezone_ptr_t; 66 | #endif 67 | 68 | /* Get the current time of day and timezone information, 69 | putting it into *TV and *TZ. If TZ is NULL, *TZ is not filled. 70 | Returns 0 on success, -1 on errors. 71 | NOTE: This form of timezone information is obsolete. 72 | Use the functions and variables declared in instead. */ 73 | extern int gettimeofday (struct timeval *__restrict __tv, 74 | __timezone_ptr_t __tz) __THROW; 75 | 76 | #ifdef __USE_BSD 77 | /* Set the current time of day and timezone information. 78 | This call is restricted to the super-user. */ 79 | extern int settimeofday (__const struct timeval *__tv, 80 | __const struct timezone *__tz) __THROW; 81 | 82 | /* Adjust the current time of day by the amount in DELTA. 83 | If OLDDELTA is not NULL, it is filled in with the amount 84 | of time adjustment remaining to be done from the last `adjtime' call. 85 | This call is restricted to the super-user. */ 86 | extern int adjtime (__const struct timeval *__delta, 87 | struct timeval *__olddelta) __THROW; 88 | #endif 89 | 90 | 91 | /* Values for the first argument to `getitimer' and `setitimer'. */ 92 | enum __itimer_which 93 | { 94 | /* Timers run in real time. */ 95 | ITIMER_REAL = 0, 96 | #define ITIMER_REAL ITIMER_REAL 97 | /* Timers run only when the process is executing. */ 98 | ITIMER_VIRTUAL = 1, 99 | #define ITIMER_VIRTUAL ITIMER_VIRTUAL 100 | /* Timers run when the process is executing and when 101 | the system is executing on behalf of the process. */ 102 | ITIMER_PROF = 2 103 | #define ITIMER_PROF ITIMER_PROF 104 | }; 105 | 106 | /* Type of the second argument to `getitimer' and 107 | the second and third arguments `setitimer'. */ 108 | struct itimerval 109 | { 110 | /* Value to put into `it_value' when the timer expires. */ 111 | struct timeval it_interval; 112 | /* Time to the next timer expiration. */ 113 | struct timeval it_value; 114 | }; 115 | 116 | #if defined __USE_GNU && !defined __cplusplus 117 | /* Use the nicer parameter type only in GNU mode and not for C++ since the 118 | strict C++ rules prevent the automatic promotion. */ 119 | typedef enum __itimer_which __itimer_which_t; 120 | #else 121 | typedef int __itimer_which_t; 122 | #endif 123 | 124 | /* Set *VALUE to the current setting of timer WHICH. 125 | Return 0 on success, -1 on errors. */ 126 | extern int getitimer (__itimer_which_t __which, 127 | struct itimerval *__value) __THROW; 128 | 129 | /* Set the timer WHICH to *NEW. If OLD is not NULL, 130 | set *OLD to the old value of timer WHICH. 131 | Returns 0 on success, -1 on errors. */ 132 | extern int setitimer (__itimer_which_t __which, 133 | __const struct itimerval *__restrict __new, 134 | struct itimerval *__restrict __old) __THROW; 135 | 136 | /* Change the access time of FILE to TVP[0] and the modification time of 137 | FILE to TVP[1]. If TVP is a null pointer, use the current time instead. 138 | Returns 0 on success, -1 on errors. */ 139 | extern int utimes (__const char *__file, __const struct timeval __tvp[2]) 140 | __THROW; 141 | 142 | #ifdef __USE_BSD 143 | /* Same as `utimes', but does not follow symbolic links. */ 144 | extern int lutimes (__const char *__file, __const struct timeval __tvp[2]) 145 | __THROW; 146 | 147 | /* Same as `utimes', but takes an open file descriptor instead of a name. */ 148 | extern int futimes (int fd, __const struct timeval __tvp[2]) __THROW; 149 | #endif 150 | 151 | 152 | #ifdef __USE_BSD 153 | /* Convenience macros for operations on timevals. 154 | NOTE: `timercmp' does not work for >= or <=. */ 155 | # define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec) 156 | # define timerclear(tvp) ((tvp)->tv_sec = (tvp)->tv_usec = 0) 157 | # define timercmp(a, b, CMP) \ 158 | (((a)->tv_sec == (b)->tv_sec) ? \ 159 | ((a)->tv_usec CMP (b)->tv_usec) : \ 160 | ((a)->tv_sec CMP (b)->tv_sec)) 161 | # define timeradd(a, b, result) \ 162 | do { \ 163 | (result)->tv_sec = (a)->tv_sec + (b)->tv_sec; \ 164 | (result)->tv_usec = (a)->tv_usec + (b)->tv_usec; \ 165 | if ((result)->tv_usec >= 1000000) \ 166 | { \ 167 | ++(result)->tv_sec; \ 168 | (result)->tv_usec -= 1000000; \ 169 | } \ 170 | } while (0) 171 | # define timersub(a, b, result) \ 172 | do { \ 173 | (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ 174 | (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ 175 | if ((result)->tv_usec < 0) { \ 176 | --(result)->tv_sec; \ 177 | (result)->tv_usec += 1000000; \ 178 | } \ 179 | } while (0) 180 | #endif /* BSD */ 181 | 182 | __END_DECLS 183 | 184 | #endif /* sys/time.h */ 185 | -------------------------------------------------------------------------------- /v6/usr/source/s1/glob.c: -------------------------------------------------------------------------------- 1 | # 2 | /* global command -- 3 | 4 | glob params 5 | 6 | "*" in params matches r.e ".*" 7 | "?" in params matches r.e. "." 8 | "[...]" in params matches character class 9 | "[...a-z...]" in params matches a through z. 10 | 11 | perform command with argument list 12 | constructed as follows: 13 | if param does not contain "*", "[", or "?", use it as is 14 | if it does, find all files in current directory 15 | which match the param, sort them, and use them 16 | 17 | prepend the command name with "/bin" or "/usr/bin" 18 | as required. 19 | */ 20 | 21 | #define E2BIG 7 22 | #define ENOEXEC 8 23 | #define ENOENT 2 24 | 25 | #define STRSIZ 522 26 | char ab[STRSIZ]; /* generated characters */ 27 | char *ava[200]; /* generated arguments */ 28 | char **av &ava[1]; 29 | char *string ab; 30 | int errno; 31 | int ncoll; 32 | 33 | main(argc, argv) 34 | char *argv[]; 35 | { 36 | register char *cp; 37 | 38 | if (argc < 3) { 39 | write(2, "Arg count\n", 10); 40 | return; 41 | } 42 | argv++; 43 | *av++ = *argv; 44 | while (--argc >= 2) 45 | expand(*++argv); 46 | if (ncoll==0) { 47 | write(2, "No match\n", 9); 48 | return; 49 | } 50 | execute(ava[1], &ava[1]); 51 | cp = cat("/usr/bin/", ava[1]); 52 | execute(cp+4, &ava[1]); 53 | execute(cp, &ava[1]); 54 | write(2, "Command not found.\n", 19); 55 | } 56 | 57 | expand(as) 58 | char *as; 59 | { 60 | register char *s, *cs; 61 | register int dirf; 62 | char **oav; 63 | static struct { 64 | int ino; 65 | char name[16]; 66 | } entry; 67 | 68 | s = cs = as; 69 | while (*cs!='*' && *cs!='?' && *cs!='[') { 70 | if (*cs++ == 0) { 71 | *av++ = cat(s, ""); 72 | return; 73 | } 74 | } 75 | for (;;) { 76 | if (cs==s) { 77 | dirf = open(".", 0); 78 | s = ""; 79 | break; 80 | } 81 | if (*--cs == '/') { 82 | *cs = 0; 83 | dirf = open(s==cs? "/": s, 0); 84 | *cs++ = 0200; 85 | break; 86 | } 87 | } 88 | if (dirf<0) { 89 | write(2, "No directory\n", 13); 90 | exit(); 91 | } 92 | oav = av; 93 | while (read(dirf, &entry, 16) == 16) { 94 | if (entry.ino==0) 95 | continue; 96 | if (match(entry.name, cs)) { 97 | *av++ = cat(s, entry.name); 98 | ncoll++; 99 | } 100 | } 101 | close(dirf); 102 | sort(oav); 103 | } 104 | 105 | sort(oav) 106 | char **oav; 107 | { 108 | register char **p1, **p2, **c; 109 | 110 | p1 = oav; 111 | while (p1 < av-1) { 112 | p2 = p1; 113 | while(++p2 < av) { 114 | if (compar(*p1, *p2) > 0) { 115 | c = *p1; 116 | *p1 = *p2; 117 | *p2 = c; 118 | } 119 | } 120 | p1++; 121 | } 122 | } 123 | 124 | execute(afile, aarg) 125 | char *afile; 126 | char **aarg; 127 | { 128 | register char *file, **arg; 129 | 130 | arg = aarg; 131 | file = afile; 132 | execv(file, arg); 133 | if (errno==ENOEXEC) { 134 | arg[0] = file; 135 | *--arg = "/bin/sh"; 136 | execv(*arg, arg); 137 | } 138 | if (errno==E2BIG) 139 | toolong(); 140 | } 141 | 142 | toolong() 143 | { 144 | write(2, "Arg list too long\n", 18); 145 | exit(); 146 | } 147 | 148 | match(s, p) 149 | char *s, *p; 150 | { 151 | if (*s=='.' && *p!='.') 152 | return(0); 153 | return(amatch(s, p)); 154 | } 155 | 156 | amatch(as, ap) 157 | char *as, *ap; 158 | { 159 | register char *s, *p; 160 | register scc; 161 | int c, cc, ok, lc; 162 | 163 | s = as; 164 | p = ap; 165 | if (scc = *s++) 166 | if ((scc =& 0177) == 0) 167 | scc = 0200; 168 | switch (c = *p++) { 169 | 170 | case '[': 171 | ok = 0; 172 | lc = 077777; 173 | while (cc = *p++) { 174 | if (cc==']') { 175 | if (ok) 176 | return(amatch(s, p)); 177 | else 178 | return(0); 179 | } else if (cc=='-') { 180 | if (lc<=scc && scc<=(c = *p++)) 181 | ok++; 182 | } else 183 | if (scc == (lc=cc)) 184 | ok++; 185 | } 186 | return(0); 187 | 188 | default: 189 | if (c!=scc) 190 | return(0); 191 | 192 | case '?': 193 | if (scc) 194 | return(amatch(s, p)); 195 | return(0); 196 | 197 | case '*': 198 | return(umatch(--s, p)); 199 | 200 | case '\0': 201 | return(!scc); 202 | } 203 | } 204 | 205 | umatch(s, p) 206 | char *s, *p; 207 | { 208 | if(*p==0) 209 | return(1); 210 | while(*s) 211 | if (amatch(s++,p)) 212 | return(1); 213 | return(0); 214 | } 215 | 216 | compar(as1, as2) 217 | char *as1, *as2; 218 | { 219 | register char *s1, *s2; 220 | 221 | s1 = as1; 222 | s2 = as2; 223 | while (*s1++ == *s2) 224 | if (*s2++ == 0) 225 | return(0); 226 | return (*--s1 - *s2); 227 | } 228 | 229 | cat(as1, as2) 230 | char *as1, *as2; 231 | { 232 | register char *s1, *s2; 233 | register int c; 234 | 235 | s2 = string; 236 | s1 = as1; 237 | while (c = *s1++) { 238 | if (s2 > &ab[STRSIZ]) 239 | toolong(); 240 | c =& 0177; 241 | if (c==0) { 242 | *s2++ = '/'; 243 | break; 244 | } 245 | *s2++ = c; 246 | } 247 | s1 = as2; 248 | do { 249 | if (s2 > &ab[STRSIZ]) 250 | toolong(); 251 | *s2++ = c = *s1++; 252 | } while (c); 253 | s1 = string; 254 | string = s2; 255 | return(s1); 256 | } 257 | -------------------------------------------------------------------------------- /v7/usr/include/sys/dir.h: -------------------------------------------------------------------------------- 1 | #ifndef DIRSIZ 2 | #define DIRSIZ 14 3 | #endif 4 | struct direct 5 | { 6 | ino_t d_ino; 7 | char d_name[DIRSIZ]; 8 | }; 9 | -------------------------------------------------------------------------------- /v7/usr/man/man3/end.3: -------------------------------------------------------------------------------- 1 | .TH END 3 2 | .SH NAME 3 | end, etext, edata \- last locations in program 4 | .SH SYNOPSIS 5 | .B extern end; 6 | .br 7 | .B extern etext; 8 | .br 9 | .B extern edata; 10 | .SH DESCRIPTION 11 | These names refer neither to routines 12 | nor to locations with interesting contents. 13 | The address of 14 | .I etext 15 | is the first address above the program text, 16 | .I edata 17 | above the initialized data region, and 18 | .I end 19 | above the uninitialized data region. 20 | .PP 21 | When execution begins, the program break 22 | coincides with 23 | .I end, 24 | but many functions reset the program break, among them 25 | the routines of 26 | .IR brk (2), 27 | .IR malloc (3), 28 | standard input/output 29 | .RI ( stdio (3)), 30 | the profile 31 | .RB ( \-p ) 32 | option of 33 | .IR cc (1), 34 | etc. 35 | The current value of the program break 36 | is reliably returned by `sbrk(0)', 37 | see 38 | .IR brk (2). 39 | .SH "SEE ALSO" 40 | brk(2), malloc(3) 41 | -------------------------------------------------------------------------------- /v7/usr/src/cmd/cat.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Concatenate files. 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | char stdbuf[BUFSIZ]; 10 | 11 | main(argc, argv) 12 | char **argv; 13 | { 14 | int fflg = 0; 15 | register FILE *fi; 16 | register c; 17 | int dev, ino = -1; 18 | struct stat statb; 19 | 20 | setbuf(stdout, stdbuf); 21 | for( ; argc>1 && argv[1][0]=='-'; argc--,argv++) { 22 | switch(argv[1][1]) { 23 | case 0: 24 | break; 25 | case 'u': 26 | setbuf(stdout, (char *)NULL); 27 | continue; 28 | } 29 | break; 30 | } 31 | fstat(fileno(stdout), &statb); 32 | statb.st_mode &= S_IFMT; 33 | if (statb.st_mode!=S_IFCHR && statb.st_mode!=S_IFBLK) { 34 | dev = statb.st_dev; 35 | ino = statb.st_ino; 36 | } 37 | if (argc < 2) { 38 | argc = 2; 39 | fflg++; 40 | } 41 | while (--argc > 0) { 42 | if (fflg || (*++argv)[0]=='-' && (*argv)[1]=='\0') 43 | fi = stdin; 44 | else { 45 | if ((fi = fopen(*argv, "r")) == NULL) { 46 | fprintf(stderr, "cat: can't open %s\n", *argv); 47 | continue; 48 | } 49 | } 50 | fstat(fileno(fi), &statb); 51 | if (statb.st_dev==dev && statb.st_ino==ino) { 52 | fprintf(stderr, "cat: input %s is output\n", 53 | fflg?"-": *argv); 54 | fclose(fi); 55 | continue; 56 | } 57 | while ((c = getc(fi)) != EOF) 58 | putchar(c); 59 | if (fi!=stdin) 60 | fclose(fi); 61 | } 62 | return(0); 63 | } 64 | -------------------------------------------------------------------------------- /v7/usr/src/cmd/echo.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | main(argc, argv) 4 | int argc; 5 | char *argv[]; 6 | { 7 | register int i, nflg; 8 | 9 | nflg = 0; 10 | if(argc > 1 && argv[1][0] == '-' && argv[1][1] == 'n') { 11 | nflg++; 12 | argc--; 13 | argv++; 14 | } 15 | for(i=1; i 11 | #include 12 | #include 13 | 14 | #define CBRA 1 15 | #define CCHR 2 16 | #define CDOT 4 17 | #define CCL 6 18 | #define NCCL 8 19 | #define CDOL 10 20 | #define CEOF 11 21 | #define CKET 12 22 | #define CBACK 18 23 | 24 | #define STAR 01 25 | 26 | #define LBSIZE 512 27 | #define ESIZE 256 28 | #define NBRA 9 29 | 30 | char expbuf[ESIZE]; 31 | long lnum; 32 | char linebuf[LBSIZE+1]; 33 | char ybuf[ESIZE]; 34 | int bflag; 35 | int lflag; 36 | int nflag; 37 | int cflag; 38 | int vflag; 39 | int nfile; 40 | int hflag = 1; 41 | int sflag; 42 | int yflag; 43 | int circf; 44 | long tln; 45 | int nsucc; 46 | char *braslist[NBRA]; 47 | char *braelist[NBRA]; 48 | char bittab[] = { 49 | 1, 50 | 2, 51 | 4, 52 | 8, 53 | 16, 54 | 32, 55 | 64, 56 | 128 57 | }; 58 | 59 | main(argc, argv) 60 | char **argv; 61 | { 62 | while (--argc > 0 && (++argv)[0][0]=='-') 63 | switch (argv[0][1]) { 64 | 65 | case 'y': 66 | yflag++; 67 | continue; 68 | 69 | case 'h': 70 | hflag = 0; 71 | continue; 72 | 73 | case 's': 74 | sflag++; 75 | continue; 76 | 77 | case 'v': 78 | vflag++; 79 | continue; 80 | 81 | case 'b': 82 | bflag++; 83 | continue; 84 | 85 | case 'l': 86 | lflag++; 87 | continue; 88 | 89 | case 'c': 90 | cflag++; 91 | continue; 92 | 93 | case 'n': 94 | nflag++; 95 | continue; 96 | 97 | case 'e': 98 | --argc; 99 | ++argv; 100 | goto out; 101 | 102 | default: 103 | errexit("grep: unknown flag\n", (char *)NULL); 104 | continue; 105 | } 106 | out: 107 | if (argc<=0) 108 | exit(2); 109 | if (yflag) { 110 | register char *p, *s; 111 | for (s = ybuf, p = *argv; *p; ) { 112 | if (*p == '\\') { 113 | *s++ = *p++; 114 | if (*p) 115 | *s++ = *p++; 116 | } else if (*p == '[') { 117 | while (*p != '\0' && *p != ']') 118 | *s++ = *p++; 119 | } else if (islower(*p)) { 120 | *s++ = '['; 121 | *s++ = toupper(*p); 122 | *s++ = *p++; 123 | *s++ = ']'; 124 | } else 125 | *s++ = *p++; 126 | if (s >= ybuf+ESIZE-5) 127 | errexit("grep: argument too long\n", (char *)NULL); 128 | } 129 | *s = '\0'; 130 | *argv = ybuf; 131 | } 132 | compile(*argv); 133 | nfile = --argc; 134 | if (argc<=0) { 135 | if (lflag) 136 | exit(1); 137 | execute((char *)NULL); 138 | } else while (--argc >= 0) { 139 | argv++; 140 | execute(*argv); 141 | } 142 | exit(nsucc == 0); 143 | } 144 | 145 | compile(astr) 146 | char *astr; 147 | { 148 | register c; 149 | register char *ep, *sp; 150 | char *cstart; 151 | char *lastep; 152 | int cclcnt; 153 | char bracket[NBRA], *bracketp; 154 | int closed; 155 | char numbra; 156 | char neg; 157 | 158 | ep = expbuf; 159 | sp = astr; 160 | lastep = 0; 161 | bracketp = bracket; 162 | closed = numbra = 0; 163 | if (*sp == '^') { 164 | circf++; 165 | sp++; 166 | } 167 | for (;;) { 168 | if (ep >= &expbuf[ESIZE]) 169 | goto cerror; 170 | if ((c = *sp++) != '*') 171 | lastep = ep; 172 | switch (c) { 173 | 174 | case '\0': 175 | *ep++ = CEOF; 176 | return; 177 | 178 | case '.': 179 | *ep++ = CDOT; 180 | continue; 181 | 182 | case '*': 183 | if (lastep==0 || *lastep==CBRA || *lastep==CKET) 184 | goto defchar; 185 | *lastep |= STAR; 186 | continue; 187 | 188 | case '$': 189 | if (*sp != '\0') 190 | goto defchar; 191 | *ep++ = CDOL; 192 | continue; 193 | 194 | case '[': 195 | if(&ep[17] >= &expbuf[ESIZE]) 196 | goto cerror; 197 | *ep++ = CCL; 198 | neg = 0; 199 | if((c = *sp++) == '^') { 200 | neg = 1; 201 | c = *sp++; 202 | } 203 | cstart = sp; 204 | do { 205 | if (c=='\0') 206 | goto cerror; 207 | if (c=='-' && sp>cstart && *sp!=']') { 208 | for (c = sp[-2]; c<*sp; c++) 209 | ep[c>>3] |= bittab[c&07]; 210 | sp++; 211 | } 212 | ep[c>>3] |= bittab[c&07]; 213 | } while((c = *sp++) != ']'); 214 | if(neg) { 215 | for(cclcnt = 0; cclcnt < 16; cclcnt++) 216 | ep[cclcnt] ^= -1; 217 | ep[0] &= 0376; 218 | } 219 | 220 | ep += 16; 221 | 222 | continue; 223 | 224 | case '\\': 225 | if((c = *sp++) == '(') { 226 | if(numbra >= NBRA) { 227 | goto cerror; 228 | } 229 | *bracketp++ = numbra; 230 | *ep++ = CBRA; 231 | *ep++ = numbra++; 232 | continue; 233 | } 234 | if(c == ')') { 235 | if(bracketp <= bracket) { 236 | goto cerror; 237 | } 238 | *ep++ = CKET; 239 | *ep++ = *--bracketp; 240 | closed++; 241 | continue; 242 | } 243 | 244 | if(c >= '1' && c <= '9') { 245 | if((c -= '1') >= closed) 246 | goto cerror; 247 | *ep++ = CBACK; 248 | *ep++ = c; 249 | continue; 250 | } 251 | 252 | defchar: 253 | default: 254 | *ep++ = CCHR; 255 | *ep++ = c; 256 | } 257 | } 258 | cerror: 259 | errexit("grep: RE error\n", (char *)NULL); 260 | } 261 | 262 | execute(file) 263 | char *file; 264 | { 265 | register char *p1, *p2; 266 | register c; 267 | 268 | if (file) { 269 | if (freopen(file, "r", stdin) == NULL) 270 | errexit("grep: can't open %s\n", file); 271 | } 272 | lnum = 0; 273 | tln = 0; 274 | for (;;) { 275 | lnum++; 276 | p1 = linebuf; 277 | while ((c = getchar()) != '\n') { 278 | if (c == EOF) { 279 | if (cflag) { 280 | if (nfile>1) 281 | printf("%s:", file); 282 | printf("%D\n", tln); 283 | } 284 | return; 285 | } 286 | *p1++ = c; 287 | if (p1 >= &linebuf[LBSIZE-1]) 288 | break; 289 | } 290 | *p1++ = '\0'; 291 | p1 = linebuf; 292 | p2 = expbuf; 293 | if (circf) { 294 | if (advance(p1, p2)) 295 | goto found; 296 | goto nfound; 297 | } 298 | /* fast check for first character */ 299 | if (*p2==CCHR) { 300 | c = p2[1]; 301 | do { 302 | if (*p1!=c) 303 | continue; 304 | if (advance(p1, p2)) 305 | goto found; 306 | } while (*p1++); 307 | goto nfound; 308 | } 309 | /* regular algorithm */ 310 | do { 311 | if (advance(p1, p2)) 312 | goto found; 313 | } while (*p1++); 314 | nfound: 315 | if (vflag) 316 | succeed(file); 317 | continue; 318 | found: 319 | if (vflag==0) 320 | succeed(file); 321 | } 322 | } 323 | 324 | advance(lp, ep) 325 | register char *lp, *ep; 326 | { 327 | register char *curlp; 328 | char c; 329 | char *bbeg; 330 | int ct; 331 | 332 | for (;;) switch (*ep++) { 333 | 334 | case CCHR: 335 | if (*ep++ == *lp++) 336 | continue; 337 | return(0); 338 | 339 | case CDOT: 340 | if (*lp++) 341 | continue; 342 | return(0); 343 | 344 | case CDOL: 345 | if (*lp==0) 346 | continue; 347 | return(0); 348 | 349 | case CEOF: 350 | return(1); 351 | 352 | case CCL: 353 | c = *lp++ & 0177; 354 | if(ep[c>>3] & bittab[c & 07]) { 355 | ep += 16; 356 | continue; 357 | } 358 | return(0); 359 | case CBRA: 360 | braslist[*ep++] = lp; 361 | continue; 362 | 363 | case CKET: 364 | braelist[*ep++] = lp; 365 | continue; 366 | 367 | case CBACK: 368 | bbeg = braslist[*ep]; 369 | if (braelist[*ep]==0) 370 | return(0); 371 | ct = braelist[*ep++] - bbeg; 372 | if(ecmp(bbeg, lp, ct)) { 373 | lp += ct; 374 | continue; 375 | } 376 | return(0); 377 | 378 | case CBACK|STAR: 379 | bbeg = braslist[*ep]; 380 | if (braelist[*ep]==0) 381 | return(0); 382 | ct = braelist[*ep++] - bbeg; 383 | curlp = lp; 384 | while(ecmp(bbeg, lp, ct)) 385 | lp += ct; 386 | while(lp >= curlp) { 387 | if(advance(lp, ep)) return(1); 388 | lp -= ct; 389 | } 390 | return(0); 391 | 392 | 393 | case CDOT|STAR: 394 | curlp = lp; 395 | while (*lp++); 396 | goto star; 397 | 398 | case CCHR|STAR: 399 | curlp = lp; 400 | while (*lp++ == *ep); 401 | ep++; 402 | goto star; 403 | 404 | case CCL|STAR: 405 | curlp = lp; 406 | do { 407 | c = *lp++ & 0177; 408 | } while(ep[c>>3] & bittab[c & 07]); 409 | ep += 16; 410 | goto star; 411 | 412 | star: 413 | if(--lp == curlp) { 414 | continue; 415 | } 416 | 417 | if(*ep == CCHR) { 418 | c = ep[1]; 419 | do { 420 | if(*lp != c) 421 | continue; 422 | if(advance(lp, ep)) 423 | return(1); 424 | } while(lp-- > curlp); 425 | return(0); 426 | } 427 | 428 | do { 429 | if (advance(lp, ep)) 430 | return(1); 431 | } while (lp-- > curlp); 432 | return(0); 433 | 434 | default: 435 | errexit("grep RE botch\n", (char *)NULL); 436 | } 437 | } 438 | 439 | succeed(f) 440 | char *f; 441 | { 442 | long ftell(); 443 | nsucc = 1; 444 | if (sflag) 445 | return; 446 | if (cflag) { 447 | tln++; 448 | return; 449 | } 450 | if (lflag) { 451 | printf("%s\n", f); 452 | fseek(stdin, 0l, 2); 453 | return; 454 | } 455 | if (nfile > 1 && hflag) 456 | printf("%s:", f); 457 | if (bflag) 458 | printf("%ld:", (ftell(stdin)-1)/BSIZE); 459 | if (nflag) 460 | printf("%ld:", lnum); 461 | printf("%s\n", linebuf); 462 | } 463 | 464 | ecmp(a, b, count) 465 | char *a, *b; 466 | { 467 | register cc = count; 468 | while(cc--) 469 | if(*a++ != *b++) return(0); 470 | return(1); 471 | } 472 | 473 | errexit(s, f) 474 | char *s, *f; 475 | { 476 | fprintf(stderr, s, f); 477 | exit(2); 478 | } 479 | -------------------------------------------------------------------------------- /v7/usr/src/cmd/ls.c: -------------------------------------------------------------------------------- 1 | /* 2 | * list file or directory 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #define NFILES 1024 11 | FILE *pwdf, *dirf; 12 | char stdbuf[BUFSIZ]; 13 | 14 | struct lbuf { 15 | union { 16 | char lname[15]; 17 | char *namep; 18 | } ln; 19 | char ltype; 20 | short lnum; 21 | short lflags; 22 | short lnl; 23 | short luid; 24 | short lgid; 25 | long lsize; 26 | long lmtime; 27 | }; 28 | 29 | int aflg, dflg, lflg, sflg, tflg, uflg, iflg, fflg, gflg, cflg; 30 | int rflg = 1; 31 | long year; 32 | int flags; 33 | int lastuid = -1; 34 | char tbuf[16]; 35 | long tblocks; 36 | int statreq; 37 | struct lbuf *flist[NFILES]; 38 | struct lbuf **lastp = flist; 39 | struct lbuf **firstp = flist; 40 | char *dotp = "."; 41 | 42 | char *makename(); 43 | struct lbuf *gstat(); 44 | char *ctime(); 45 | long nblock(); 46 | 47 | #define ISARG 0100000 48 | 49 | main(argc, argv) 50 | char *argv[]; 51 | { 52 | int i; 53 | register struct lbuf *ep, **ep1; 54 | register struct lbuf **slastp; 55 | struct lbuf **epp; 56 | struct lbuf lb; 57 | char *t; 58 | int compar(); 59 | 60 | setbuf(stdout, stdbuf); 61 | time(&lb.lmtime); 62 | year = lb.lmtime - 6L*30L*24L*60L*60L; /* 6 months ago */ 63 | if (--argc > 0 && *argv[1] == '-') { 64 | argv++; 65 | while (*++*argv) switch (**argv) { 66 | 67 | case 'a': 68 | aflg++; 69 | continue; 70 | 71 | case 's': 72 | sflg++; 73 | statreq++; 74 | continue; 75 | 76 | case 'd': 77 | dflg++; 78 | continue; 79 | 80 | case 'g': 81 | gflg++; 82 | continue; 83 | 84 | case 'l': 85 | lflg++; 86 | statreq++; 87 | continue; 88 | 89 | case 'r': 90 | rflg = -1; 91 | continue; 92 | 93 | case 't': 94 | tflg++; 95 | statreq++; 96 | continue; 97 | 98 | case 'u': 99 | uflg++; 100 | continue; 101 | 102 | case 'c': 103 | cflg++; 104 | continue; 105 | 106 | case 'i': 107 | iflg++; 108 | continue; 109 | 110 | case 'f': 111 | fflg++; 112 | continue; 113 | 114 | default: 115 | continue; 116 | } 117 | argc--; 118 | } 119 | if (fflg) { 120 | aflg++; 121 | lflg = 0; 122 | sflg = 0; 123 | tflg = 0; 124 | statreq = 0; 125 | } 126 | if(lflg) { 127 | t = "/etc/passwd"; 128 | if(gflg) 129 | t = "/etc/group"; 130 | pwdf = fopen(t, "r"); 131 | } 132 | if (argc==0) { 133 | argc++; 134 | argv = &dotp - 1; 135 | } 136 | for (i=0; i < argc; i++) { 137 | if ((ep = gstat(*++argv, 1))==NULL) 138 | continue; 139 | ep->ln.namep = *argv; 140 | ep->lflags |= ISARG; 141 | } 142 | qsort(firstp, lastp - firstp, sizeof *lastp, compar); 143 | slastp = lastp; 144 | for (epp=firstp; eppltype=='d' && dflg==0 || fflg) { 147 | if (argc>1) 148 | printf("\n%s:\n", ep->ln.namep); 149 | lastp = slastp; 150 | readdir(ep->ln.namep); 151 | if (fflg==0) 152 | qsort(slastp,lastp - slastp,sizeof *lastp,compar); 153 | if (lflg || sflg) 154 | printf("total %D\n", tblocks); 155 | for (ep1=slastp; ep1lnum == -1) 173 | return; 174 | if (iflg) 175 | printf("%5u ", p->lnum); 176 | if (sflg) 177 | printf("%4D ", nblock(p->lsize)); 178 | if (lflg) { 179 | putchar(p->ltype); 180 | pmode(p->lflags); 181 | printf("%2d ", p->lnl); 182 | t = p->luid; 183 | if(gflg) 184 | t = p->lgid; 185 | if (getname(t, tbuf)==0) 186 | printf("%-6.6s", tbuf); 187 | else 188 | printf("%-6d", t); 189 | if (p->ltype=='b' || p->ltype=='c') 190 | printf("%3d,%3d", major((int)p->lsize), minor((int)p->lsize)); 191 | else 192 | printf("%7ld", p->lsize); 193 | cp = ctime(&p->lmtime); 194 | if(p->lmtime < year) 195 | printf(" %-7.7s %-4.4s ", cp+4, cp+20); else 196 | printf(" %-12.12s ", cp+4); 197 | } 198 | if (p->lflags&ISARG) 199 | printf("%s\n", p->ln.namep); 200 | else 201 | printf("%.14s\n", p->ln.lname); 202 | } 203 | 204 | getname(uid, buf) 205 | int uid; 206 | char buf[]; 207 | { 208 | int j, c, n, i; 209 | 210 | if (uid==lastuid) 211 | return(0); 212 | if(pwdf == NULL) 213 | return(-1); 214 | rewind(pwdf); 215 | lastuid = -1; 216 | do { 217 | i = 0; 218 | j = 0; 219 | n = 0; 220 | while((c=fgetc(pwdf)) != '\n') { 221 | if (c==EOF) 222 | return(-1); 223 | if (c==':') { 224 | j++; 225 | c = '0'; 226 | } 227 | if (j==0) 228 | buf[i++] = c; 229 | if (j==2) 230 | n = n*10 + c - '0'; 231 | } 232 | } while (n != uid); 233 | buf[i++] = '\0'; 234 | lastuid = uid; 235 | return(0); 236 | } 237 | 238 | long 239 | nblock(size) 240 | long size; 241 | { 242 | return((size+511)>>9); 243 | } 244 | 245 | int m1[] = { 1, S_IREAD>>0, 'r', '-' }; 246 | int m2[] = { 1, S_IWRITE>>0, 'w', '-' }; 247 | int m3[] = { 2, S_ISUID, 's', S_IEXEC>>0, 'x', '-' }; 248 | int m4[] = { 1, S_IREAD>>3, 'r', '-' }; 249 | int m5[] = { 1, S_IWRITE>>3, 'w', '-' }; 250 | int m6[] = { 2, S_ISGID, 's', S_IEXEC>>3, 'x', '-' }; 251 | int m7[] = { 1, S_IREAD>>6, 'r', '-' }; 252 | int m8[] = { 1, S_IWRITE>>6, 'w', '-' }; 253 | int m9[] = { 2, S_ISVTX, 't', S_IEXEC>>6, 'x', '-' }; 254 | 255 | int *m[] = { m1, m2, m3, m4, m5, m6, m7, m8, m9}; 256 | 257 | pmode(aflag) 258 | { 259 | register int **mp; 260 | 261 | flags = aflag; 262 | for (mp = &m[0]; mp < &m[sizeof(m)/sizeof(m[0])];) 263 | select(*mp++); 264 | } 265 | 266 | select(pairp) 267 | register int *pairp; 268 | { 269 | register int n; 270 | 271 | n = *pairp++; 272 | while (--n>=0 && (flags&*pairp++)==0) 273 | pairp++; 274 | putchar(*pairp); 275 | } 276 | 277 | char * 278 | makename(dir, file) 279 | char *dir, *file; 280 | { 281 | static char dfile[100]; 282 | register char *dp, *fp; 283 | register int i; 284 | 285 | dp = dfile; 286 | fp = dir; 287 | while (*fp) 288 | *dp++ = *fp++; 289 | *dp++ = '/'; 290 | fp = file; 291 | for (i=0; ilnum != -1) 320 | ep->lnum = dentry.d_ino; 321 | for (j=0; jln.lname[j] = dentry.d_name[j]; 323 | } 324 | fclose(dirf); 325 | } 326 | 327 | struct lbuf * 328 | gstat(file, argfl) 329 | char *file; 330 | { 331 | extern char *malloc(); 332 | struct stat statb; 333 | register struct lbuf *rep; 334 | static int nomocore; 335 | 336 | if (nomocore) 337 | return(NULL); 338 | rep = (struct lbuf *)malloc(sizeof(struct lbuf)); 339 | if (rep==NULL) { 340 | fprintf(stderr, "ls: out of memory\n"); 341 | nomocore = 1; 342 | return(NULL); 343 | } 344 | if (lastp >= &flist[NFILES]) { 345 | static int msg; 346 | lastp--; 347 | if (msg==0) { 348 | fprintf(stderr, "ls: too many files\n"); 349 | msg++; 350 | } 351 | } 352 | *lastp++ = rep; 353 | rep->lflags = 0; 354 | rep->lnum = 0; 355 | rep->ltype = '-'; 356 | if (argfl || statreq) { 357 | if (stat(file, &statb)<0) { 358 | printf("%s not found\n", file); 359 | statb.st_ino = -1; 360 | statb.st_size = 0; 361 | statb.st_mode = 0; 362 | if (argfl) { 363 | lastp--; 364 | return(0); 365 | } 366 | } 367 | rep->lnum = statb.st_ino; 368 | rep->lsize = statb.st_size; 369 | switch(statb.st_mode&S_IFMT) { 370 | 371 | case S_IFDIR: 372 | rep->ltype = 'd'; 373 | break; 374 | 375 | case S_IFBLK: 376 | rep->ltype = 'b'; 377 | rep->lsize = statb.st_rdev; 378 | break; 379 | 380 | case S_IFCHR: 381 | rep->ltype = 'c'; 382 | rep->lsize = statb.st_rdev; 383 | break; 384 | } 385 | rep->lflags = statb.st_mode & ~S_IFMT; 386 | rep->luid = statb.st_uid; 387 | rep->lgid = statb.st_gid; 388 | rep->lnl = statb.st_nlink; 389 | if(uflg) 390 | rep->lmtime = statb.st_atime; 391 | else if (cflg) 392 | rep->lmtime = statb.st_ctime; 393 | else 394 | rep->lmtime = statb.st_mtime; 395 | tblocks += nblock(statb.st_size); 396 | } 397 | return(rep); 398 | } 399 | 400 | compar(pp1, pp2) 401 | struct lbuf **pp1, **pp2; 402 | { 403 | register struct lbuf *p1, *p2; 404 | 405 | p1 = *pp1; 406 | p2 = *pp2; 407 | if (dflg==0) { 408 | if (p1->lflags&ISARG && p1->ltype=='d') { 409 | if (!(p2->lflags&ISARG && p2->ltype=='d')) 410 | return(1); 411 | } else { 412 | if (p2->lflags&ISARG && p2->ltype=='d') 413 | return(-1); 414 | } 415 | } 416 | if (tflg) { 417 | if(p2->lmtime == p1->lmtime) 418 | return(0); 419 | if(p2->lmtime > p1->lmtime) 420 | return(rflg); 421 | return(-rflg); 422 | } 423 | return(rflg * strcmp(p1->lflags&ISARG? p1->ln.namep: p1->ln.lname, 424 | p2->lflags&ISARG? p2->ln.namep: p2->ln.lname)); 425 | } 426 | -------------------------------------------------------------------------------- /v7/usr/src/cmd/rmdir.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Remove directory 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | int Errors = 0; 11 | char *rindex(); 12 | char *strcat(); 13 | char *strcpy(); 14 | 15 | main(argc,argv) 16 | int argc; 17 | char **argv; 18 | { 19 | 20 | if(argc < 2) { 21 | fprintf(stderr, "rmdir: arg count\n"); 22 | exit(1); 23 | } 24 | while(--argc) 25 | rmdir(*++argv); 26 | exit(Errors!=0); 27 | } 28 | 29 | rmdir(d) 30 | char *d; 31 | { 32 | int fd; 33 | char *np, name[500]; 34 | struct stat st, cst; 35 | struct direct dir; 36 | 37 | strcpy(name, d); 38 | if((np = rindex(name, '/')) == NULL) 39 | np = name; 40 | if(stat(name,&st) < 0) { 41 | fprintf(stderr, "rmdir: %s non-existent\n", name); 42 | ++Errors; 43 | return; 44 | } 45 | if (stat("", &cst) < 0) { 46 | fprintf(stderr, "rmdir: cannot stat \"\""); 47 | ++Errors; 48 | exit(1); 49 | } 50 | if((st.st_mode & S_IFMT) != S_IFDIR) { 51 | fprintf(stderr, "rmdir: %s not a directory\n", name); 52 | ++Errors; 53 | return; 54 | } 55 | if(st.st_ino==cst.st_ino &&st.st_dev==cst.st_dev) { 56 | fprintf(stderr, "rmdir: cannot remove current directory\n"); 57 | ++Errors; 58 | return; 59 | } 60 | if((fd = open(name,0)) < 0) { 61 | fprintf(stderr, "rmdir: %s unreadable\n", name); 62 | ++Errors; 63 | return; 64 | } 65 | while(read(fd, (char *)&dir, sizeof dir) == sizeof dir) { 66 | if(dir.d_ino == 0) continue; 67 | if(!strcmp(dir.d_name, ".") || !strcmp(dir.d_name, "..")) 68 | continue; 69 | fprintf(stderr, "rmdir: %s not empty\n", name); 70 | ++Errors; 71 | close(fd); 72 | return; 73 | } 74 | close(fd); 75 | if(!strcmp(np, ".") || !strcmp(np, "..")) { 76 | fprintf(stderr, "rmdir: cannot remove . or ..\n"); 77 | ++Errors; 78 | return; 79 | } 80 | strcat(name, "/."); 81 | if((access(name, 0)) < 0) { /* name/. non-existent */ 82 | strcat(name, "."); 83 | goto unl; 84 | } 85 | strcat(name, "."); 86 | if((access(name, 0)) < 0) /* name/.. non-existent */ 87 | goto unl2; 88 | if(access(name, 02)) { 89 | name[strlen(name)-3] = '\0'; 90 | fprintf(stderr, "rmdir: %s: no permission\n", name); 91 | ++Errors; 92 | return; 93 | } 94 | unl: 95 | unlink(name); /* unlink name/.. */ 96 | unl2: 97 | name[strlen(name)-1] = '\0'; 98 | unlink(name); /* unlink name/. */ 99 | name[strlen(name)-2] = '\0'; 100 | if (unlink(name) < 0) { 101 | fprintf(stderr, "rmdir: %s not removed\n", name); 102 | ++Errors; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /v7/usr/src/libc/gen/sleep.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static jmp_buf jmp; 5 | 6 | sleep(n) 7 | unsigned n; 8 | { 9 | int sleepx(); 10 | unsigned altime; 11 | int (*alsig)() = SIG_DFL; 12 | 13 | if (n==0) 14 | return; 15 | altime = alarm(1000); /* time to maneuver */ 16 | if (setjmp(jmp)) { 17 | signal(SIGALRM, alsig); 18 | alarm(altime); 19 | return; 20 | } 21 | if (altime) { 22 | if (altime > n) 23 | altime -= n; 24 | else { 25 | n = altime; 26 | altime = 1; 27 | } 28 | } 29 | alsig = signal(SIGALRM, sleepx); 30 | alarm(n); 31 | for(;;) 32 | pause(); 33 | /*NOTREACHED*/ 34 | } 35 | 36 | static 37 | sleepx() 38 | { 39 | longjmp(jmp, 1); 40 | } 41 | --------------------------------------------------------------------------------