Christian Biere
2006-11-01 05:22:54 UTC
Hi,
the following program does not terminate i.e., recv() never returns although
the child exits thus closing the other side of the socket pair.
#include <sys/socket.h>
#include <stdlib.h>
#include <unistd.h>
#include <err.h>
int
main(void)
{
int fd_pair[2] = { -1, -1 };
pid_t pid;
if (-1 == socketpair(AF_LOCAL, SOCK_DGRAM, 0, fd_pair))
err(EXIT_FAILURE, "socketpair");
pid = fork();
if ((pid_t) -1 == pid)
err(EXIT_FAILURE, "fork");
if (0 == pid) {
close(fd_pair[0]);
_exit(EXIT_SUCCESS);
} else {
char c;
close(fd_pair[1]);
recv(fd_pair[0], &c, sizeof c, 0);
}
return EXIT_SUCCESS;
}
For what it's worth, on FreeBSD the program terminates, on Linux recv() doesn't
return either. What's also interesting is that with some minor variations both
processes actually terminate on NetBSD as well as Linux. For example, if I
replace '0 == pid' with '0 != pid', or if I insert "poll(NULL, 0, 1000);"
before recv().
The following fixes the problem here so that recv() returns with ECONNRESET. Are
there any objections or may I commit this?
Index: uipc_usrreq.c
===================================================================
RCS file: /cvsroot/src/sys/kern/uipc_usrreq.c,v
retrieving revision 1.93
diff -u -p -r1.93 uipc_usrreq.c
--- uipc_usrreq.c 3 Sep 2006 21:15:29 -0000 1.93
+++ uipc_usrreq.c 1 Nov 2006 04:14:26 -0000
@@ -799,7 +800,7 @@ unp_disconnect(struct unpcb *unp)
unp2->unp_nextref = unp->unp_nextref;
}
unp->unp_nextref = 0;
- unp->unp_socket->so_state &= ~SS_ISCONNECTED;
+ soisdisconnected(unp->unp_socket);
break;
case SOCK_STREAM:
the following program does not terminate i.e., recv() never returns although
the child exits thus closing the other side of the socket pair.
#include <sys/socket.h>
#include <stdlib.h>
#include <unistd.h>
#include <err.h>
int
main(void)
{
int fd_pair[2] = { -1, -1 };
pid_t pid;
if (-1 == socketpair(AF_LOCAL, SOCK_DGRAM, 0, fd_pair))
err(EXIT_FAILURE, "socketpair");
pid = fork();
if ((pid_t) -1 == pid)
err(EXIT_FAILURE, "fork");
if (0 == pid) {
close(fd_pair[0]);
_exit(EXIT_SUCCESS);
} else {
char c;
close(fd_pair[1]);
recv(fd_pair[0], &c, sizeof c, 0);
}
return EXIT_SUCCESS;
}
For what it's worth, on FreeBSD the program terminates, on Linux recv() doesn't
return either. What's also interesting is that with some minor variations both
processes actually terminate on NetBSD as well as Linux. For example, if I
replace '0 == pid' with '0 != pid', or if I insert "poll(NULL, 0, 1000);"
before recv().
The following fixes the problem here so that recv() returns with ECONNRESET. Are
there any objections or may I commit this?
Index: uipc_usrreq.c
===================================================================
RCS file: /cvsroot/src/sys/kern/uipc_usrreq.c,v
retrieving revision 1.93
diff -u -p -r1.93 uipc_usrreq.c
--- uipc_usrreq.c 3 Sep 2006 21:15:29 -0000 1.93
+++ uipc_usrreq.c 1 Nov 2006 04:14:26 -0000
@@ -799,7 +800,7 @@ unp_disconnect(struct unpcb *unp)
unp2->unp_nextref = unp->unp_nextref;
}
unp->unp_nextref = 0;
- unp->unp_socket->so_state &= ~SS_ISCONNECTED;
+ soisdisconnected(unp->unp_socket);
break;
case SOCK_STREAM:
--
Christian
--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Christian
--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de