]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/aux/listen1.c
exec(2): fix prototypes
[plan9front.git] / sys / src / cmd / aux / listen1.c
1 #include <u.h>
2 #include <libc.h>
3 #include <auth.h>
4
5 int maxprocs;
6 int verbose;
7 int trusted;
8
9 void
10 usage(void)
11 {
12         fprint(2, "usage: listen1 [-tv] [-p maxprocs] address cmd args...\n");
13         exits("usage");
14 }
15
16 void
17 becomenone(void)
18 {
19         int fd;
20
21         fd = open("#c/user", OWRITE);
22         if(fd < 0 || write(fd, "none", strlen("none")) < 0)
23                 sysfatal("can't become none: %r");
24         close(fd);
25         if(newns("none", nil) < 0)
26                 sysfatal("can't build namespace: %r");
27 }
28
29 char*
30 remoteaddr(char *dir)
31 {
32         static char buf[128];
33         char *p;
34         int n, fd;
35
36         snprint(buf, sizeof buf, "%s/remote", dir);
37         fd = open(buf, OREAD);
38         if(fd < 0)
39                 return "";
40         n = read(fd, buf, sizeof(buf));
41         close(fd);
42         if(n > 0){
43                 buf[n] = 0;
44                 p = strchr(buf, '!');
45                 if(p)
46                         *p = 0;
47                 return buf;
48         }
49         return "";
50 }
51
52 void
53 main(int argc, char **argv)
54 {
55         char data[60], dir[40], ndir[40], wbuf[64];
56         int ctl, nctl, fd;
57         int wfd, nowait, procs;
58         Dir *d;
59
60         ARGBEGIN{
61         default:
62                 usage();
63         case 't':
64                 trusted = 1;
65                 break;
66         case 'v':
67                 verbose = 1;
68                 break;
69         case 'p':
70                 maxprocs = atoi(EARGF(usage()));
71                 break;
72         }ARGEND
73
74         if(argc < 2)
75                 usage();
76
77         if(!verbose){
78                 close(1);
79                 fd = open("/dev/null", OWRITE);
80                 if(fd != 1){
81                         dup(fd, 1);
82                         close(fd);
83                 }
84         }
85
86         if(!trusted)
87                 becomenone();
88
89         print("listen started\n");
90         ctl = announce(argv[0], dir);
91         if(ctl < 0)
92                 sysfatal("announce %s: %r", argv[0]);
93
94         wfd = -1;
95         nowait = RFNOWAIT;
96         if(maxprocs > 0){
97                 snprint(wbuf, sizeof(wbuf), "/proc/%d/wait", getpid());
98                 if((wfd = open(wbuf, OREAD)) >= 0)
99                         nowait = 0;
100         }
101         procs = 0;
102         for(;;){
103                 if(nowait == 0 && (procs >= maxprocs || (procs % 8) == 0))
104                         while(procs > 0){
105                                 if(procs < maxprocs){
106                                         d = dirfstat(wfd);
107                                         if(d == nil || d->length == 0){
108                                                 free(d);
109                                                 break;
110                                         }
111                                         free(d);
112                                 }
113                                 if(read(wfd, wbuf, sizeof(wbuf)) > 0)
114                                         procs--;
115                         }
116
117                 nctl = listen(dir, ndir);
118                 if(nctl < 0)
119                         sysfatal("listen %s: %r", argv[0]);
120
121                 switch(rfork(RFFDG|RFPROC|RFMEM|RFENVG|RFNAMEG|RFNOTEG|RFREND|nowait)){
122                 case -1:
123                         reject(nctl, ndir, "host overloaded");
124                         close(nctl);
125                         continue;
126                 case 0:
127                         fd = accept(nctl, ndir);
128                         if(fd < 0){
129                                 fprint(2, "accept %s: can't open  %s/data: %r\n",
130                                         argv[0], ndir);
131                                 _exits(0);
132                         }
133                         print("incoming call for %s from %s in %s\n", argv[0],
134                                 remoteaddr(ndir), ndir);
135                         fprint(nctl, "keepalive");
136                         close(ctl);
137                         close(nctl);
138                         if(wfd >= 0)
139                                 close(wfd);
140                         putenv("net", ndir);
141                         snprint(data, sizeof data, "%s/data", ndir);
142                         bind(data, "/dev/cons", MREPL);
143                         dup(fd, 0);
144                         dup(fd, 1);
145                         /* dup(fd, 2); keep stderr */
146                         close(fd);
147                         exec(argv[1], argv+1);
148                         if(argv[1][0] != '/')
149                                 exec(smprint("/bin/%s", argv[1]), argv+1);
150                         fprint(2, "%s: exec: %r\n", argv0);
151                         exits(nil);
152                 default:
153                         close(nctl);
154                         procs++;
155                         break;
156                 }
157         }
158 }