listen(1): implement one-shot mode flag for listen1 (thanks kivik)
This commit is contained in:
parent
023d957e6b
commit
be8cbcc852
2 changed files with 44 additions and 30 deletions
|
@ -18,7 +18,7 @@ listen, listen1, tcp7, tcp9, tcp19, tcp21, tcp23, tcp25, tcp53, tcp110, tcp113,
|
|||
.PP
|
||||
.B aux/listen1
|
||||
[
|
||||
.B -tv
|
||||
.B -1tv
|
||||
]
|
||||
.RB [ -p
|
||||
.IR maxprocs ]
|
||||
|
@ -237,7 +237,7 @@ modeled from Inferno's
|
|||
.\" write out this way so automatic programs
|
||||
.\" don't try to make it into a real man page reference.
|
||||
\fIlisten\fR(1).
|
||||
announces on
|
||||
It announces on
|
||||
.IR address ,
|
||||
running
|
||||
.I cmd
|
||||
|
@ -255,6 +255,10 @@ is to become
|
|||
.B none
|
||||
before listening.
|
||||
Option
|
||||
.B -1
|
||||
arms a one-shot listener; it terminates listen1
|
||||
upon receiving a single call.
|
||||
Option
|
||||
.B -v
|
||||
causes verbose logging on standard output.
|
||||
See
|
||||
|
|
|
@ -5,12 +5,13 @@
|
|||
int maxprocs;
|
||||
int verbose;
|
||||
int trusted;
|
||||
int oneshot;
|
||||
char *nsfile;
|
||||
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
fprint(2, "usage: listen1 [-tv] [-p maxprocs] [-n namespace] address cmd args...\n");
|
||||
fprint(2, "usage: listen1 [-1tv] [-p maxprocs] [-n namespace] address cmd args...\n");
|
||||
exits("usage");
|
||||
}
|
||||
|
||||
|
@ -61,6 +62,9 @@ main(int argc, char **argv)
|
|||
ARGBEGIN{
|
||||
default:
|
||||
usage();
|
||||
case '1':
|
||||
oneshot = 1;
|
||||
break;
|
||||
case 't':
|
||||
trusted = 1;
|
||||
break;
|
||||
|
@ -122,41 +126,47 @@ main(int argc, char **argv)
|
|||
if(nctl < 0)
|
||||
sysfatal("listen %s: %r", argv[0]);
|
||||
|
||||
if(!oneshot)
|
||||
switch(rfork(RFFDG|RFPROC|RFMEM|RFENVG|RFNAMEG|RFNOTEG|RFREND|nowait)){
|
||||
case 0:
|
||||
break;
|
||||
case -1:
|
||||
reject(nctl, ndir, "host overloaded");
|
||||
close(nctl);
|
||||
continue;
|
||||
case 0:
|
||||
fd = accept(nctl, ndir);
|
||||
if(fd < 0){
|
||||
fprint(2, "accept %s: can't open %s/data: %r\n",
|
||||
argv[0], ndir);
|
||||
_exits(0);
|
||||
}
|
||||
print("incoming call for %s from %s in %s\n", argv[0],
|
||||
remoteaddr(ndir), ndir);
|
||||
fprint(nctl, "keepalive");
|
||||
close(ctl);
|
||||
close(nctl);
|
||||
if(wfd >= 0)
|
||||
close(wfd);
|
||||
putenv("net", ndir);
|
||||
snprint(data, sizeof data, "%s/data", ndir);
|
||||
bind(data, "/dev/cons", MREPL);
|
||||
dup(fd, 0);
|
||||
dup(fd, 1);
|
||||
/* dup(fd, 2); keep stderr */
|
||||
close(fd);
|
||||
exec(argv[1], argv+1);
|
||||
if(argv[1][0] != '/')
|
||||
exec(smprint("/bin/%s", argv[1]), argv+1);
|
||||
fprint(2, "%s: exec: %r\n", argv0);
|
||||
exits(nil);
|
||||
default:
|
||||
close(nctl);
|
||||
procs++;
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
fd = accept(nctl, ndir);
|
||||
if(fd < 0){
|
||||
fprint(2, "accept %s: can't open %s/data: %r\n", argv[0], ndir);
|
||||
if(oneshot){
|
||||
close(nctl);
|
||||
continue;
|
||||
}
|
||||
exits("accept");
|
||||
}
|
||||
|
||||
print("incoming call for %s from %s in %s\n", argv[0], remoteaddr(ndir), ndir);
|
||||
fprint(nctl, "keepalive");
|
||||
close(ctl);
|
||||
close(nctl);
|
||||
if(wfd >= 0)
|
||||
close(wfd);
|
||||
putenv("net", ndir);
|
||||
snprint(data, sizeof data, "%s/data", ndir);
|
||||
bind(data, "/dev/cons", MREPL);
|
||||
dup(fd, 0);
|
||||
dup(fd, 1);
|
||||
/* dup(fd, 2); keep stderr */
|
||||
close(fd);
|
||||
exec(argv[1], argv+1);
|
||||
if(argv[1][0] != '/')
|
||||
exec(smprint("/bin/%s", argv[1]), argv+1);
|
||||
fprint(2, "%s: exec: %r\n", argv0);
|
||||
exits("exec");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue