|
|
1.1 ! root 1: #include <stdio.h> ! 2: #include <signal.h> ! 3: ! 4: #define Read 1 ! 5: #define Write 2 ! 6: #define Endfile 3 ! 7: #define Error 4 ! 8: ! 9: int inpipe, outpipe; ! 10: int infd = 0, outfd = 1; ! 11: int bufmax = 32768; ! 12: char *buffer; ! 13: int reclen; ! 14: extern char *optarg; ! 15: extern int optind; ! 16: extern char *malloc(); ! 17: ! 18: int ! 19: gettoken() ! 20: { ! 21: char c; ! 22: ! 23: switch (read (inpipe, &c, 1)) { ! 24: case 0: return Endfile; ! 25: case 1: return c; ! 26: default: ! 27: perror ("gettoken"); ! 28: return Error; ! 29: } ! 30: } ! 31: ! 32: void ! 33: puttoken(t) ! 34: char t; ! 35: { ! 36: write (outpipe, &t, 1); ! 37: } ! 38: ! 39: int ! 40: readbuf() ! 41: { ! 42: reclen = read (infd, buffer, bufmax); ! 43: ! 44: if (reclen < 0) { ! 45: perror ("read"); ! 46: return 0; ! 47: } ! 48: ! 49: return reclen > 0; ! 50: } ! 51: ! 52: int ! 53: writebuf() ! 54: { ! 55: if (write (outfd, buffer, reclen) != reclen) { ! 56: perror ("write"); ! 57: return 0; ! 58: } ! 59: return 1; ! 60: } ! 61: ! 62: int ! 63: copyloop() ! 64: { ! 65: for (;;) { ! 66: int t; ! 67: if ((t = gettoken()) != Read) ! 68: return t; ! 69: if (!readbuf()) { ! 70: puttoken (Endfile); ! 71: return Endfile; ! 72: } ! 73: puttoken (Read); ! 74: if ((t = gettoken()) != Write) ! 75: return t; ! 76: if (!writebuf()) { ! 77: puttoken (Error); ! 78: return Error; ! 79: } ! 80: puttoken (Write); ! 81: } ! 82: } ! 83: ! 84: int ! 85: copyfile() ! 86: { ! 87: int p0[2], p1[2]; ! 88: int p, pid, status; ! 89: pipe (p0); ! 90: pipe (p1); ! 91: switch (pid = fork()) { ! 92: default: /* parent */ ! 93: inpipe = p0[0]; ! 94: close (p0[1]); ! 95: outpipe = p1[1]; ! 96: close (p1[0]); ! 97: ! 98: status = copyloop(); ! 99: if (status != Endfile) { ! 100: fprintf (stderr, "error: parent status %d\n", status); ! 101: return 1; ! 102: } ! 103: ! 104: do p = wait (&status); ! 105: while (p >= 0 && p != pid); ! 106: if (p < 0) { ! 107: perror ("wait"); ! 108: return 1; ! 109: } ! 110: ! 111: if (status != Endfile<<8) { ! 112: fprintf (stderr, "error: child status %d\n", status); ! 113: return 1; ! 114: } ! 115: ! 116: return 0; ! 117: ! 118: case 0: /* child */ ! 119: inpipe = p1[0]; ! 120: close (p1[1]); ! 121: outpipe = p0[1]; ! 122: close (p0[0]); ! 123: puttoken (Read); ! 124: puttoken (Write); ! 125: exit (copyloop()); ! 126: ! 127: case -1: /* error */ ! 128: perror ("fork"); ! 129: return 1; ! 130: } ! 131: } ! 132: ! 133: main (argc, argv) ! 134: int argc; ! 135: char **argv; ! 136: { ! 137: int c; ! 138: while ((c = getopt (argc, argv, "b:")) != -1) { ! 139: switch (c) { ! 140: case 'b': ! 141: bufmax = atoi (optarg); ! 142: if (bufmax <= 0) { ! 143: fprintf (stderr, "invalid buffer size\n"); ! 144: exit (1); ! 145: } ! 146: } ! 147: } ! 148: ! 149: if ((buffer = malloc (bufmax)) == NULL) { ! 150: fprintf (stderr, "out of memory\n"); ! 151: exit (1); ! 152: } ! 153: ! 154: if (argc > optind + 1) { ! 155: fprintf (stderr, "only one input file\n"); ! 156: exit (1); ! 157: } ! 158: ! 159: if (argc > optind) { ! 160: infd = open (argv[optind], 0); ! 161: if (infd < 0) { ! 162: perror (argv[optind]); ! 163: exit (1); ! 164: } ! 165: } ! 166: ! 167: signal (SIGPIPE, SIG_IGN); ! 168: return copyfile(); ! 169: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.