/*
* 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. |