add the listen1 command.
[akaros.git] / tests / listen1.c
1 /* 
2  * This file is part of the UCB release of Plan 9. It is subject to the license
3  * terms in the LICENSE file found in the top-level directory of this
4  * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
5  * part of the UCB release of Plan 9, including this file, may be copied,
6  * modified, propagated, or distributed except according to the terms contained
7  * in the LICENSE file.
8  */
9
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <parlib.h>
13 #include <unistd.h>
14 #include <signal.h>
15 #include <iplib.h>
16 #include <icmp.h>
17 #include <ctype.h>
18 #include <pthread.h>
19 #include <spinlock.h>
20 #include <timing.h>
21 #include <tsc-compat.h>
22 #include <printf-ext.h>
23 #include <alarm.h>
24 #include <ndb.h>
25 #include <fcntl.h>
26
27 int verbose;
28
29 void
30 usage(void)
31 {
32         fprintf(stderr, "usage: listen1 [-tv] address cmd args...\n");
33         fprintf(stderr, "usage");
34         exit(1);
35 }
36
37 char*
38 remoteaddr(char *dir)
39 {
40         static char buf[128];
41         char *p;
42         int n, fd;
43
44         snprintf(buf, sizeof buf, "%s/remote", dir);
45         fd = open(buf, O_RDONLY);
46         if(fd < 0)
47                 return "";
48         n = read(fd, buf, sizeof(buf));
49         close(fd);
50         if(n > 0){
51                 buf[n] = 0;
52                 p = strchr(buf, '!');
53                 if(p)
54                         *p = 0;
55                 return buf;
56         }
57         return "";
58 }
59
60 void
61 main(int argc, char **argv)
62 {
63         static char data[1024], dir[1024], ndir[1024];
64         int ctl, nctl, fd;
65
66         verbose = 1;
67
68         if(!verbose){
69                 close(1);
70                 fd = open("/dev/null", O_WRONLY);
71                 if(fd != 1){
72                         dup2(fd, 1);
73                         close(fd);
74                 }
75         }
76
77         argc--, argv++;
78         printf("listen started\n");
79         ctl = announce(argv[0], dir);
80         if(ctl < 0){
81                 fprintf(stderr, "announce %s: %r", argv[0]);
82                 exit(1);
83         }
84
85         for(;;){
86                 nctl = listen(dir, ndir);
87                 if(nctl < 0){
88                         fprintf(stderr, "listen %s: %r", argv[0]);
89                         exit(1);
90                 }
91
92                 //switch(rfork(RFFDG|RFPROC|RFNOWAIT|RFENVG|RFNAMEG|RFNOTEG)){
93                 switch(fork()){
94                 case -1:
95                         reject(nctl, ndir, "host overloaded");
96                         close(nctl);
97                         continue;
98                 case 0:
99                         fd = accept(nctl, ndir);
100                         if(fd < 0){
101                                 fprintf(stderr, "accept %s: can't open  %s/data: %r\n",
102                                         argv[0], ndir);
103                                 exit(1);
104                         }
105                         printf("incoming call for %s from %s in %s\n", argv[0],
106                                 remoteaddr(ndir), ndir);
107                         //fprintf(nctl, "keepalive");
108                         close(ctl);
109                         close(nctl);
110                         //putenv("net", ndir);
111                         /* this is for children that open /dev/cons. Too bad. 
112                         snprintf(data, sizeof data, "%s/data", ndir);
113                         bind(data, "/dev/cons", MREPL);
114                         */
115                         dup2(fd, 0);
116                         dup2(fd, 1);
117                         dup2(fd, 2);
118                         close(fd);
119                         execv(argv[1], argv+1);
120 //                      if(argv[1][0] != '/')
121 //                              exec(smprintf("%s", argv[1]), argv+1);
122                         fprintf(stderr, "exec: %r\n");
123                         exit(1);
124                 default:
125                         close(nctl);
126                         break;
127                 }
128         }
129 }