listen(1): implement one-shot mode flag for listen1 (thanks kivik)
This commit is contained in:
parent
023d957e6b
commit
be8cbcc852
|
@ -18,7 +18,7 @@ listen, listen1, tcp7, tcp9, tcp19, tcp21, tcp23, tcp25, tcp53, tcp110, tcp113,
|
||||||
.PP
|
.PP
|
||||||
.B aux/listen1
|
.B aux/listen1
|
||||||
[
|
[
|
||||||
.B -tv
|
.B -1tv
|
||||||
]
|
]
|
||||||
.RB [ -p
|
.RB [ -p
|
||||||
.IR maxprocs ]
|
.IR maxprocs ]
|
||||||
|
@ -237,7 +237,7 @@ modeled from Inferno's
|
||||||
.\" write out this way so automatic programs
|
.\" write out this way so automatic programs
|
||||||
.\" don't try to make it into a real man page reference.
|
.\" don't try to make it into a real man page reference.
|
||||||
\fIlisten\fR(1).
|
\fIlisten\fR(1).
|
||||||
announces on
|
It announces on
|
||||||
.IR address ,
|
.IR address ,
|
||||||
running
|
running
|
||||||
.I cmd
|
.I cmd
|
||||||
|
@ -255,6 +255,10 @@ is to become
|
||||||
.B none
|
.B none
|
||||||
before listening.
|
before listening.
|
||||||
Option
|
Option
|
||||||
|
.B -1
|
||||||
|
arms a one-shot listener; it terminates listen1
|
||||||
|
upon receiving a single call.
|
||||||
|
Option
|
||||||
.B -v
|
.B -v
|
||||||
causes verbose logging on standard output.
|
causes verbose logging on standard output.
|
||||||
See
|
See
|
||||||
|
|
|
@ -5,12 +5,13 @@
|
||||||
int maxprocs;
|
int maxprocs;
|
||||||
int verbose;
|
int verbose;
|
||||||
int trusted;
|
int trusted;
|
||||||
|
int oneshot;
|
||||||
char *nsfile;
|
char *nsfile;
|
||||||
|
|
||||||
void
|
void
|
||||||
usage(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");
|
exits("usage");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,6 +62,9 @@ main(int argc, char **argv)
|
||||||
ARGBEGIN{
|
ARGBEGIN{
|
||||||
default:
|
default:
|
||||||
usage();
|
usage();
|
||||||
|
case '1':
|
||||||
|
oneshot = 1;
|
||||||
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
trusted = 1;
|
trusted = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -122,41 +126,47 @@ main(int argc, char **argv)
|
||||||
if(nctl < 0)
|
if(nctl < 0)
|
||||||
sysfatal("listen %s: %r", argv[0]);
|
sysfatal("listen %s: %r", argv[0]);
|
||||||
|
|
||||||
|
if(!oneshot)
|
||||||
switch(rfork(RFFDG|RFPROC|RFMEM|RFENVG|RFNAMEG|RFNOTEG|RFREND|nowait)){
|
switch(rfork(RFFDG|RFPROC|RFMEM|RFENVG|RFNAMEG|RFNOTEG|RFREND|nowait)){
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
case -1:
|
case -1:
|
||||||
reject(nctl, ndir, "host overloaded");
|
reject(nctl, ndir, "host overloaded");
|
||||||
close(nctl);
|
close(nctl);
|
||||||
continue;
|
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:
|
default:
|
||||||
close(nctl);
|
close(nctl);
|
||||||
procs++;
|
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