/*
* This file is part of DisOrder.
- * Copyright (C) 2004, 2005, 2006 Richard Kettlewell
+ * Copyright (C) 2004, 2005, 2006, 2007 Richard Kettlewell
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
/* writer is done */
c->w = 0;
if(c->r == 0) {
- D(("server writer_error closes %d", fd));
+ //D(("server writer_error closes %d", fd));
+ info("server writer_error closes %d because all done", fd); /* TODO */
xclose(fd); /* reader is done too, close */
} else {
- D(("server writer_error shutdown %d SHUT_WR", fd));
+ //D(("server writer_error shutdown %d SHUT_WR", fd));
+ info("server writer_error shutdown %d SHUT_WR", fd); /* TODO */
xshutdown(fd, SHUT_WR); /* reader is not done yet */
}
} else {
error(errno_value, "S%x write error on socket", c->tag);
if(c->r)
ev_reader_cancel(c->r);
+ info("server writer_error closes %d because errno=%d", fd, errno_value); /* TODO */
xclose(fd);
}
return 0;
D(("server reader_error %d %d", fd, errno_value));
error(errno, "S%x read error on socket", c->tag);
- ev_writer_cancel(c->w);
+ if(c->w) {
+ ev_writer_cancel(c->w);
+ c->w = 0;
+ }
+ ev_report(ev);
+ info("reader_error closing fd %d", fd); /* TODO */
xclose(fd);
return 0;
}
return 1; /* completed */
}
+static void got_stats(char *stats, void *u) {
+ struct conn *const c = u;
+
+ sink_printf(ev_writer_sink(c->w), "253 stats\n%s\n.\n", stats);
+ /* Now we can start processing commands again */
+ ev_reader_enable(c->r);
+}
+
static int c_stats(struct conn *c,
char attribute((unused)) **vec,
int attribute((unused)) nvec) {
- char **v;
- int nv, n;
-
- v = trackdb_stats(&nv);
- sink_printf(ev_writer_sink(c->w), "253 stats\n");
- for(n = 0; n < nv; ++n) {
- if(v[n][0] == '.')
- sink_writes(ev_writer_sink(c->w), ".");
- sink_printf(ev_writer_sink(c->w), "%s\n", v[n]);
- }
- sink_writes(ev_writer_sink(c->w), ".\n");
- return 1;
+ trackdb_stats_subprocess(c->ev, got_stats, c);
+ return 0; /* not yet complete */
}
static int c_volume(struct conn *c,
/* don't log to this conn any more */
eventlog_remove(c->lo);
- /* terminate the log output */
- sink_writes(ev_writer_sink(c->w), ".\n");
+ if(c->w) {
+ /* Terminate the log output, but only if the writer hasn't been killed off
+ * from a failure on some earlier write */
+ sink_writes(ev_writer_sink(c->w), ".\n");
+ }
/* restore the reader callback */
c->reader = reader_callback;
/* ...and exit via it */
static void logclient(const char *msg, void *user) {
struct conn *c = user;
+ if(!c->w || !c->r) {
+ /* This connection has gone up in smoke for some reason */
+ eventlog_remove(c->lo);
+ return;
+ }
sink_printf(ev_writer_sink(c->w), "%"PRIxMAX" %s\n",
(uintmax_t)time(0), msg);
}