chiark / gitweb /
Do not assume that loop->on_fd is idempotent
[inn-innduct.git] / backends / innduct.c
index 6e9dd262dbfd5bd4c573dc5b3c858df6fb949a91..29fe5c10ccdfe294d445269648900fc6edf673df 100644 (file)
@@ -365,7 +365,7 @@ static oop_rd_call peer_rd_err, peer_rd_ok;
 static const char *sitename, *remote_host;
 static const char *feedfile, *path_run, *path_cli, *path_cli_dir;
 static int quiet_multiple=0;
-static int become_daemon=1, try_filemon=1;
+static int interactive=0, try_filemon=1;
 static int try_stream=1;
 static int port=119;
 static const char *inndconffile;
@@ -373,7 +373,7 @@ static const char *inndconffile;
 static int max_connections=10;
 static int max_queue_per_conn=200;
 static int target_max_feedfile_size=100000;
-static int period_seconds=60;
+static int period_seconds=30;
 static int filepoll_seconds=5;
 static int max_queue_per_ipf=-1;
 
@@ -511,6 +511,7 @@ struct Conn {
   ISNODE(Conn);
   int fd; /* may be 0, meaning closed (during construction/destruction) */
   oop_read *rd; /* likewise */
+  int oopwriting; /* since on_fd is not idempotent */
   int max_queue, stream;
   const char *quitting;
   int since_activity; /* periods */
@@ -554,7 +555,7 @@ int simulate_flush= -1;
 static void logcore(int sysloglevel, const char *fmt, ...) PRINTF(2,3);
 static void logcore(int sysloglevel, const char *fmt, ...) {
   VA;
-  if (become_daemon) {
+  if (interactive < 2) {
     vsyslog(sysloglevel,fmt,al);
   } else {
     if (self_pid) fprintf(stderr,"[%lu] ",(unsigned long)self_pid);
@@ -1547,12 +1548,16 @@ static void conn_maybe_write(Conn *conn)  {
     conn_make_some_xmits(conn);
     if (!conn->xmitu) {
       loop->cancel_fd(loop, conn->fd, OOP_WRITE);
+      conn->oopwriting= 0;
       return;
     }
 
     void *rp= conn_write_some_xmits(conn);
     if (rp==OOP_CONTINUE) {
-      loop->on_fd(loop, conn->fd, OOP_WRITE, conn_writeable, conn);
+      if (!conn->oopwriting) {
+       loop->on_fd(loop, conn->fd, OOP_WRITE, conn_writeable, conn);
+       conn->oopwriting= 1;
+      }
       return;
     } else if (rp==OOP_HALT) {
       return;
@@ -3481,7 +3486,7 @@ static void vbadusage(const char *fmt, va_list al) {
   fprintf(stderr, "bad usage: %s\n"
          "say --help for help, or read the manpage\n",
          m);
-  if (become_daemon)
+  if (interactive < 2)
     syslog(LOG_CRIT,"innduct: invoked with bad usage: %s",m);
   exit(8);
 }
@@ -3641,7 +3646,8 @@ static void help(const Option *o, const char *val);
 static const Option innduct_options[]= {
 {'f',"feedfile",         "F",     &feedfile,                 op_string      },
 {'q',"quiet-multiple",   0,       &quiet_multiple,           op_setint, 1   },
-{0,"no-daemon",          0,       &become_daemon,            op_setint, 0   },
+{0,"no-daemon",          0,       &interactive,              op_setint, 1   },
+{0,"interactive",        0,       &interactive,              op_setint, 2   },
 {0,"no-streaming",       0,       &try_stream,               op_setint, 0   },
 {0,"no-filemon",         0,       &try_filemon,              op_setint, 0   },
 {'C',"inndconf",         "F",     &inndconffile,             op_string      },
@@ -3802,13 +3808,17 @@ int main(int argc, char **argv) {
 
   LIST_INIT(conns);
 
-  if (become_daemon) {
+  if (interactive < 1) {
     int i;
     for (i=3; i<255; i++)
       /* do this now before we open syslog, etc. */
       close(i);
+  }
+
+  if (interactive < 2)
     openlog("innduct",LOG_NDELAY|LOG_PID,LOG_NEWS);
 
+  if (interactive < 1) {
     int null= open("/dev/null",O_RDWR);
     if (null<0) sysfatal("failed to open /dev/null");
     dup2(null,0);
@@ -3842,7 +3852,7 @@ int main(int argc, char **argv) {
   r= SMsetup(SM_PREOPEN, &val); if (!r) warn("SMsetup SM_PREOPEN failed");
   r= SMinit(); if (!r) die("storage manager initialisation (SMinit) failed");
 
-  if (!become_daemon)
+  if (interactive >= 2)
     cli_stdio();
 
   cli_init();