1 #include <u.h> 2 #include <libc.h> 3 #include <fcall.h> 4 #include <thread.h> 5 #include <9p.h> 6 #include <auth.h> 7 8 static void postproc(void*); 9 10 void 11 _postmountsrv(Srv *s, char *name, char *mtpt, int flag) 12 { 13 int fd[2]; 14 15 if(!s->nopipe){ 16 if(pipe(fd) < 0) 17 sysfatal("pipe: %r"); 18 s->infd = s->outfd = fd[1]; 19 s->srvfd = fd[0]; 20 } 21 if(name) 22 if(postfd(name, s->srvfd) < 0) 23 sysfatal("postfd %s: %r", name); 24 25 if(_forker == nil) 26 sysfatal("no forker"); 27 _forker(postproc, s, RFNAMEG); 28 29 /* 30 * Normally the server is posting as the last thing it does 31 * before exiting, so the correct thing to do is drop into 32 * a different fd space and close the 9P server half of the 33 * pipe before trying to mount the kernel half. This way, 34 * if the file server dies, we don't have a ref to the 9P server 35 * half of the pipe. Then killing the other procs will drop 36 * all the refs on the 9P server half, and the mount will fail. 37 * Otherwise the mount hangs forever. 38 * 39 * Libthread in general and acme win in particular make 40 * it hard to make this fd bookkeeping work out properly, 41 * so leaveinfdopen is a flag that win sets to opt out of this 42 * safety net. 43 */ 44 if(!s->leavefdsopen){ 45 rfork(RFFDG); 46 rendezvous(0, 0); 47 close(s->infd); 48 if(s->infd != s->outfd) 49 close(s->outfd); 50 } 51 52 if(mtpt){ 53 if(amount(s->srvfd, mtpt, flag, "") == -1) 54 sysfatal("mount %s: %r", mtpt); 55 }else 56 close(s->srvfd); 57 } 58 59 static void 60 postproc(void *v) 61 { 62 Srv *s; 63 64 s = v; 65 if(!s->leavefdsopen){ 66 rfork(RFNOTEG); 67 rendezvous(0, 0); 68 close(s->srvfd); 69 } 70 srv(s); 71 } 72