Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!sdd.hp.com!usc!apple!altos!megadon!clp From: steve@altos86.Altos.COM (Steve Scherf) Newsgroups: comp.unix Subject: Re: PIPES Message-ID: <2281@megadon.UUCP> Date: 27 Nov 90 23:49:36 GMT References: <2274@megadon.UUCP> Sender: clp@megadon.UUCP Reply-To: steve@altos.com (Steve Scherf) Organization: Altos Computer Systems, San Jose, CA Lines: 110 Approved: clp@megadon.UUCP In article <2274@megadon.UUCP> akrishn@csserv2.ic.sunysb.edu (Arvind Krishnan) writes: >two pipes for full duplex communications with its child (mailx). > > 1. stdout of the child is the stdin of the parent and > 2. stdout of the parent is the stdin of the child > >For some unknown reason, '1' works but '2' doesn't. The parent process can >read the output of its child, but the child doesn't seem to be reading the >output of the parent process. Your pipes seem set up properly, but I do have a few comments about how you do it. I also have a few questions about your interesting while loop. > if (fork() == 0) > { This close() is unnecessary since dup2() closes the descriptor. > close(0); > dup2(to_child[0], 0); Ditto. > close(1); > dup2(to_par[1], 1); > close(to_par[1]); > close(to_child[0]); > close(to_par[0]); > close(to_child[1]); The below if() is unnecessary, since execl() will only return on error. > if (execl("/usr/bin/mailx", "mailx", (char *) 0)) > fprintf(stderr,"Exec Error\n"); An exit() here would be nice. > } ... And here's that while loop: > fcntl(0, F_SETFL, O_NDELAY); > while (1) > { > if (flag == 0) Just say no to busy-waits. This is bogus on a multiuser system. > while ((flag = read(0,buf,1)) == 0); And just what does ^^ (flag) do here? flag just gets reset below anyway. > write(2,buf,1); What's this read() all about? > flag = read(0,buf,1); Huh? > if (flag == 0) > write(1, command, 1); > } >} Your while loop seems to be written in such a way that you might end up spinning in that busy-wait forever. It is also possible that you might never actually write to the child. You are playing around with time-dependent factors in a bad way. If your system has select(), you might look it up. I would suggest scanning for the mailx input prompt, but it seems to suppress printing it when input is not a tty. Also, you seem to throw away every other byte that you get from the child. Actually, I'm exactly not sure what you're trying to do. Below is a version which might do what you want. You would also probably want to write a signal handler for SIGCLD and SIGPIPE, in addition. It is rough and untested, but should hopefully give you a hint. readmail() { char buf[100]; int p2c[2], c2p[2], c; pipe(p2c); pipe(c2p); if((c = fork()) < 0) return -1; if(c) { /* parent */ dup2(p2c[1], 1); dup2(c2p[0], 0); } else { /* child */ dup2(c2p[1], 1); dup2(p2c[0], 0); } close(p2c[0]); close(p2c[1]); close(c2p[0]); close(c2p[1]); if(!c) { execl("/usr/bin/mailx", "mailx", 0); exit(1); } /* talk to child */ write(1, "1\nx\n", 4); /* tell it to print mail, then quit */ /* listen to child */ for(;;) { if((c = read(0, buf, 100)) <= 0) return c; write(2, buf, c); } } Hope this helps. -- Steve Scherf steve@Altos.COM ...!{sun|sco|pyramid|amdahl|uunet}!altos!steve These opinions are solely mine, but others may share them if they like.