Various: Report errors encountered while doing channel I/O.
authorMark Wooding <mdw@distorted.org.uk>
Mon, 10 May 2010 01:18:04 +0000 (02:18 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Mon, 10 May 2010 01:28:37 +0000 (02:28 +0100)
I'm amazed I let these get swallowed up between chan and endpt.  Oh,
well.

Minor interface change: endpt_join wants a channel description string,
but the source (which always does the joining anyway) has one to hand.
The channel structure has grown an error indicator which the endpoint
manager inspects when it's tearing down the connection.

chan.c
endpt.c
exec.c
file.c
fwd.h
socket.c

diff --git a/chan.c b/chan.c
index e5b6d06..5fbecb1 100644 (file)
--- a/chan.c
+++ b/chan.c
@@ -80,9 +80,9 @@ static void writechan(int fd, unsigned mode, void *vp)
     if (w < 0) {
       if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)
        return;
+      c->err = errno;
       goto close;
-    }
-    else if (w == 0)
+    } else if (w == 0)
       goto close;
     else if (c->len == CHAN_BUFSZ && !(c->f & CHANF_CLOSE))
       sel_addfile(&c->r);
@@ -153,9 +153,9 @@ static void readchan(int fd, unsigned mode, void *vp)
   if (r < 0) {
     if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)
       return;
+    c->err = errno;
     goto close;
-  }
-  else if (r == 0)
+  } else if (r == 0)
     goto close;
   else if (c->len == 0 && (c->f & CHANF_READY)) {
     sel_addfile(&c->w);
diff --git a/endpt.c b/endpt.c
index a1b6ac7..1fbf188 100644 (file)
--- a/endpt.c
+++ b/endpt.c
@@ -47,6 +47,7 @@ typedef struct chanpair {
 typedef struct tango {
   struct tango *next, *prev;           /* A big list of all tangos */
   endpt *a, *b;                                /* The two endpoints */
+  char *desc;                          /* Description of the connection */
   unsigned s;                          /* State of the connection */
   chanpair *c;                         /* The pair of channels */
 } tango;
@@ -121,6 +122,10 @@ void endpt_kill(endpt *a)
    */
 
   if (a->f & b->f & EPF_FILE) {
+    if (t->c->ab.err)
+      fw_log(-1, "[%s] error: %s", t->desc, strerror(t->c->ab.err));
+    else if (t->c->ba.err)
+      fw_log(-1, "[%s] error: %s", t->desc, strerror(t->c->ba.err));
     if (t->s & EPS_AB)
       chan_close(&t->c->ab);
     if (!(b->f & EPF_PENDING) && (t->s & EPS_BA))
@@ -139,6 +144,8 @@ void endpt_kill(endpt *a)
     t->prev->next = t->next;
   else
     tangos = t->next;
+  if (t->desc)
+    xfree(t->desc);
   DESTROY(t);
 }
 
@@ -167,6 +174,7 @@ void endpt_killall(void)
  *
  * Arguments:  @endpt *a@ = pointer to first endpoint
  *             @endpt *b@ = pointer to second endpoint
+ *             @const char *desc@ = description of connection
  *
  * Returns:    ---
  *
@@ -174,9 +182,13 @@ void endpt_killall(void)
  *             which are already joined; in fact, the the right thing to do
  *             when your endpoint decides that it's not pending any more is
  *             to join it to its partner again.
+ *
+ *             If the endpoints are already connected then the description
+ *             string is ignored.  The endpoint manager takes a copy of the
+ *             string, so you don't need to keep it around.
  */
 
-void endpt_join(endpt *a, endpt *b)
+void endpt_join(endpt *a, endpt *b, const char *desc)
 {
   tango *t = a->t;
 
@@ -191,6 +203,7 @@ void endpt_join(endpt *a, endpt *b)
     a->t = b->t = t;
     t->s = EPS_AB | EPS_BA;
     t->c = 0;
+    t->desc = xstrdup(desc);
     if (tangos)
       tangos->prev = t;
     tangos = t;
diff --git a/exec.c b/exec.c
index bdd9b5b..9b7e87b 100644 (file)
--- a/exec.c
+++ b/exec.c
@@ -1032,7 +1032,7 @@ static void xsource_attach(source *s, scanner *sc, target *t)
     ee->ops->close(ee);
     goto tidy;
   }
-  endpt_join(e, ee);
+  endpt_join(e, ee, xs->s.desc);
 
   /* --- Dispose of source and target --- */
 
diff --git a/file.c b/file.c
index 31e1e07..cc319ce 100644 (file)
--- a/file.c
+++ b/file.c
@@ -488,7 +488,7 @@ static void fsource_attach(source *s, scanner *sc, target *t)
     ee->ops->close(ee);
     goto tidy;
   }
-  endpt_join(e, ee);
+  endpt_join(e, ee, fs->s.desc);
 
   /* --- Dispose of the source and target now --- */
 
diff --git a/fwd.h b/fwd.h
index 6c16fb6..2d139e4 100644 (file)
--- a/fwd.h
+++ b/fwd.h
@@ -154,6 +154,7 @@ typedef struct chan {
   unsigned base, len;                  /* Base and length of data */
   unsigned f;                          /* Various interesting flags */
   void (*func)(void */*p*/);           /* Function to call on closure */
+  int err;                             /* What's wrong with the channel */
   void *p;                             /* Argument to pass function */
   sel_file r, w;                       /* Reader and writer selectors */
   char buf[CHAN_BUFSZ];                        /* The actual data buffer */
@@ -891,13 +892,21 @@ extern void endpt_killall(void);
  *
  * Arguments:  @endpt *a@ = pointer to first endpoint
  *             @endpt *b@ = pointer to second endpoint
+ *             @const char *desc@ = description of connection
  *
  * Returns:    ---
  *
- * Use:                Joins two endpoints together.
+ * Use:                Joins two endpoints together.  It's OK to join endpoints
+ *             which are already joined; in fact, the the right thing to do
+ *             when your endpoint decides that it's not pending any more is
+ *             to join it to its partner again.
+ *
+ *             If the endpoints are already connected then the description
+ *             string is ignored.  The endpoint manager takes a copy of
+ *             the string, so you don't need to keep it around.
  */
 
-extern void endpt_join(endpt */*a*/, endpt */*b*/);
+extern void endpt_join(endpt */*a*/, endpt */*b*/, const char */*desc*/);
 
 /* --- @source_add@ --- *
  *
index 518117c..a1a9a55 100644 (file)
--- a/socket.c
+++ b/socket.c
@@ -225,7 +225,7 @@ void starget_connected(int fd, void *p)
     e->e.in = e->e.out = r;
     e->e.f &= ~EPF_PENDING;
     if (e->e.other)
-      endpt_join(&e->e, e->e.other);
+      endpt_join(&e->e, e->e.other, 0);
   }
 }
 
@@ -454,7 +454,7 @@ static void ss_accept(int fd, unsigned mode, void *p)
 
     /* --- Let everything else happen --- */
 
-    endpt_join(&e->e, ee);
+    endpt_join(&e->e, ee, ss->s.desc);
   }
 }