From: Mark Wooding Date: Sat, 20 Dec 2008 11:39:32 +0000 (+0000) Subject: uslip: Associate a done-function with gobblers. X-Git-Tag: 1.0.0pre8~42 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/tripe/commitdiff_plain/e12ebbe8100dfbfea12b2797e89c0e362eff0aa3?ds=sidebyside uslip: Associate a done-function with gobblers. These work just like the dribbler done-functions. We're going to need this soon. --- diff --git a/uslip/uslip.c b/uslip/uslip.c index 245f1ec0..dee9f94d 100644 --- a/uslip/uslip.c +++ b/uslip/uslip.c @@ -81,6 +81,8 @@ typedef struct client { typedef struct gobbler { sel_file f; + void (*done)(struct gobbler *, int, void *); + void *p; } 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. - * 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) @@ -209,21 +211,27 @@ static void do_gobble_in(int fd, unsigned mode, void *p) 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) { + if (g->done) g->done(g, 0, g->p); 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); + 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); @@ -385,7 +393,7 @@ static void do_client_in(int fd, unsigned mode, void *p) 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;