00001 /* 00002 Miscellaneous examples for Chap. 6 00003 AUP2, Chap. 6 00004 00005 Copyright 2003 by Marc J. Rochkind. All rights reserved. 00006 May be copied only for purposes and under conditions described 00007 on the Web page www.basepath.com/aup/copyright.htm. 00008 00009 The Example Files are provided "as is," without any warranty; 00010 without even the implied warranty of merchantability or fitness 00011 for a particular purpose. The author and his publisher are not 00012 responsible for any damages, direct or incidental, resulting 00013 from the use or non-use of these Example Files. 00014 00015 The Example Files may contain defects, and some contain deliberate 00016 coding mistakes that were included for educational reasons. 00017 You are responsible for determining if and how the Example Files 00018 are to be used. 00019 00020 */ 00021 #include "defs.h" 00022 #include <sys/wait.h> 00023 00024 /*[pipetest]*/ 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 /*[pipewrite]*/ 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: /* child */ 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: /* parent */ 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 /*[pipewrite2bug]*/ 00074 void pipewrite2bug(void) /* has a bug */ 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: /* child */ 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: /* parent */ 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 /*[pipewrite2]*/ 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: /* child */ 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: /* parent */ 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 /*[who_wc]*/ 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: /* first child */ 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 /* parent */ 00150 switch (pid2 = fork()) { 00151 case -1: 00152 EC_FAIL 00153 case 0: /* second child */ 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 /* still the parent */ 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 /*[who_wc2]*/ 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: /* child */ 00184 switch (pid2 = fork()) { 00185 case -1: 00186 EC_FAIL 00187 case 0: /* grandchild */ 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 /* still the child */ 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 /* parent */ 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 /*[fsort0]*/ 00214 void fsort0(void) /* wrong */ 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) { /* child */ 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 /* parent */ 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 /*[fsort]*/ 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) { /* child */ 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 /* parent */ 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 /*[fpathconf_test]*/ 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 /*[pipe_access_mode]*/ 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 }