Adds eshutdown(2) to allow programs to stop event processing before exiting. There is currently no way for programs using event(2) to stop event processing. Device files and memory are held by the library. This prevents programs using event(2) from returning to console mode cleanly without exiting. This patch adds eshutdown(2) to provide that function. Existing programs using event(2) should not be affected by this change. I have recompiled and run clock(1) and tweak(1) for testing, both of which behave unchanged. Updated to fix style(6) violations. Notes: Sat Mar 22 18:39:39 EDT 2008 geoff would it suffice to make ekill() in /sys/src/libdraw/event.c documented and non-static? Thu Apr 10 19:26:30 EDT 2008 geoff This is just not the Plan 9 way of doing things. vim is a mistake to begin with and we don't need shell escapes. Reference: /n/sources/patch/sorry/eshutdown2 Date: Thu Mar 20 08:44:08 CET 2008 Signed-off-by: stefanha@gmail.com Reviewed-by: geoff --- /sys/include/event.h Thu Mar 20 08:42:40 2008 +++ /sys/include/event.h Thu Mar 20 08:42:32 2008 @@ -44,6 +44,7 @@ * Events */ extern void einit(ulong); +extern void eshutdown(void); extern ulong estart(ulong, int, int); extern ulong estartfn(ulong, int, int, int (*fn)(int, Event*, uchar*, int)); extern ulong etimer(ulong, int); --- /sys/src/libdraw/event.c Thu Mar 20 08:42:59 2008 +++ /sys/src/libdraw/event.c Sun Mar 23 23:02:44 2008 @@ -10,7 +10,7 @@ struct Slave { int pid; - Ebuf *head; /* ueue of messages for this descriptor */ + Ebuf *head; /* queue of messages for this descriptor */ Ebuf *tail; int (*fn)(int, Event*, uchar*, int); }; @@ -22,6 +22,8 @@ uchar buf[EMAXMSG]; }; +enum { Noexit, Exiting }; + static Slave eslave[MAXSLAVE]; static int Skeyboard = -1; static int Smouse = -1; @@ -31,15 +33,18 @@ static int nslave; static int parentpid; static int epipe[2]; + +static int mousefd; +static int cursorfd; +static int consfd; +static int ctlfd; + static int eforkslave(ulong); static void extract(void); static void ekill(void); static int enote(void *, char *); -static int mousefd; -static int cursorfd; -static -Ebuf* +static Ebuf* ebread(Slave *s) { Ebuf *eb; @@ -228,13 +233,15 @@ void einit(ulong keys) { - int ctl, fd; + int firstinit; char buf[256]; + firstinit = (parentpid == 0); parentpid = getpid(); if(pipe(epipe) < 0) drawerror(display, "events: einit pipe"); - atexit(ekill); + if(firstinit) + atexit(ekill); atnotify(enote, 1); snprint(buf, sizeof buf, "%s/mouse", display->devdir); mousefd = open(buf, ORDWR|OCEXEC); @@ -246,17 +253,17 @@ drawerror(display, "einit: can't open cursor\n"); if(keys&Ekeyboard){ snprint(buf, sizeof buf, "%s/cons", display->devdir); - fd = open(buf, OREAD); - if(fd < 0) + consfd = open(buf, OREAD); + if(consfd < 0) drawerror(display, "events: can't open console"); snprint(buf, sizeof buf, "%s/consctl", display->devdir); - ctl = open("/dev/consctl", OWRITE|OCEXEC); - if(ctl < 0) + ctlfd = open("/dev/consctl", OWRITE|OCEXEC); + if(ctlfd < 0) drawerror(display, "events: can't open consctl"); - write(ctl, "rawon", 5); + write(ctlfd, "rawon", 5); for(Skeyboard=0; Ekeyboard & ~(1< 0 && (wm = wait()) != nil) { + for(i = 0; i < nslave; i++) + if(eslave[i].pid == wm->pid) + nalive--; + free(wm); + } + for(i = 0; i < nslave; i++){ + for(eb = eslave[i].head; eb; eb = next){ + next = eb->next; + free(eb); + } + memset(&eslave[i], 0, sizeof(eslave[i])); + } + write(ctlfd, "rawoff", 6); + close(ctlfd); + close(consfd); + close(cursorfd); + close(mousefd); + nslave = 0; + Skeyboard = Smouse = Stimer = ctlfd = consfd = cursorfd = mousefd = -1; +} + +void +eshutdown(void) +{ + edoshutdown(Noexit); +} + +static void extract(void) { Slave *s; @@ -372,22 +432,15 @@ } return 0; } - close(epipe[0]); - epipe[0] = -1; - close(epipe[1]); - epipe[1] = -1; - for(i=0; i