Newsgroups: comp.unix.programmer Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!think.com!snorkelwacker.mit.edu!bloom-picayune.mit.edu!athena.mit.edu!jik From: jik@athena.mit.edu (Jonathan I. Kamens) Subject: Re: generate EOF on socketpair? Message-ID: <1991Apr3.220936.25035@athena.mit.edu> Sender: news@athena.mit.edu (News system) Organization: Massachusetts Institute of Technology References: <40164@netnews.upenn.edu> Distribution: na Date: Wed, 3 Apr 91 22:09:36 GMT Lines: 109 In article <40164@netnews.upenn.edu>, rpotter@grip.cis.upenn.edu (Robert Potter) writes: |> My problem: how do I indicate to the program that it has reached EOF on its |> standard input? I can't just close the socket, since I want to keep the socket |> open for reading. Do I have to set up two separate sockets (or pipes)? You could create two pipe()s, one for input to the sub-process and one for output from it, and close the input pipe in the parent when you are done sending input to the child. I'm sure that'll work, and I've done it before. Alternatively, you could use the shutdown(2) system call to shutdown sends on the socket in the parent, to signify that you won't be doing any more writing to it. I'm not sure this'll work. So I guess I'll write a program to test it. First, the pipe version (with most error-checking omitted to conserve space): #include main() { int tochild[2], fromchild[2]; char buf[3]; pipe(tochild); pipe(fromchild); if (! fork()) { /* child */ close(tochild[1]); close(fromchild[0]); dup2(tochild[0], 0); /* over stdin */ dup2(fromchild[1], 1); /* over stdout */ execl("/usr/bin/tr", "tr", "[A-Z]", "[a-z]", 0); fprintf(stderr, "Exec of /usr/bin/tr failed!\n"); exit(1); /* NOTREACHED */ } else { /* parent */ close(tochild[0]); close(fromchild[1]); fputs("Sending ABC\n", stdout); write(tochild[1], "ABC", 3); close(tochild[1]); read(fromchild[0], buf, 3); printf("Received %3s\n", buf); exit(0); } } And here's what happens when I run it: % ./a.out Sending ABC Received abc Now, the socketpair version: #include #include #include main() { int sockets[2]; char buf[3]; socketpair(AF_UNIX, SOCK_STREAM, 0, sockets); if (! fork()) { /* child */ close(sockets[0]); dup2(sockets[1], 0); dup2(sockets[1], 1); execl("/usr/bin/tr", "tr", "[A-Z]", "[a-z]", 0); fprintf(stderr, "Exec of /usr/bin/tr failed!\n"); exit(1); /* NOTREACHED */ } else { /* parent */ close(sockets[1]); fputs("Sending ABC\n", stdout); write(sockets[0], "ABC", 3); shutdown(sockets[0], 1); read(sockets[0], buf, 3); printf("Received %3s\n", buf); exit(0); } } And here's what happens when I run it: % ./a.out Sending ABC And it just stays there until I interrupt it. In other words, it looks to me like the shutdown() *doesn't* work. I can't think of any other way to achieve what you're trying to achive. My recommendation would be to use to pipe()s or socketpair()s. I hope someone can correct me and tell me how to get this to work, because now I'm interested in it :-). -- Jonathan Kamens USnail: MIT Project Athena 11 Ashford Terrace jik@Athena.MIT.EDU Allston, MA 02134 Office: 617-253-8085 Home: 617-782-0710