chiark / gitweb /
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 e5b6d06ab5771244df203ce1131a70241ce1d37a..5fbecb1605e4d3eef8e89bd34ce936b2c18402fb 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 a1b6ac785aed9c92a15d59395418bdac8e5c39f4..1fbf1880d76078069f33319eae842df28276c0bd 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 bdd9b5bbee95e3596bc710147817d9bd520815b4..9b7e87b7347ed2376ccfd407f2e16e211e278171 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 31e1e07c0fa16c27ebff2f0a9e608d465e0551c8..cc319ce0be40046e92f6056dbb350b2a18d43815 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 6c16fb628c06328647850f54c32dd92bc5a4e420..2d139e4f21680ff0e457f92b54af509e9d35e911 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 518117c8124d1857d60e34fe8171bcc9c0b2e51b..a1a9a55026b6475f1a95045f374c200c5a19f1c8 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);
   }
 }