ref: be8cbcc8524cee8328bce97200f5d7e22abbb3da
parent: 023d957e6b80f88584fdff30a95be6330613b27a
author: cinap_lenrek <[email protected]>
date: Sun Feb 2 15:31:48 EST 2020
listen(1): implement one-shot mode flag for listen1 (thanks kivik)
--- a/sys/man/8/listen
+++ b/sys/man/8/listen
@@ -18,7 +18,7 @@
.PP
.B aux/listen1
[
-.B -tv
+.B -1tv
]
.RB [ -p
.IR maxprocs ]
@@ -237,7 +237,7 @@
.\" 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
@@ -254,6 +254,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.
--- a/sys/src/cmd/aux/listen1.c
+++ b/sys/src/cmd/aux/listen1.c
@@ -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 @@
ARGBEGIN{
default:
usage();
+ case '1':
+ oneshot = 1;
+ break;
case 't':
trusted = 1;
break;
@@ -122,41 +126,47 @@
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");
}
}