Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!batcomputer!munnari.oz.au!comp.vuw.ac.nz!ajv From: Andrew.Vignaux@comp.vuw.ac.nz (Andrew Vignaux) Newsgroups: comp.unix.programmer Subject: Can you partially shutdown() a UNIX domain socket? Keywords: socket, shutdown, AF_UNIX Message-ID: <1991Apr02.101330.22133@comp.vuw.ac.nz> Date: 2 Apr 91 10:13:30 GMT Sender: news@comp.vuw.ac.nz (News Admin) Organization: Comp Sci, Victoria University, Wellington, New Zealand. Lines: 138 Nntp-Posting-Host: downstage.comp.vuw.ac.nz Can I shutdown(,1) an AF_UNIX socket so that it propagates the "end-of-file" indication to the other end? I seem to be able to do this with AF_INET sockets. Am I asking too much from shutdown()? I have tried the following program under MORE/bsd on our hp300s, HPUX 7.0 on 9000/{8,3}00, SunOS 4.1, and AIX 3.1. The program compiled with -DINET gets a 0 read in the child after shutdown() is called in the parent, the -UINET program doesn't. BTW: my original 4-fd select() loop in the parent has been simplified (too much?) into a synchronised for(;;) loop. Should I just use pipe()s? My real program talks to a remote server using INET sockets but occasionally I want to fire up a local program and talk to that. If I can get the shutdown() to work I can use the same processing loop because everyone's a socket. Actually, my real program is in perl and I've already rewritten it using pipes ;-) Andrew -- Domain address: Andrew.Vignaux@comp.vuw.ac.nz ------------------------------------------------------------------------------- #include #include #include #ifndef INET # include # define NAME "socket" #else # include #endif #define DATA1 "In Xanadu, did Kublai Khan . . ." #define DATA2 "A stately pleasure dome decree . . ." #define DATA3 "And now for something completely different . . ." int main() { int family; int s, child; int sockets[2]; char buf[1024]; #ifndef INET struct sockaddr_un addr; #else int l; struct sockaddr_in addr; #endif #ifndef INET addr.sun_family = family = AF_UNIX; strcpy (addr.sun_path, NAME); #else addr.sin_family = family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = 0; #endif if ((s = socket(family, SOCK_STREAM, 0)) < 0) { perror("master: socket"); exit(1); } if (bind(s, &addr, sizeof(addr)) < 0) { perror("master: bind"); exit(1); } #ifdef INET l = sizeof(addr); if (getsockname(s, &addr, &l)) { perror("master: getsockname"); exit(1); } #endif listen (s, 5); setbuf (stdout, (char *)NULL); if ((child = fork()) == -1) perror("fork"); else if (child == 0) { /* This is the child. */ int r; if ((sockets[1] = accept(s, (struct sockaddr *)0, (int *)0)) < 0) { perror("child: accept"); exit(1); } #ifndef INET if (unlink (addr.sun_path) < 0) perror ("child: unlink"); #endif while (1) { r = read(sockets[1], buf, 1024); if (r < 0) { perror("child: read"); exit (1); } else if (r == 0) { (void) fprintf (stderr, "\n"); break; } (void) printf("%d==>%.*s\n", r, r, buf); if (write(sockets[1], DATA2, sizeof(DATA2)) < 0) perror("child: write"); } if (write(sockets[1], DATA3, sizeof(DATA3)) < 0) perror("child: end write"); if (close(sockets[1]) < 0) perror("child: close"); } else { /* This is the parent. */ int i, r; if ((sockets[0] = socket(family, SOCK_STREAM, 0)) < 0) { perror("parent: socket"); exit(1); } if (connect (sockets[0], &addr, sizeof(addr)) < 0) { perror("parent: connect"); exit(1); } for (i = 0; i < 5; i++) { if (write(sockets[0], DATA1, sizeof(DATA1)) < 0) perror("parent: write"); if ((r = read(sockets[0], buf, 1024)) < 0) perror("parent: read"); (void) printf("%d-->%.*s\n", r, r, buf); } if (shutdown(sockets[0], 1) < 0) perror("parent: shutdown"); if ((r = read(sockets[0], buf, 1024)) < 0) perror("parent: end read"); (void) printf("%d**>%.*s\n", r, r, buf); if (close(sockets[0]) < 0) perror("parent: close"); } return 0; }