X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?a=blobdiff_plain;f=backends%2Finnduct.c;h=b6984eaeb89cea752c54c0264e143bb174bb1f18;hb=03afab2d8ef7b2f62424cf96192d378ca15e8ad4;hp=7557b0f694ed6863c53f3fffdf4de230a638b3ca;hpb=2b227ef223abbe8dc57abd6509490f73cdc48755;p=inn-innduct.git diff --git a/backends/innduct.c b/backends/innduct.c index 7557b0f..b6984ea 100644 --- a/backends/innduct.c +++ b/backends/innduct.c @@ -343,7 +343,7 @@ static void inputfile_reading_resume(InputFile *ipf); static void filemon_start(InputFile *ipf); static void filemon_stop(InputFile *ipf); -static void filemon_callback(InputFile *ipf); +static void tailing_make_readable(InputFile *ipf); static void vconnfail(Conn *conn, const char *fmt, va_list al) PRINTF(2,0); static void connfail(Conn *conn, const char *fmt, ...) PRINTF(2,3); @@ -356,7 +356,7 @@ static oop_rd_call peer_rd_err, peer_rd_ok; /* when changing defaults, remember to update the manpage */ static const char *sitename, *remote_host; -static const char *feedfile, *path_cli, *path_cli_dir; +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 try_stream=1; @@ -457,7 +457,7 @@ struct InputFile { oop_read *rd; /* non-0: reading; 0: constructing, or had EOF */ off_t offset; - int skippinglong, paused; + int skippinglong, paused, fake_readable; ArticleList queue; long inprogress; /* includes queue.count and also articles in conns */ @@ -1117,7 +1117,7 @@ static void vconnfail(Conn *conn, const char *fmt, va_list al) { xmit_free(d); char *m= xvasprintf(fmt,al); - warn("C%d connection failed (requeueing " RCI_TRIPLE_FMT_BASE "): %s", + warn("C%d connection failed requeueing " RCI_TRIPLE_FMT_BASE ": %s", conn->fd, RCI_TRIPLE_VALS_BASE(requeue, /*nothing*/), m); free(m); @@ -2125,7 +2125,16 @@ static void *feedfile_got_article(oop_source *lp, oop_read *rd, static void *tailing_rable_call_time(oop_source *loop, struct timeval tv, void *user) { + /* lifetime of ipf here is OK because destruction will cause + * on_cancel which will cancel this callback */ InputFile *ipf= user; + + if (!ipf->fake_readable) return OOP_CONTINUE; + + /* we just keep calling readable until our caller (oop_rd) + * has called try_read, and try_read has found EOF so given EAGAIN */ + loop->on_time(loop, OOP_TIME_NOW, tailing_rable_call_time, ipf); + return ipf->readable_callback(loop, &ipf->readable, ipf->readable_callback_user); } @@ -2138,9 +2147,10 @@ static void tailing_on_cancel(struct oop_readable *rable) { ipf->readable_callback= 0; } -static void tailing_queue_readable(InputFile *ipf) { - /* lifetime of ipf here is OK because destruction will cause - * on_cancel which will cancel this callback */ +static void tailing_make_readable(InputFile *ipf) { + if (!ipf || !ipf->readable_callback) /* so callers can be naive */ + return; + ipf->fake_readable= 1; loop->on_time(loop, OOP_TIME_NOW, tailing_rable_call_time, ipf); } @@ -2152,8 +2162,7 @@ static int tailing_on_readable(struct oop_readable *rable, ipf->readable_callback= cb; ipf->readable_callback_user= user; filemon_start(ipf); - - tailing_queue_readable(ipf); + tailing_make_readable(ipf); return 0; } @@ -2164,11 +2173,13 @@ static ssize_t tailing_try_read(struct oop_readable *rable, void *buffer, ssize_t r= read(ipf->fd, buffer, length); if (r==-1) { if (errno==EINTR) continue; + ipf->fake_readable= 0; return r; } if (!r) { if (ipf==main_input_file) { errno=EAGAIN; + ipf->fake_readable= 0; return -1; } else if (ipf==flushing_input_file) { assert(ipf->rd); @@ -2179,7 +2190,6 @@ static ssize_t tailing_try_read(struct oop_readable *rable, void *buffer, abort(); } } - tailing_queue_readable(ipf); return r; } } @@ -2244,7 +2254,7 @@ static void *filemon_inotify_readable(oop_source *lp, int fd, } InputFile *ipf= filemon_inotify_wd2ipf[iev.wd]; /*debug("filemon inotify readable read %p wd=%d", ipf, iev.wd);*/ - filemon_callback(ipf); + tailing_make_readable(ipf); } return OOP_CONTINUE; } @@ -2305,11 +2315,6 @@ static void filemon_stop(InputFile *ipf) { ipf->filemon= 0; } -static void filemon_callback(InputFile *ipf) { - if (ipf && ipf->readable_callback) /* so filepoll() can be naive */ - ipf->readable_callback(loop, &ipf->readable, ipf->readable_callback_user); -} - /*---------- interface to start and stop an input file ----------*/ static const oop_rd_style feedfile_rdstyle= { @@ -3048,7 +3053,7 @@ static void *inndcomm_event(oop_source *lp, int fd, oop_event e, void *u) { case INNDCOMMCHILD_ESTATUS_NONESUCH: notice("feed has been dropped by innd, finishing up"); flushing_input_file= main_input_file; - tailing_queue_readable(flushing_input_file); + tailing_make_readable(flushing_input_file); /* we probably previously returned EAGAIN from our fake read method * when in fact we were at EOF, so signal another readable event * so we actually see the EOF */ @@ -3068,7 +3073,7 @@ static void *inndcomm_event(oop_source *lp, int fd, oop_event e, void *u) { case 0: /* as above */ flushing_input_file= main_input_file; - tailing_queue_readable(flushing_input_file); + tailing_make_readable(flushing_input_file); main_input_file= open_input_file(feedfile); if (!main_input_file) @@ -3217,8 +3222,8 @@ static void every(int interval, int fixed_rate, void (*f)(void)) { } static void filepoll(void) { - filemon_callback(main_input_file); - filemon_callback(flushing_input_file); + tailing_make_readable(main_input_file); + tailing_make_readable(flushing_input_file); } static char *debug_report_ipf(InputFile *ipf) { @@ -3567,6 +3572,7 @@ static const Option innduct_options[]= { {0,"no-filemon", 0, &try_filemon, op_setint, 0 }, {'C',"inndconf", "F", &inndconffile, op_string }, {'P',"port", "PORT", &port, op_integer }, +{0,"chdir", "DIR", &path_run, op_string }, {0,"cli", "DIR/|PATH", &path_cli, op_string }, {0,"help", 0, 0, help }, @@ -3664,7 +3670,10 @@ int main(int argc, char **argv) { if (max_bad_data_ratio < 0 || max_bad_data_ratio > 100) badusage("bad input data ratio must be between 0..100"); max_bad_data_ratio *= 0.01; - + + if (!path_run) + path_run= innconf->pathrun; + if (!feedfile) { feedfile= xasprintf("%s/%s",innconf->pathoutgoing,sitename); } else if (!feedfile[0]) { @@ -3674,7 +3683,7 @@ int main(int argc, char **argv) { } if (!path_cli) { - path_cli_dir= xasprintf("%s/innduct", innconf->pathrun); + path_cli_dir= "innduct"; } else if (!path_cli[0] || !strcmp(path_cli,"none")) { path_cli= 0; /* ok, don't then */ } else if (path_ends_slash(path_cli)) { @@ -3694,6 +3703,9 @@ int main(int argc, char **argv) { /* set things up */ + r= chdir(path_run); + if (r) sysdie("could not chdir to pathrun %s", path_run); + path_lock= xasprintf("%s_lock", feedfile); path_flushing= xasprintf("%s_flushing", feedfile); path_defer= xasprintf("%s_defer", feedfile); @@ -3724,7 +3736,7 @@ int main(int argc, char **argv) { if (child1) _exit(0); pid_t sid= setsid(); - if (sid != child1) sysfatal("setsid failed"); + if (sid == -1) sysfatal("setsid failed"); pid_t child2= xfork("daemonise second fork"); if (child2) _exit(0);