00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "defs.h"
00022 #include <sys/wait.h>
00023
00024
00025 void pipetest(void)
00026 {
00027 int pfd[2];
00028 ssize_t nread;
00029 char s[100];
00030
00031 ec_neg1( pipe(pfd) )
00032 ec_neg1( write(pfd[1], "hello", 6) )
00033 ec_neg1( nread = read(pfd[0], s, sizeof(s)) )
00034 if (nread == 0)
00035 printf("EOF\n");
00036 else
00037 printf("read %ld bytes: %s\n", (long)nread, s);
00038 return;
00039
00040 EC_CLEANUP_BGN
00041 EC_FLUSH("pipetest");
00042 EC_CLEANUP_END
00043 }
00044
00045
00046
00047 void pipewrite(void)
00048 {
00049 int pfd[2];
00050 char fdstr[10];
00051
00052 ec_neg1( pipe(pfd) )
00053 switch (fork()) {
00054 case -1:
00055 EC_FAIL
00056 case 0:
00057 ec_neg1( close(pfd[1]))
00058 snprintf(fdstr, sizeof(fdstr), "%d", pfd[0]);
00059 execlp("./piperead", "piperead", fdstr, NULL);
00060 EC_FAIL
00061 default:
00062 ec_neg1( close(pfd[0]) )
00063 ec_neg1( write(pfd[1], "hello", 6) )
00064 }
00065 return;
00066
00067 EC_CLEANUP_BGN
00068 EC_FLUSH("pipewrite");
00069 EC_CLEANUP_END
00070 }
00071
00072
00073
00074 void pipewrite2bug(void)
00075 {
00076 int pfd[2];
00077 pid_t pid;
00078
00079 ec_neg1( pipe(pfd) )
00080 switch (pid = fork()) {
00081 case -1:
00082 EC_FAIL
00083 case 0:
00084 ec_neg1( dup2(pfd[0], STDIN_FILENO) )
00085 ec_neg1( close(pfd[0]))
00086 ec_neg1( close(pfd[1]))
00087 execlp("cat", "cat", NULL);
00088 EC_FAIL
00089 default:
00090 ec_neg1( close(pfd[0]) )
00091 ec_neg1( write(pfd[1], "hello", 6) )
00092 ec_neg1( waitpid(pid, NULL, 0) )
00093 }
00094 return;
00095
00096 EC_CLEANUP_BGN
00097 EC_FLUSH("pipewrite2bug");
00098 EC_CLEANUP_END
00099 }
00100
00101
00102
00103 void pipewrite2(void)
00104 {
00105 int pfd[2];
00106 pid_t pid;
00107
00108 ec_neg1( pipe(pfd) )
00109 switch (pid = fork()) {
00110 case -1:
00111 EC_FAIL
00112 case 0:
00113 ec_neg1( dup2(pfd[0], STDIN_FILENO) )
00114 ec_neg1( close(pfd[0]))
00115 ec_neg1( close(pfd[1]))
00116 execlp("cat", "cat", NULL);
00117 EC_FAIL
00118 default:
00119 ec_neg1( close(pfd[0]) )
00120 ec_neg1( write(pfd[1], "hello", 6) )
00121 ec_neg1( close(pfd[1]) )
00122 ec_neg1( waitpid(pid, NULL, 0) )
00123 }
00124 return;
00125
00126 EC_CLEANUP_BGN
00127 EC_FLUSH("pipewrite2");
00128 EC_CLEANUP_END
00129 }
00130
00131
00132
00133 void who_wc(void)
00134 {
00135 int pfd[2];
00136 pid_t pid1, pid2;
00137
00138 ec_neg1( pipe(pfd) )
00139 switch (pid1 = fork()) {
00140 case -1:
00141 EC_FAIL
00142 case 0:
00143 ec_neg1( dup2(pfd[1], STDOUT_FILENO) )
00144 ec_neg1( close(pfd[0]))
00145 ec_neg1( close(pfd[1]))
00146 execlp("who", "who", NULL);
00147 EC_FAIL
00148 }
00149
00150 switch (pid2 = fork()) {
00151 case -1:
00152 EC_FAIL
00153 case 0:
00154 ec_neg1( dup2(pfd[0], STDIN_FILENO) )
00155 ec_neg1( close(pfd[0]))
00156 ec_neg1( close(pfd[1]))
00157 execlp("wc", "wc", "-l", NULL);
00158 EC_FAIL
00159 }
00160
00161 ec_neg1( close(pfd[0]) )
00162 ec_neg1( close(pfd[1]) )
00163 ec_neg1( waitpid(pid1, NULL, 0) )
00164 ec_neg1( waitpid(pid2, NULL, 0) )
00165 return;
00166
00167 EC_CLEANUP_BGN
00168 EC_FLUSH("who_wc");
00169 EC_CLEANUP_END
00170 }
00171
00172
00173
00174 void who_wc2(void)
00175 {
00176 int pfd[2];
00177 pid_t pid1, pid2;
00178
00179 ec_neg1( pipe(pfd) )
00180 switch (pid1 = fork()) {
00181 case -1:
00182 EC_FAIL
00183 case 0:
00184 switch (pid2 = fork()) {
00185 case -1:
00186 EC_FAIL
00187 case 0:
00188 ec_neg1( dup2(pfd[0], STDIN_FILENO) )
00189 ec_neg1( close(pfd[0]))
00190 ec_neg1( close(pfd[1]))
00191 execlp("wc", "wc", "-l", NULL);
00192 EC_FAIL
00193 }
00194
00195 ec_neg1( dup2(pfd[1], STDOUT_FILENO) )
00196 ec_neg1( close(pfd[0]))
00197 ec_neg1( close(pfd[1]))
00198 execlp("who", "who", NULL);
00199 EC_FAIL
00200 }
00201
00202 ec_neg1( close(pfd[0]) )
00203 ec_neg1( close(pfd[1]) )
00204 ec_neg1( waitpid(pid1, NULL, 0) )
00205 return;
00206
00207 EC_CLEANUP_BGN
00208 EC_FLUSH("who_wc2");
00209 EC_CLEANUP_END
00210 }
00211
00212
00213
00214 void fsort0(void)
00215 {
00216 int pfd[2], fd;
00217 ssize_t nread;
00218 pid_t pid;
00219 char buf[512];
00220
00221 ec_neg1( pipe(pfd) )
00222 ec_neg1( pid = fork() )
00223 if (pid == 0) {
00224 ec_neg1( dup2(pfd[0], STDIN_FILENO) )
00225 ec_neg1( close(pfd[0]) )
00226 ec_neg1( dup2(pfd[1], STDOUT_FILENO) )
00227 ec_neg1( close(pfd[1]) )
00228 execlp("sort", "sort", NULL);
00229 EC_FAIL
00230 }
00231
00232 ec_neg1( fd = open("datafile", O_RDONLY) )
00233 while (true) {
00234 ec_neg1( nread = read(fd, buf, sizeof(buf)) )
00235 if (nread == 0)
00236 break;
00237 ec_neg1( write(pfd[1], buf, nread) )
00238 }
00239 ec_neg1( close(fd) )
00240 ec_neg1( close(pfd[1]) )
00241 while (true) {
00242 ec_neg1( nread = read(pfd[0], buf, sizeof(buf)) )
00243 if (nread == 0)
00244 break;
00245 ec_neg1( write(STDOUT_FILENO, buf, nread) )
00246 }
00247 ec_neg1( close(pfd[0]) )
00248 ec_neg1( waitpid(pid, NULL, 0) )
00249 return;
00250
00251 EC_CLEANUP_BGN
00252 EC_FLUSH("fsort0");
00253 EC_CLEANUP_END
00254 }
00255
00256
00257
00258 void fsort(void)
00259 {
00260 int pfdout[2], pfdin[2], fd;
00261 ssize_t nread;
00262 pid_t pid;
00263 char buf[512];
00264
00265 ec_neg1( pipe(pfdout) )
00266 ec_neg1( pipe(pfdin) )
00267 ec_neg1( pid = fork() )
00268 if (pid == 0) {
00269 ec_neg1( dup2(pfdout[0], STDIN_FILENO) )
00270 ec_neg1( close(pfdout[0]) )
00271 ec_neg1( close(pfdout[1]) )
00272 ec_neg1( dup2(pfdin[1], STDOUT_FILENO) )
00273 ec_neg1( close(pfdin[0]) )
00274 ec_neg1( close(pfdin[1]) )
00275 execlp("sort", "sort", NULL);
00276 EC_FAIL
00277 }
00278
00279 ec_neg1( close(pfdout[0]) )
00280 ec_neg1( close(pfdin[1]) )
00281 ec_neg1( fd = open("datafile", O_RDONLY) )
00282 while (true) {
00283 ec_neg1( nread = read(fd, buf, sizeof(buf)) )
00284 if (nread == 0)
00285 break;
00286 ec_neg1( write(pfdout[1], buf, nread) )
00287 }
00288 ec_neg1( close(fd) )
00289 ec_neg1( close(pfdout[1]) )
00290 while (true) {
00291 ec_neg1( nread = read(pfdin[0], buf, sizeof(buf)) )
00292 if (nread == 0)
00293 break;
00294 ec_neg1( write(STDOUT_FILENO, buf, nread) )
00295 }
00296 ec_neg1( close(pfdin[0]) )
00297 ec_neg1( waitpid(pid, NULL, 0) )
00298 return;
00299
00300 EC_CLEANUP_BGN
00301 EC_FLUSH("fsort");
00302 EC_CLEANUP_END
00303 }
00304
00305
00306 static void fpathconf_test(void)
00307 {
00308
00309 int pfd[2];
00310 long v;
00311
00312 ec_neg1( pipe(pfd) )
00313 errno = 0;
00314 v = fpathconf(pfd[0], _PC_PIPE_BUF);
00315 if (errno != 0)
00316 EC_FAIL
00317 else if (v == -1)
00318 printf("No limit for PIPE_BUF\n");
00319 else
00320 printf("PIPE_BUF = %ld\n", v);
00321
00322 return;
00323
00324 EC_CLEANUP_BGN
00325 EC_FLUSH("fpathconf_test")
00326 EC_CLEANUP_END
00327 }
00328
00329 void pipe_access_mode(void)
00330 {
00331 int pfd[2], flags, i;
00332
00333 ec_neg1( pipe(pfd) )
00334 for (i = 0; i < 2; i++) {
00335 ec_neg1( flags = fcntl(pfd[i], F_GETFL) )
00336 if ((flags & O_ACCMODE) == O_RDONLY)
00337 printf("pfd[%d] O_RDONLY\n", i);
00338 if ((flags & O_ACCMODE) == O_WRONLY)
00339 printf("pfd[%d] O_WRONLY\n", i);
00340 if ((flags & O_ACCMODE) == O_RDWR)
00341 printf("pfd[%d] O_RDWR\n", i);
00342 }
00343 return;
00344
00345 EC_CLEANUP_BGN
00346 EC_FLUSH("pipe_access_mode")
00347 EC_CLEANUP_END
00348 }
00349
00350
00351 int main(void)
00352 {
00353 char buf[10];
00354
00355 while (true) {
00356 printf("Choose example to run:\n");
00357 printf("\t1: pipetest\n");
00358 printf("\t2: pipewrite\n");
00359 printf("\t3: pipewrite2bug (hangs)\n");
00360 printf("\t4: pipewrite2\n");
00361 printf("\t5: who_wc\n");
00362 printf("\t6: who_wc2\n");
00363 printf("\t7: fsort0 (wrong)\n");
00364 printf("\t8: fsort\n");
00365 printf("\t9: fpathconf\n");
00366 printf("\ta: pipe_access_mode\n");
00367 printf("\tp: ps\n");
00368 printf("\tq: quit\n");
00369 printf("\nChoice? ");
00370
00371 if (fgets(buf, sizeof(buf), stdin) != NULL)
00372 switch (buf[0]) {
00373 case '1':
00374 pipetest();
00375 continue;
00376 case '2':
00377 pipewrite();
00378 continue;
00379 case '3':
00380 pipewrite2bug();
00381 continue;
00382 case '4':
00383 pipewrite2();
00384 continue;
00385 case '5':
00386 who_wc();
00387 continue;
00388 case '6':
00389 who_wc2();
00390 continue;
00391 case '7':
00392 fsort0();
00393 continue;
00394 case '8':
00395 fsort();
00396 continue;
00397 case '9':
00398 fpathconf_test();
00399 continue;
00400 case 'a':
00401 pipe_access_mode();
00402 continue;
00403 case 'p':
00404 system("ps");
00405 continue;
00406 case 'q':
00407 break;
00408 default:
00409 printf("Invalid response\n");
00410 continue;
00411 }
00412 break;
00413 }
00414 exit(EXIT_SUCCESS);
00415 }