/* * Concatenate files. */ #include #include #include /* All comments below this one not in the original file. */ char stdbuf[BUFSIZ]; /* BUFSIZ is typically 512, according to man page. */ /* Old style function declaration. Return type defaults to int. Param types * default to int. You can specify param types (when not int) after the * parentheses like below. */ main(argc, argv) char **argv; { int fflg = 0; /* Flag set to 1 if reading from stdin */ register FILE *fi; /* File handle */ register c; /* Current char */ int dev, ino = -1; /* Keep track of file inodes */ struct stat statb; /* File status struct */ /* Handle -u flag */ setbuf(stdout, stdbuf); for( ; argc>1 && argv[1][0]=='-'; argc--,argv++) { switch(argv[1][1]) { case 0: break; case 'u': /* -u flag means don't buffer */ setbuf(stdout, (char *)NULL); continue; } break; } fstat(fileno(stdout), &statb); /* Get file status. */ statb.st_mode &= S_IFMT; /* Use mask to get file type. */ /* If file is not "character special" or "block special"... */ if (statb.st_mode!=S_IFCHR && statb.st_mode!=S_IFBLK) { /* Save file inode data in local vars */ dev = statb.st_dev; ino = statb.st_ino; } if (argc < 2) { argc = 2; fflg++; /* We're reading from stdin */ } while (--argc > 0) { if (fflg || (*++argv)[0]=='-' && (*argv)[1]=='\0') fi = stdin; else { if ((fi = fopen(*argv, "r")) == NULL) { fprintf(stderr, "cat: can't open %s\n", *argv); continue; } } fstat(fileno(fi), &statb); /* Check if we're reading from and writing to same file */ if (statb.st_dev==dev && statb.st_ino==ino) { fprintf(stderr, "cat: input %s is output\n", fflg?"-": *argv); fclose(fi); continue; } while ((c = getc(fi)) != EOF) putchar(c); if (fi!=stdin) fclose(fi); } return(0); }