chiark / gitweb /
discard data sent to logging client; more close fixing
authorRichard Kettlewell <rjk@greenend.org.uk>
Tue, 13 Nov 2007 22:23:41 +0000 (22:23 +0000)
committerRichard Kettlewell <rjk@greenend.org.uk>
Tue, 13 Nov 2007 22:23:41 +0000 (22:23 +0000)
doc/disorder_protocol.5.in
server/server.c

index 4fe53ced51f471de30a84510de3aca67478d29da..d20edcf571896866e105b0942f40ae12150a9f38 100644 (file)
@@ -90,9 +90,9 @@ Gets the length of the track in seconds.  On success the second field of the
 response line will have the value.
 .TP
 .B log
-Sends event log messages in a response body.  The command will only terminate (and
-close the response body with a final dot) when a further command is readable on
-the control connection.
+Sends event log messages in a response body.  The command will never terminate.
+Any further data sent to the server will be discarded (explicitly; i.e. it will
+not accumulate in a buffer somewhere).
 .IP
 See \fBEVENT LOG\fR below for more details.
 .TP
index 6bfee6b67323b8332c34c0710a80307943831012..ccd08238967754d3c34584733b077e521cab4173 100644 (file)
@@ -81,16 +81,30 @@ struct listener {
   int pf;
 };
 
+/** @brief One client connection */
 struct conn {
+  /** @brief Read commands from here */
   ev_reader *r;
+  /** @brief Send responses to here */
   ev_writer *w;
+  /** @brief Underlying file descriptor */
   int fd;
+  /** @brief Unique identifier for connection used in log messages */
   unsigned tag;
+  /** @brief Login name or NULL */
   char *who;
+  /** @brief Event loop */
   ev_source *ev;
+  /** @brief Nonce chosen for this connection */
   unsigned char nonce[NONCE_SIZE];
+  /** @brief Current reader callback
+   *
+   * We change this depending on whether we're servicing the @b log command
+   */
   ev_reader_callback *reader;
+  /** @brief Event log output sending to this connection */
   struct eventlog_output *lo;
+  /** @brief Parent listener */
   const struct listener *l;
 };
 
@@ -103,6 +117,10 @@ static int reader_callback(ev_source *ev,
 
 static const char *noyes[] = { "no", "yes" };
 
+/** @brief Called when a connection's writer fails or is shut down
+ *
+ * If the connection still has a raeder that is cancelled.
+ */
 static int writer_error(ev_source attribute((unused)) *ev,
                        int errno_value,
                        void *u) {
@@ -128,6 +146,10 @@ static int writer_error(ev_source attribute((unused)) *ev,
   return 0;
 }
 
+/** @brief Called when a conncetion's reader fails or is shut down
+ *
+ * If connection still has a writer then it is closed.
+ */
 static int reader_error(ev_source attribute((unused)) *ev,
                        int errno_value,
                        void *u) {
@@ -144,7 +166,7 @@ static int reader_error(ev_source attribute((unused)) *ev,
   return 0;
 }
 
-/* return true if we are talking to a trusted user */
+/** @brief Return true if we are talking to a trusted user */
 static int trusted(struct conn *c) {
   int n;
   
@@ -715,26 +737,31 @@ static int c_volume(struct conn *c,
   return 1;
 }
 
-/* we are logging, and some data is available to read */
-static int logging_reader_callback(ev_source *ev,
+/** @brief Called when data arrives on a log connection
+ *
+ * We just discard all such data.  The client may occasionally send data as a
+ * keepalive.
+ */
+static int logging_reader_callback(ev_source attribute((unused)) *ev,
                                   ev_reader *reader,
-                                  void *ptr,
+                                  void attribute((unused)) *ptr,
                                   size_t bytes,
-                                  int eof,
-                                  void *u) {
+                                  int attribute((unused)) eof,
+                                  void attribute((unused)) *u) {
   struct conn *c = u;
 
-  /* don't log to this conn any more */
-  eventlog_remove(c->lo);
-  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");
+  ev_reader_consume(reader, bytes);
+  if(eof) {
+    /* Oops, that's all for now */
+    info("logging reader eof");
+    if(c->w) {
+      info("close writer");
+      ev_writer_close(c->w);
+      c->w = 0;
+    }
+    c->r = 0;
   }
-  /* restore the reader callback */
-  c->reader = reader_callback;
-  /* ...and exit via it */
-  return c->reader(ev, reader, ptr, bytes, eof, u);
+  return 0;
 }
 
 static void logclient(const char *msg, void *user) {
@@ -1093,7 +1120,13 @@ static int reader_callback(ev_source attribute((unused)) *ev,
   if(eof) {
     if(bytes)
       error(0, "S%x unterminated line", c->tag);
-    return ev_writer_close(c->w);
+    info("normal reader close");
+    c->r = 0;
+    if(c->w) {
+      info("close associated writer");
+      ev_writer_close(c->w);
+      c->w = 0;
+    }
   }
   return 0;
 }