dale@mddc.UUCP (Dale Anglin) (07/17/84)
[] I have a need to read the "who" list into a program buffer. I wrote a test program to verify that it would work. The output of the following program is as expected except that the program seems to hang up in the "read" call. CRT dialog... % cc tst.c -o tst % tst about to read who chris ttyj5 Jul 17 08:15 dale ttyj3 Jul 17 08:31 ... at this point, "tst" does not return to the shell. It can be ^Z'd and ^C'd, but does not terminate as expected. file tst.c cut here ----------------------------------------------- /* *-- Why doesn't this work ??? * * Program is supposed to execute and read the "who" processor output */ main() { int pipefd[2]; int pid; int chkpid; char buffer[100]; pipe(pipefd); switch(pid=fork()) { case -1: /* error */ printf("could not fork\n"); exit(0); case 0: /* child */ close(1); dup(pipefd[1]); printf("about to exec who\n"); execlp("/bin/who", "who", (char*)0); printf("could not execute\n"); exit(0); default: /* parent */ close(0); dup(pipefd[0]); printf("about to read who\n"); while (read(0,buffer,1) == 1) { putchar(buffer[0]); } printf("after who output\n"); while ((chkpid = wait(0)) != pid && chkpid > 0) /* null */; } printf("about to exit\n"); exit(0); } end of file tst.c cut here ---------------------------------------- I was hoping the "read" statement would EOF on the pipe. Any ideas ? Thanks in advance. Dale Anglin Management Decisions Development Corp. 7209 Dixie Highway Fairfield, Ohio 45014 (513) 874-6464 ...{ucbvax,decvax,inhp4,mhuxi}!cbosgd!mddc!dale (uucp)
brad@bradley.UUCP (07/18/84)
#R:mddc:-34200:bradley:400006:000:1348 bradley!brad Jul 18 08:40:00 1984 Below is the mod's I made to the program, the reason it didn't work was that you had dup'ed a file descr. This now leaves two file descr. going to the same place. When you forked you needed to close them after the dupes. I am not sure you need to close both sides but I generally do just to be safe. Bradley Smith {ihnp4,cepu,uiucdcs,noao}!bradley!brad Bradley University Text Processing ----------------------- 1,.d here -------------------------------- /* *-- Why doesn't this work ??? * * Program is supposed to execute and read the "who" processor output */ main() { int pipefd[2]; int pid; int chkpid; char buffer[100]; pipe(pipefd); switch(pid=fork()) { case -1: /* error */ printf("could not fork\n"); exit(0); case 0: /* child */ close(1); close(pipefd[0]); dup(pipefd[1]); close(pipefd[1]); printf("about to exec who\n"); execl("/bin/who", "who", (char*)0); printf("could not execute\n"); exit(0); default: /* parent */ close(0); close(pipefd[1]); dup(pipefd[0]); close(pipefd[0]); printf("about to read who\n"); while (read(0,buffer,1) == 1) { putchar(buffer[0]); } printf("after who output\n"); while ((chkpid = wait(0)) != pid && chkpid > 0) /* null */; } printf("about to exit\n"); exit(0); }
toby@gargoyle.UChicago.UUCP (Toby Harness) (07/18/84)
(sorry, but I can`t seem to reply) Well, you didn`t close the 'unused' sides of the pipe. pipe(pipefd); switch(pid=fork()) ... case 0: /* child */ ========> close(pipefd[0]); /* not necessary, just good practice */ close(1); dup(pipefd[1]); printf("about to exec who\n"); execlp("/bin/who", "who", (char*)0); printf("could not execute\n"); exit(0); default: /* parent */ ========> close (pipefd[1]); /* necessary */ close(0); dup(pipefd[0]); ... Toby Harness Ogburn/Stouffer Center, University of Chicago ...ihnp4!gargoyle!toby
steiny@scc.UUCP (Don Steiny) (07/19/84)
**** When a program is reading from a pipe it does not read an EOF until the write end of the pipe is closed. When one forks a process, closes standard output and makes file descriptor 1 the write end of the pipe, file discriptor 1 is sill open in the parent. The problem program keeps writing to 1 in the parent, so 1 is never closed, the read inside the fork never reads an EOF and the program hangs. The following modifications will make it work: diff tst.c new.c --------------------------------- 5a6 > # include <stdio.h> 26c27,29 < printf("about to exec who\n"); --- > close(0); > close(pipefd[0]); > fprintf(stderr,"about to exec who\n"); 28c31 < printf("could not execute\n"); --- > fprintf(stderr,"could not execute\n"); 33a37,38 > close(1); > close(pipefd[1]); 34a40 > 38c44 < putchar(buffer[0]); --- > putc(buffer[0],stderr); ------------------------- Don Steiny Personetics 109 Torrey Pine Terr. Santa Cruz, Calif. 95060 (408) 425-0382 ucbvax!hplabs!pesnta!scc!steiny harpo!fortune!idsvax!scc!steiny