]> git.lizzy.rs Git - plan9front.git/blob - sys/src/lib9p/post.c
devshr: changed #σc to contain directories
[plan9front.git] / sys / src / lib9p / post.c
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 void
60 _postsharesrv(Srv *s, char *name, char *mtpt, char *desc)
61 {
62         int fd[2];
63
64         if(!s->nopipe){
65                 if(pipe(fd) < 0)
66                         sysfatal("pipe: %r");
67                 s->infd = s->outfd = fd[1];
68                 s->srvfd = fd[0];
69         }
70         if(name)
71                 if(postfd(name, s->srvfd) < 0)
72                         sysfatal("postfd %s: %r", name);
73
74         if(_forker == nil)
75                 sysfatal("no forker");
76         _forker(postproc, s, RFNAMEG);
77
78         /*
79          * Normally the server is posting as the last thing it does
80          * before exiting, so the correct thing to do is drop into
81          * a different fd space and close the 9P server half of the
82          * pipe before trying to mount the kernel half.  This way,
83          * if the file server dies, we don't have a ref to the 9P server
84          * half of the pipe.  Then killing the other procs will drop
85          * all the refs on the 9P server half, and the mount will fail.
86          * Otherwise the mount hangs forever.
87          *
88          * Libthread in general and acme win in particular make
89          * it hard to make this fd bookkeeping work out properly,
90          * so leaveinfdopen is a flag that win sets to opt out of this
91          * safety net.
92          */
93         if(!s->leavefdsopen){
94                 rfork(RFFDG);
95                 rendezvous(0, 0);
96                 close(s->infd);
97                 if(s->infd != s->outfd)
98                         close(s->outfd);
99         }
100
101         if(mtpt){
102                 if(sharefd(mtpt, desc, s->srvfd) < 0)
103                         sysfatal("sharefd %s: %r", mtpt);
104         }else
105                 close(s->srvfd);
106 }
107
108
109 static void
110 postproc(void *v)
111 {
112         Srv *s;
113
114         s = v;
115         if(!s->leavefdsopen){
116                 rfork(RFNOTEG);
117                 rendezvous(0, 0);
118                 close(s->srvfd);
119         }
120         srv(s);
121 }