©2004 by Marc J. Rochkind. All rights reserved. Portions marked "Open Source" may be copied under license.

 

Main Page   Modules   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

c6/x6.c

Go to the documentation of this file.
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 }

Generated on Fri Apr 23 10:56:58 2004 for AUP2 Example Source by doxygen 1.3.1