int count; \
} T##List
-#define NODE(n) (assert((void*)&(n)->list_node == &(n)), &(n)->list_node)
+#define NODE(n) (assert((void*)&(n)->list_node == (n)), &(n)->list_node)
#define LIST_CHECKCANHAVENODE(l,n) \
((void)((n) == ((l).u.for_type))) /* just for the type check */
int r= kill(*pid, SIGKILL);
if (r) sysdie("cannot kill %s child", what);
- pid_t got= waitpid(*pid, &status, WNOHANG);
+ pid_t got= waitpid(*pid, &status, 0);
if (got==-1) sysdie("cannot reap %s child", what);
+ if (got==0) die("cannot reap %s child", what);
*pid= 0;
static void connect_attempt_discard(void) {
if (connecting_child) {
- int r= kill(connecting_child, SIGTERM);
- if (r) syswarn("failed to kill connecting child");
int status= xwaitpid(&connecting_child, "connect");
-
if (!(WIFEXITED(status) ||
(WIFSIGNALED(status) && WTERMSIG(status) == SIGKILL)))
report_child_status("connect", status);
Conn *conn= 0;
assert(fd == connecting_fdpass_sock);
+ PREP_DECL_MSG_CMSG(msg);
+ ssize_t rs= recvmsg(fd, &msg, 0);
+ if (rs<0) {
+ if (isewouldblock(errno)) return OOP_CONTINUE;
+ syswarn("failed to read socket from connecting child");
+ goto x;
+ }
conn= xmalloc(sizeof(*conn));
memset(conn,0,sizeof(*conn));
- PREP_DECL_MSG_CMSG(msg);
struct cmsghdr *h= 0;
- ssize_t rs= recvmsg(fd, &msg, MSG_DONTWAIT);
if (rs >= 0) h= CMSG_FIRSTHDR(&msg);
if (!h) {
- int status;
- pid_t got= waitpid(connecting_child, &status, WNOHANG);
- if (got != -1) {
- assert(got==connecting_child);
- connecting_child= 0;
- if (WIFEXITED(status)) {
- if (WEXITSTATUS(status) != 0 &&
- WEXITSTATUS(status) != CONNCHILD_ESTATUS_STREAM &&
- WEXITSTATUS(status) != CONNCHILD_ESTATUS_NOSTREAM)
- /* child already reported the problem */;
- else
- warn("connect: connection child exited code %d but no cmsg",
+ int status= xwaitpid(&connecting_child, "connect child (broken)");
+
+ if (WIFEXITED(status)) {
+ if (WEXITSTATUS(status) != 0 &&
+ WEXITSTATUS(status) != CONNCHILD_ESTATUS_STREAM &&
+ WEXITSTATUS(status) != CONNCHILD_ESTATUS_NOSTREAM)
+ /* child already reported the problem */;
+ else {
+ if (e == OOP_EXCEPTION)
+ warn("connect: connection child exited code %d but"
+ " unexpected exception on fdpass socket",
WEXITSTATUS(status));
- } else if (WIFSIGNALED(status) && WTERMSIG(status) == SIGALRM) {
- warn("connect: connection attempt timed out");
- } else {
- report_child_status("connect", status);
+ else
+ warn("connect: connection child exited code %d but"
+ " no cmsg (rs=%d)",
+ WEXITSTATUS(status), (int)rs);
}
+ } else if (WIFSIGNALED(status) && WTERMSIG(status) == SIGALRM) {
+ warn("connect: connection attempt timed out");
} else {
- /* child is still running apparently, report the socket problem */
- if (rs < 0)
- syswarn("connect: read from fdpass socket failed");
- else if (e == OOP_EXCEPTION)
- warn("connect: unexpected exception on fdpass socket");
- else if (!rs)
- warn("connect: unexpected EOF on fdpass socket");
- else
- fatal("connect: unexpected lack of cmsg from child");
+ report_child_status("connect", status);
}
goto x;
}
xclose(socks[1], "connecting fdpass child's socket",0);
connecting_fdpass_sock= socks[0];
+ xsetnonblock(connecting_fdpass_sock, 1);
on_fd_read_except(connecting_fdpass_sock, connchild_event);
}