diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/lib9p/post.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/lib9p/post.c')
-rwxr-xr-x | sys/src/lib9p/post.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/sys/src/lib9p/post.c b/sys/src/lib9p/post.c new file mode 100755 index 000000000..b42c7b32c --- /dev/null +++ b/sys/src/lib9p/post.c @@ -0,0 +1,71 @@ +#include <u.h> +#include <libc.h> +#include <fcall.h> +#include <thread.h> +#include <9p.h> +#include <auth.h> + +static void postproc(void*); + +void +_postmountsrv(Srv *s, char *name, char *mtpt, int flag) +{ + int fd[2]; + + if(!s->nopipe){ + if(pipe(fd) < 0) + sysfatal("pipe: %r"); + s->infd = s->outfd = fd[1]; + s->srvfd = fd[0]; + } + if(name) + if(postfd(name, s->srvfd) < 0) + sysfatal("postfd %s: %r", name); + + if(_forker == nil) + sysfatal("no forker"); + _forker(postproc, s, RFNAMEG); + + /* + * Normally the server is posting as the last thing it does + * before exiting, so the correct thing to do is drop into + * a different fd space and close the 9P server half of the + * pipe before trying to mount the kernel half. This way, + * if the file server dies, we don't have a ref to the 9P server + * half of the pipe. Then killing the other procs will drop + * all the refs on the 9P server half, and the mount will fail. + * Otherwise the mount hangs forever. + * + * Libthread in general and acme win in particular make + * it hard to make this fd bookkeeping work out properly, + * so leaveinfdopen is a flag that win sets to opt out of this + * safety net. + */ + if(!s->leavefdsopen){ + rfork(RFFDG); + rendezvous(0, 0); + close(s->infd); + if(s->infd != s->outfd) + close(s->outfd); + } + + if(mtpt){ + if(amount(s->srvfd, mtpt, flag, "") == -1) + sysfatal("mount %s: %r", mtpt); + }else + close(s->srvfd); +} + +static void +postproc(void *v) +{ + Srv *s; + + s = v; + if(!s->leavefdsopen){ + rfork(RFNOTEG); + rendezvous(0, 0); + close(s->srvfd); + } + srv(s); +} |