chiark / gitweb /
uslip: Associate a done-function with gobblers.
authorMark Wooding <mdw@distorted.org.uk>
Sat, 20 Dec 2008 11:39:32 +0000 (11:39 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Sat, 20 Dec 2008 11:39:32 +0000 (11:39 +0000)
These work just like the dribbler done-functions.  We're going to need
this soon.

uslip/uslip.c

index 245f1ec0e22e6afa611608d758c5b7423d41a543..dee9f94d63e92d64df14c538d810ad34d3d0171b 100644 (file)
@@ -81,6 +81,8 @@ typedef struct client {
 
 typedef struct gobbler {
   sel_file f;
 
 typedef struct gobbler {
   sel_file f;
+  void (*done)(struct gobbler *, int, void *);
+  void *p;
 } gobbler;
 
 typedef struct dribbler {
 } gobbler;
 
 typedef struct dribbler {
@@ -188,8 +190,8 @@ static void destroy_pkq(pkq *q)
 /*----- Gobblers ----------------------------------------------------------*
  *
  * A gobbler just eats everything it sees on its input descriptor.
 /*----- Gobblers ----------------------------------------------------------*
  *
  * A gobbler just eats everything it sees on its input descriptor.
- * Eventually, when it sees end-of-file, it closes the input descriptor and
- * quits.
+ * Eventually, when it sees end-of-file, it closes the input descriptor,
+ * calls a user-supplied calback function, and quits.
  */
 
 static void gobbler_close(gobbler *g)
  */
 
 static void gobbler_close(gobbler *g)
@@ -209,21 +211,27 @@ static void do_gobble_in(int fd, unsigned mode, void *p)
        break;
       else {
        moan("read (gobble): %s", strerror(errno));
        break;
       else {
        moan("read (gobble): %s", strerror(errno));
+       if (g->done) g->done(g, errno, g->p);
        gobbler_close(g);
        break;
       }
     } else if (n == 0) {
        gobbler_close(g);
        break;
       }
     } else if (n == 0) {
+      if (g->done) g->done(g, 0, g->p);
       gobbler_close(g);
       break;
     }
   }
 }
 
       gobbler_close(g);
       break;
     }
   }
 }
 
-static gobbler *make_gobbler(int fd)
+static gobbler *make_gobbler(int fd,
+                            void (*done)(gobbler *, int, void *),
+                            void *p)
 {
   gobbler *g;
 
   g = CREATE(gobbler);
 {
   gobbler *g;
 
   g = CREATE(gobbler);
+  g->done = done;
+  g->p = p;
   sel_initfile(&sel, &g->f, fd, SEL_READ, do_gobble_in, g);
   sel_addfile(&g->f);
   do_gobble_in(fd, SEL_READ, g);
   sel_initfile(&sel, &g->f, fd, SEL_READ, do_gobble_in, g);
   sel_addfile(&g->f);
   do_gobble_in(fd, SEL_READ, g);
@@ -385,7 +393,7 @@ static void do_client_in(int fd, unsigned mode, void *p)
          break;
        case '<':
          w = CREATE(waiter);
          break;
        case '<':
          w = CREATE(waiter);
-         w->g = make_gobbler(fd);
+         w->g = make_gobbler(fd, 0, 0);
          w->next = 0;
          w->fd = fd;
          *wait_tail = w;
          w->next = 0;
          w->fd = fd;
          *wait_tail = w;