generate EOF on socketpair?

Jonathan I. Kamens jik at athena.mit.edu
Thu Apr 4 08:09:36 AEST 1991


In article <40164 at netnews.upenn.edu>, rpotter at 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 <stdio.h>

	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 <stdio.h>
	#include <sys/types.h>
	#include <sys/socket.h>

	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 at Athena.MIT.EDU				Allston, MA  02134
Office: 617-253-8085			      Home: 617-782-0710



More information about the Comp.unix.programmer mailing list