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;
}
alarm(connection_setup_timeout);
if (NNTPconnect((char*)remote_host, port, &cn_from, &cn_to, buf) < 0) {
- if (buf[0]) fatal("connect: rejected: %s", sanitise(buf));
- else sysfatal("connect: connection attempt failed");
+ int l= strlen(buf);
+ int stripped=0;
+ while (l>0) {
+ unsigned char c= buf[l-1];
+ if (!isspace(c)) break;
+ if (c=='\n' || c=='\r') stripped=1;
+ --l;
+ }
+ if (!buf[0]) {
+ sysfatal("connect: connection attempt failed");
+ } else {
+ buf[l]= 0;
+ fatal("connect: %s: %s", stripped ? "rejected" : "failed",
+ sanitise(buf));
+ }
}
if (NNTPsendpassword((char*)remote_host, cn_from, cn_to) < 0)
sysfatal("connect: authentication failed");
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);
}
{'q',"quiet-multiple", 0, &quiet_multiple, op_setint, 1 },
{0,"no-daemon", 0, &become_daemon, op_setint, 0 },
{0,"no-streaming", 0, &try_stream, op_setint, 0 },
-{0,"inndconf", "F", &inndconffile, op_string },
+{'C',"inndconf", "F", &inndconffile, op_string },
{'P',"port", "PORT", &port, op_integer },
{0,"help", 0, 0, help },
/* defaults */
+ int r= innconf_read(inndconffile);
+ if (!r) badusage("could not read inn.conf (more info on stderr)");
+
if (!remote_host) remote_host= sitename;
if (nocheck_thresh < 0 || nocheck_thresh > 100)
max_bad_data_ratio *= 0.01;
if (!feedfile) {
- innconf_read(inndconffile);
feedfile= xasprintf("%s/%s",innconf->pathoutgoing,sitename);
} else if (!feedfile[0]) {
badusage("feed filename must be nonempty");
/* let's go */
- void *r= oop_sys_run(sysloop);
- assert(r == OOP_ERROR);
+ void *run= oop_sys_run(sysloop);
+ assert(run == OOP_ERROR);
sysdie("event loop failed");
}