ref: 7bc9df198eb58491ebe50ddfb663ebd405b521e8
parent: 1855315a5bd797443155520973cf0848fb789477
author: cinap_lenrek <cinap_lenrek@felloff.net>
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");}
}
--
⑨