From 8ffd26b800b4b460915524050d06c9e1612abe74 Mon Sep 17 00:00:00 2001 From: ian Date: Mon, 30 May 2005 11:11:23 +0000 Subject: [PATCH] more than one client possible --- hostside/hostside.c | 116 +++++++++++++++++++++++--------------------- hostside/hostside.h | 27 ++++++++++- hostside/serialio.c | 18 +++++-- 3 files changed, 102 insertions(+), 59 deletions(-) diff --git a/hostside/hostside.c b/hostside/hostside.c index 414e769..bd00f9b 100644 --- a/hostside/hostside.c +++ b/hostside/hostside.c @@ -15,21 +15,19 @@ oop_source *events; FILE *dump_stream= 0; -typedef struct OutBuffer OutBuffer; -struct OutBuffer { - OutBuffer *back, *next; - char *m; - int l; -}; -typedef struct OutBufferChain OutBufferChain; -struct OutBufferChain { - const char *what; - int fd; - int done_of_head; - struct { OutBuffer *head, *tail; } obs; -}; -static OutBufferChain stdin_ochain= { "stdin", 0 }; -static OutBufferChain serial_ochain= { "serial", -1 }; +static void serial_error(OutBufferChain *ch, const char *e1, const char *e2) { + abort(); +} + +static void stdin_error(OutBufferChain *ch, const char *e1, const char *e2) { + if (!e1) + exit(0); + fprintf(stderr,"stdin: %s: %s\n", e1, e2); + exit(12); +} + +static OutBufferChain serial_ochain= { (char*)"serial", -1, serial_error }; +static Client stdin_client= { { (char*)"stdin", 0, stdin_error } }; static void *ochain_writeable(oop_source *evts, int fd, oop_event evt, void *ch_v) { @@ -44,7 +42,6 @@ static void *ochain_writeable(oop_source *evts, int fd, ob= ch->obs.head; if (!ob) { events->cancel_fd(events, fd, OOP_WRITE); - events->cancel_fd(events, fd, OOP_EXCEPTION); return OOP_CONTINUE; } if (ch->done_of_head == ob->l) { @@ -58,7 +55,7 @@ static void *ochain_writeable(oop_source *evts, int fd, if (r==-1) { if (errno==EINTR) continue; if (errno==EWOULDBLOCK) return OOP_CONTINUE; - diee(ch->what); + ch->error(ch,"write",strerror(errno)); } assert(r>=0); ch->done_of_head += r; @@ -66,44 +63,49 @@ static void *ochain_writeable(oop_source *evts, int fd, } } -static void *ochain_exception(oop_source *evts, int fd, - oop_event evt, void *ch_v) { - OutBufferChain *ch= ch_v; - die(ch->what); +static void *client_exception(oop_source *evts, int fd, + oop_event evt, void *cl_v) { + Client *cl= cl_v; + cl->ch.error(&cl->ch,"comms error","exception"); + return OOP_CONTINUE; +} + +static void *serial_exception(oop_source *evts, int fd, + oop_event evt, void *cl_v) { + die("serial port - exception"); } static void ochain_addlink(OutBufferChain *ch, OutBuffer *ob) { - if (!ch->obs.head) { + if (!ch->obs.head) events->on_fd(events, ch->fd, OOP_WRITE, ochain_writeable, ch); - events->on_fd(events, ch->fd, OOP_EXCEPTION, ochain_exception, ch); - } LIST_LINK_TAIL(ch->obs, ob); } -static void ovprintf(const char *fmt, va_list al) - __attribute__((format(printf,1,0))); -static void ovprintf(const char *fmt, va_list al) { +static void ovprintf(OutBufferChain *ch, const char *fmt, va_list al) + __attribute__((format(printf,2,0))); +static void ovprintf(OutBufferChain *ch, const char *fmt, va_list al) { OutBuffer *ob; ob= malloc(sizeof(*ob)); if (!ob) diem(); ob->l= vasprintf(&ob->m, fmt, al); if (ob->l <= 0) diem(); - ochain_addlink(&stdin_ochain, ob); + ochain_addlink(&stdin_client.ch, ob); } -static void oprintf(const char *msg, ...) __attribute__((format(printf,1,2))); -static void oprintf(const char *msg, ...) { +static void oprintf(OutBufferChain *ch, const char *msg, ...) + __attribute__((format(printf,2,3))); +static void oprintf(OutBufferChain *ch, const char *msg, ...) { va_list al; va_start(al,msg); - ovprintf(msg,al); + ovprintf(ch,msg,al); va_end(al); } -static void badcmd(const char *how) { - oprintf("error %s\n",how); +static void badcmd(ParseState *ps, const char *how) { + oprintf(&ps->cl->ch,"error %s\n",how); } static void cmd_noop(ParseState *ps, const CmdInfo *ci) { - oprintf("noop successful\n"); + oprintf(&ps->cl->ch,"noop successful\n"); } static const CmdInfo toplevel_cmds[]= { @@ -121,7 +123,7 @@ static const CmdInfo toplevel_cmds[]= { static int ps_needword(ParseState *ps) { const char *space; - if (!ps->remain) { badcmd("too few args"); return 0; } + if (!ps->remain) { badcmd(ps,"too few args"); return 0; } space= strchr(ps->remain, ' '); ps->thisword= ps->remain; if (space) { @@ -149,32 +151,36 @@ static const CmdInfo *ps_needword_lookup(ParseState *ps, const CmdInfo *infs) { return ps_lookup(ps,infs); } -static void *stdin_iferr(oop_source *evts, oop_read *stdin_read, - oop_rd_event evt, const char *errmsg, int errnoval, - const char *data, size_t recsz, void *u0) - __attribute__((noreturn)); -static void *stdin_iferr(oop_source *evts, oop_read *stdin_read, - oop_rd_event evt, const char *errmsg, int errnoval, - const char *data, size_t recsz, void *u0) { - fprintf(stderr,"stdin %s\n", - oop_rd_errmsg(stdin_read, evt, errnoval, OOP_RD_STYLE_GETLINE)); - exit(4); +static void *client_iferr(oop_source *evts, oop_read *cl_read, + oop_rd_event evt, const char *errmsg, int errnoval, + const char *data, size_t recsz, void *cl_v) { + Client *cl= cl_v; + + cl->ch.error(&cl->ch, "read", + oop_rd_errmsg(cl_read, evt, + errnoval, OOP_RD_STYLE_GETLINE)); + return OOP_CONTINUE; } -static void *stdin_ifok(oop_source *evts, oop_read *stdin_read, - oop_rd_event evt, const char *errmsg, int errnoval, - const char *data, size_t recsz, void *u0) { +static void *client_ifok(oop_source *evts, oop_read *cl_read, + oop_rd_event evt, const char *errmsg, int errnoval, + const char *data, size_t recsz, void *cl_v) { + Client *cl= cl_v; ParseState ps; const CmdInfo *ci; - if (evt == OOP_RD_EOF) - exit(0); - if (evt != OOP_RD_OK) - stdin_iferr(evts,stdin_read,evt,errmsg,errnoval,data,recsz,u0); + if (evt == OOP_RD_EOF) { + cl->ch.error(&cl->ch,0,0); + return OOP_CONTINUE; + } + if (evt != OOP_RD_OK) + return client_iferr(evts,cl_read,evt,errmsg,errnoval,data,recsz,cl_v); + + ps.cl= cl; ps.remain= data; ci= ps_needword_lookup(&ps, toplevel_cmds); - if (!ci) { badcmd("unknown command"); return OOP_CONTINUE; } + if (!ci) { badcmd(&ps,"unknown command"); return OOP_CONTINUE; } ci->fn(&ps,ci); return OOP_CONTINUE; } @@ -204,10 +210,12 @@ int main(int argc, const char **argv) { stdin_source= oop_rd_new_fd(events, 0, 0,0); if (!stdin_source) diee("oop_rd_new_fd(,0,,)"); r= oop_rd_read(stdin_source, OOP_RD_STYLE_GETLINE, 1024, - stdin_ifok, 0, stdin_iferr, 0); + client_ifok, 0, client_iferr, 0); if (r) diee("oop_rd_read(stdin_source,...)"); + events->on_fd(events, 0, OOP_EXCEPTION, client_exception, &stdin_client); events->on_fd(events, serial_fd, OOP_READ, serial_readable, 0); + events->on_fd(events, serial_fd, OOP_EXCEPTION, serial_exception, 0); oop_sys_run(sys_events); abort(); } diff --git a/hostside/hostside.h b/hostside/hostside.h index f3d63bf..22c8cf4 100644 --- a/hostside/hostside.h +++ b/hostside/hostside.h @@ -8,9 +8,30 @@ typedef unsigned char Byte; +typedef struct OutBuffer OutBuffer; +struct OutBuffer { + OutBuffer *back, *next; + char *m; + int l; +}; + +typedef struct OutBufferChain OutBufferChain; +struct OutBufferChain { + char *desc; + int fd; + void (*error)(OutBufferChain *obc, const char *e1, const char *e2); + int done_of_head; + struct { OutBuffer *head, *tail; } obs; +}; + +typedef struct Client Client; +struct Client { + OutBufferChain ch; +}; typedef struct ParseState ParseState; struct ParseState { + Client *cl; const char *remain; const char *thisword; int lthisword; @@ -23,8 +44,10 @@ struct CmdInfo { }; extern oop_source *events; -void die(const char *m) __attribute__((noreturn)); -void diee(const char *m) __attribute__((noreturn)); +void vdie(const char *fmt, int ev, va_list al) + __attribute__((noreturn,format(printf,1,0))); +void die(const char *fmt, ...) __attribute__((noreturn,format(printf,1,2))); +void diee(const char *fmt, ...) __attribute__((noreturn,format(printf,1,2))); void diem(void) __attribute__((noreturn)); diff --git a/hostside/serialio.c b/hostside/serialio.c index 5d964ea..4497f69 100644 --- a/hostside/serialio.c +++ b/hostside/serialio.c @@ -4,7 +4,9 @@ #include #include #include +#include #include +#include #include #include @@ -14,9 +16,19 @@ int serial_fudge_delay= 0; int serial_fd= -1; -void die(const char *m) { fprintf(stderr,"%s\n",m); exit(8); } -void diee(const char *m) { perror(m); exit(12); } -void diem(void) { perror("malloc failed"); exit(16); } +void vdie(const char *fmt, int ev, va_list al) { + vfprintf(stderr,fmt,al); + if (ev) fprintf(stderr,": %s",strerror(ev)); + fputc('\n',stderr); + exit(12); +} + +void die(const char *fmt, ...) + { va_list al; va_start(al,fmt); vdie(fmt,0,al); } +void diee(const char *fmt, ...) + { va_list al; va_start(al,fmt); vdie(fmt,errno,al); } +void diem(void) + { diee("malloc failed"); } void serial_open(const char *device) { assert(serial_fd==-1); -- 2.30.2