/* * catsys.c -- a program to print a file twice * This demonstrates the use of file descriptors * * Matt Bishop, ECS 30 (now 36A) * -- November 9, 1996 original version * -- May 30, 2024 minor change to quiet strlen warning */ #include <sys/types.h> #include <fcntl.h> #include <unistd.h> #include <string.h> /* * macros */ #define BUFSIZ 1024 /* size of buffer for file I/O */ /* * forward declarations */ void perror(char *); /* print system error message */ /* * print the file with the given file descriptor * returns 0 on success, -1 on error * does not print any error message */ int cat(int fd) { register int n; /* number of bytes read */ char buf[BUFSIZ]; /* buffer for file I/O */ /* * grab BUFSIZ bytes and dump them to * the standard output */ while((n = read(fd, buf, BUFSIZ)) > 0) /* if error, end this function at once */ if (write(1, buf, n) != n) return(-1); /* if read failed, return error; else okay */ return(n < 0 ? -1 : 0); } /* * print the named file twice * returns 0 on success, 1 on error * prints system error message if there is a problem */ int twocat(char *name) { register int fd; /* file's descriptor */ register int retval = 0; /* value to return */ /* * open the file */ if ((fd = open(name, O_RDONLY)) < 0){ perror(name); return(-1); } /* * display the file, rewind it, and redisplay it * if there's an error, print the system error * message and quit */ if (cat(fd) < 0 || lseek(fd, 0L, SEEK_SET) != 0 || cat(fd) < 0){ perror(name); retval = 1; } /* * close it up and return status */ (void) close(fd); return(retval); } /* * main routine */ int main(int argc, char *argv[]) { register int i; /* counter in a for loop */ register int estat = 0; /* exit status */ /* * bad usage message */ if (argc == 1){ (void) write(2, "Usage: ", strlen("Usage: ")); (void) write(2, argv[0], strlen(argv[0])); (void) write(2, " file [ ... ]\n", strlen(" file [ ... ]\n")); return(1); } /* * print each file twice as you go */ for(i = 1; i < argc; i++) estat += twocat(argv[i]); /* * return number of failures */ return(estat); }
|
ECS 36A, Programming & Problem Solving Version of April 2, 2024 at 12:13PM
|
You can get the raw source code here. |