diff --git a/sys/include/9p.h b/sys/include/9p.h index 949476232..1a51ffeab 100644 --- a/sys/include/9p.h +++ b/sys/include/9p.h @@ -235,23 +235,29 @@ struct Srv { int spid; /* pid of srv() caller */ + void (*forker)(void (*)(void*), void*, int); void (*free)(Srv*); }; +void srvforker(void (*)(void*), void*, int); +void threadsrvforker(void (*)(void*), void*, int); + void srv(Srv*); +void postsrv(Srv*, char*); void postmountsrv(Srv*, char*, char*, int); -void _postmountsrv(Srv*, char*, char*, int); void postsharesrv(Srv*, char*, char*, char*); -void _postsharesrv(Srv*, char*, char*, char*); void listensrv(Srv*, char*); -void _listensrv(Srv*, char*); -int chatty9p; -void respond(Req*, char*); -void responderror(Req*); + +void threadsrv(Srv*); +void threadpostsrv(Srv*, char*); void threadpostmountsrv(Srv*, char*, char*, int); void threadpostsharesrv(Srv*, char*, char*, char*); void threadlistensrv(Srv *s, char *addr); +int chatty9p; +void respond(Req*, char*); +void responderror(Req*); + /* * Helper. Assumes user is same as group. */ @@ -276,8 +282,6 @@ void authwrite(Req*); void authdestroy(Fid*); int authattach(Req*); -extern void (*_forker)(void (*)(void*), void*, int); - void srvacquire(Srv *); void srvrelease(Srv *); diff --git a/sys/man/2/9p b/sys/man/2/9p index 9a110e292..d68fbaa2c 100644 --- a/sys/man/2/9p +++ b/sys/man/2/9p @@ -9,16 +9,21 @@ estrdup9p, listensrv, postmountsrv, postsharesrv, +postsrv, readbuf, readstr, respond, responderror, +srv srvacquire, +srvforker, srvrelease, threadlistensrv, threadpostmountsrv, threadpostsharesrv, -srv \- 9P file service +threadpostsrv, +threadsrv, +threadsrvforker - 9P file service .SH SYNOPSIS .ft L .nf @@ -59,6 +64,8 @@ typedef struct Srv { int infd; int outfd; int srvfd; + + void (*forker)(void (*fn)(void*), void *arg, int flags); } Srv; .fi .PP @@ -66,12 +73,17 @@ typedef struct Srv { .ft L .ta \w'\fLvoid* 'u void srv(Srv *s) +void postsrv(Srv *s, char *name); void postmountsrv(Srv *s, char *name, char *mtpt, int flag) void postsharesrv(Srv *s, char *name, char *mtpt, char *desc) +void listensrv(Srv *s, char *addr) +void threadsrv(Srv *s) +void threadpostsrv(Srv *s, char *name); void threadpostmountsrv(Srv *s, char *name, char *mtpt, int flag) void threadpostsharesrv(Srv *s, char *name, char *mtpt, char *desc) -void listensrv(Srv *s, char *addr) void threadlistensrv(Srv *s, char *addr) +void srvforker(void (*fn)(void*), void *arg, int flags) +void threadsrvforker(void (*fn)(void*), void *arg, int flags) void respond(Req *r, char *error) void responderror(Req*) void readstr(Req *r, char *src) @@ -106,7 +118,9 @@ extern int chatty9p; .SH DESCRIPTION The function .I srv -serves a 9P session by reading requests from +and +.I threadsrv +serve a 9P session by reading requests from .BR s->infd , dispatching them to the function pointers kept in .BR Srv , @@ -166,6 +180,19 @@ but abort the program if they run out of memory. If alternate behavior is desired, clients can link against alternate implementations of these functions. .PP +The functions +.I srvforker +and +.I threadsrvforker +handle the creation of new processes on a connection which use +.I rfork +(see +.IR fork (2)) +or +.I procrfork +(see +.IR thread (2)). +.PP .I Postmountsrv and .I threadpostmountsrv @@ -174,6 +201,14 @@ are wrappers that create a separate process in which to run They do the following: .IP Initialize +.IB s -> forker +to eigther +.I srvforker +or +.I threadsrvforker +unless already initialized to a non-nil value. +.IP +Initialize .IB s -> infd and .IB s -> outfd @@ -187,16 +222,12 @@ If is non-nil, post the file descriptor .IB s -> srvfd under the name -.BI /srv/ name . +.BI /srv/ name +using a call to +.IR postsrv . .IP Fork a child process via -.I rfork -(see -.IR fork (2)) -or -.I procrfork -(see -.IR thread (2)), +.IB s -> forker using the .BR RFPROC , .BR RFNOWAIT , diff --git a/sys/src/lib9p/listen.c b/sys/src/lib9p/listen.c index 89b2f322d..59082f594 100644 --- a/sys/src/lib9p/listen.c +++ b/sys/src/lib9p/listen.c @@ -11,7 +11,7 @@ static void srvfree(Srv *); static char *getremotesys(char*); void -_listensrv(Srv *os, char *addr) +listensrv(Srv *os, char *addr) { Srv *s; @@ -33,9 +33,9 @@ _listensrv(Srv *os, char *addr) s->spid = 0; s->free = nil; - if(_forker == nil) - sysfatal("no forker"); - _forker(listenproc, s, 0); + if(s->forker == nil) + s->forker = srvforker; + (*s->forker)(listenproc, s, 0); } static void @@ -72,7 +72,7 @@ listenproc(void *v) s->addr = getremotesys(ndir); s->infd = s->outfd = data; s->free = srvfree; - _forker(srvproc, s, 0); + (*s->forker)(srvproc, s, 0); } free(os->addr); free(os); diff --git a/sys/src/lib9p/mkfile b/sys/src/lib9p/mkfile index 78129109b..6ec968a88 100644 --- a/sys/src/lib9p/mkfile +++ b/sys/src/lib9p/mkfile @@ -7,17 +7,24 @@ OFILES=\ fid.$O\ file.$O\ intmap.$O\ - listen.$O\ mem.$O\ req.$O\ parse.$O\ - post.$O\ queue.$O\ - rfork.$O\ - srv.$O\ - thread.$O\ uid.$O\ util.$O\ + srv.$O\ + post.$O\ + mount.$O\ + share.$O\ + listen.$O\ + rfork.$O\ + thread.$O\ + threadsrv.$O\ + threadpostsrv.$O\ + threadpostmountsrv.$O\ + threadpostsharesrv.$O\ + threadlistensrv.$O\ HFILES=/sys/include/9p.h diff --git a/sys/src/lib9p/mount.c b/sys/src/lib9p/mount.c new file mode 100644 index 000000000..1adc90bed --- /dev/null +++ b/sys/src/lib9p/mount.c @@ -0,0 +1,19 @@ +#include +#include +#include +#include +#include <9p.h> +#include + +void +postmountsrv(Srv *s, char *name, char *mtpt, int flag) +{ + postsrv(s, name); + + if(mtpt != nil){ + if(amount(s->srvfd, mtpt, flag, "") == -1) + sysfatal("mount %s: %r", mtpt); + /* mount closed s->srvfd */ + } else + close(s->srvfd); +} diff --git a/sys/src/lib9p/post.c b/sys/src/lib9p/post.c index ba4265494..803d7646d 100644 --- a/sys/src/lib9p/post.c +++ b/sys/src/lib9p/post.c @@ -8,15 +8,13 @@ static void postproc(void *v) { - Srv *s; - - s = v; + Srv *s = v; rendezvous(0, 0); close(s->srvfd); srv(s); } -static void +void postsrv(Srv *s, char *name) { char buf[80]; @@ -37,9 +35,9 @@ postsrv(Srv *s, char *name) } else cfd = -1; - if(_forker == nil) - sysfatal("no forker"); - _forker(postproc, s, RFNAMEG|RFNOTEG); + if(s->forker == nil) + s->forker = srvforker; + (*s->forker)(postproc, s, RFNAMEG|RFNOTEG); rfork(RFFDG); rendezvous(0, 0); @@ -51,43 +49,3 @@ postsrv(Srv *s, char *name) if(cfd >= 0) close(cfd); } - -void -_postmountsrv(Srv *s, char *name, char *mtpt, int flag) -{ - postsrv(s, name); - - if(mtpt != nil){ - if(amount(s->srvfd, mtpt, flag, "") == -1) - sysfatal("mount %s: %r", mtpt); - /* mount closed s->srvfd */ - } else - close(s->srvfd); -} - -void -_postsharesrv(Srv *s, char *name, char *mtpt, char *desc) -{ - char buf[80]; - int cfd; - - if(mtpt != nil && desc != nil){ - snprint(buf, sizeof buf, "#σc/%s", mtpt); - if((cfd = create(buf, OREAD, DMDIR|0700)) >= 0) - close(cfd); - - snprint(buf, sizeof buf, "#σc/%s/%s", mtpt, desc); - if((cfd = create(buf, OWRITE|ORCLOSE|OCEXEC, 0600)) < 0) - sysfatal("create %s: %r", buf); - } else - cfd = -1; - - postsrv(s, name); - - if(cfd >= 0){ - if(fprint(cfd, "%d\n", s->srvfd) < 0) - sysfatal("write %s: %r", buf); - close(cfd); - } - close(s->srvfd); -} diff --git a/sys/src/lib9p/rfork.c b/sys/src/lib9p/rfork.c index 45bf59365..32621d57f 100644 --- a/sys/src/lib9p/rfork.c +++ b/sys/src/lib9p/rfork.c @@ -4,8 +4,8 @@ #include #include <9p.h> -static void -rforker(void (*fn)(void*), void *arg, int flag) +void +srvforker(void (*fn)(void*), void *arg, int flag) { switch(rfork(RFPROC|RFMEM|RFNOWAIT|flag)){ case -1: @@ -17,24 +17,3 @@ rforker(void (*fn)(void*), void *arg, int flag) _exits(0); } } - -void -listensrv(Srv *s, char *addr) -{ - _forker = rforker; - _listensrv(s, addr); -} - -void -postmountsrv(Srv *s, char *name, char *mtpt, int flag) -{ - _forker = rforker; - _postmountsrv(s, name, mtpt, flag); -} - -void -postsharesrv(Srv *s, char *name, char *mtpt, char *desc) -{ - _forker = rforker; - _postsharesrv(s, name, mtpt, desc); -} diff --git a/sys/src/lib9p/share.c b/sys/src/lib9p/share.c new file mode 100644 index 000000000..f33d62b1e --- /dev/null +++ b/sys/src/lib9p/share.c @@ -0,0 +1,33 @@ +#include +#include +#include +#include +#include <9p.h> +#include + +void +postsharesrv(Srv *s, char *name, char *mtpt, char *desc) +{ + char buf[80]; + int cfd; + + if(mtpt != nil && desc != nil){ + snprint(buf, sizeof buf, "#σc/%s", mtpt); + if((cfd = create(buf, OREAD, DMDIR|0700)) >= 0) + close(cfd); + + snprint(buf, sizeof buf, "#σc/%s/%s", mtpt, desc); + if((cfd = create(buf, OWRITE|ORCLOSE|OCEXEC, 0600)) < 0) + sysfatal("create %s: %r", buf); + } else + cfd = -1; + + postsrv(s, name); + + if(cfd >= 0){ + if(fprint(cfd, "%d\n", s->srvfd) < 0) + sysfatal("write %s: %r", buf); + close(cfd); + } + close(s->srvfd); +} diff --git a/sys/src/lib9p/srv.c b/sys/src/lib9p/srv.c index f3039e012..5e82b5603 100644 --- a/sys/src/lib9p/srv.c +++ b/sys/src/lib9p/srv.c @@ -5,8 +5,6 @@ #include #include <9p.h> -void (*_forker)(void(*)(void*), void*, int); - static char Ebadattach[] = "unknown specifier in attach"; static char Ebadoffset[] = "bad offset"; static char Ebadcount[] = "bad count"; @@ -813,7 +811,7 @@ srvrelease(Srv *srv) { if(decref(&srv->sref) == 0){ incref(&srv->sref); - _forker(srvwork, srv, 0); + (*srv->forker)(srvwork, srv, 0); } qunlock(&srv->slock); } @@ -843,6 +841,9 @@ srv(Srv *srv) if(srv->start) srv->start(srv); + if(srv->forker == nil) + srv->forker = srvforker; + incref(&srv->sref); srvwork(srv); } diff --git a/sys/src/lib9p/thread.c b/sys/src/lib9p/thread.c index 445791be4..0e536ba5b 100644 --- a/sys/src/lib9p/thread.c +++ b/sys/src/lib9p/thread.c @@ -4,29 +4,8 @@ #include #include <9p.h> -static void -tforker(void (*fn)(void*), void *arg, int rflag) +void +threadsrvforker(void (*fn)(void*), void *arg, int rflag) { procrfork(fn, arg, 32*1024, rflag); } - -void -threadlistensrv(Srv *s, char *addr) -{ - _forker = tforker; - _listensrv(s, addr); -} - -void -threadpostmountsrv(Srv *s, char *name, char *mtpt, int flag) -{ - _forker = tforker; - _postmountsrv(s, name, mtpt, flag); -} - -void -threadpostsharesrv(Srv *s, char *name, char *mtpt, char *desc) -{ - _forker = tforker; - _postsharesrv(s, name, mtpt, desc); -} diff --git a/sys/src/lib9p/threadlistensrv.c b/sys/src/lib9p/threadlistensrv.c new file mode 100644 index 000000000..65be4e51e --- /dev/null +++ b/sys/src/lib9p/threadlistensrv.c @@ -0,0 +1,13 @@ +#include +#include +#include +#include +#include <9p.h> + +void +threadlistensrv(Srv *s, char *addr) +{ + if(s->forker == nil) + s->forker = threadsrvforker; + listensrv(s, addr); +} diff --git a/sys/src/lib9p/threadpostmountsrv.c b/sys/src/lib9p/threadpostmountsrv.c new file mode 100644 index 000000000..025459b65 --- /dev/null +++ b/sys/src/lib9p/threadpostmountsrv.c @@ -0,0 +1,13 @@ +#include +#include +#include +#include +#include <9p.h> + +void +threadpostmountsrv(Srv *s, char *name, char *mtpt, int flag) +{ + if(s->forker == nil) + s->forker = threadsrvforker; + postmountsrv(s, name, mtpt, flag); +} diff --git a/sys/src/lib9p/threadpostsharesrv.c b/sys/src/lib9p/threadpostsharesrv.c new file mode 100644 index 000000000..383852c4a --- /dev/null +++ b/sys/src/lib9p/threadpostsharesrv.c @@ -0,0 +1,13 @@ +#include +#include +#include +#include +#include <9p.h> + +void +threadpostsharesrv(Srv *s, char *name, char *mtpt, char *desc) +{ + if(s->forker == nil) + s->forker = threadsrvforker; + postsharesrv(s, name, mtpt, desc); +} diff --git a/sys/src/lib9p/threadpostsrv.c b/sys/src/lib9p/threadpostsrv.c new file mode 100644 index 000000000..abdb882e8 --- /dev/null +++ b/sys/src/lib9p/threadpostsrv.c @@ -0,0 +1,13 @@ +#include +#include +#include +#include +#include <9p.h> + +void +threadpostsrv(Srv *s, char *name) +{ + if(s->forker == nil) + s->forker = threadsrvforker; + postsrv(s, name); +} diff --git a/sys/src/lib9p/threadsrv.c b/sys/src/lib9p/threadsrv.c new file mode 100644 index 000000000..f892f5195 --- /dev/null +++ b/sys/src/lib9p/threadsrv.c @@ -0,0 +1,13 @@ +#include +#include +#include +#include +#include <9p.h> + +void +threadsrv(Srv *s) +{ + if(s->forker == nil) + s->forker = threadsrvforker; + srv(s); +}