diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2023-01-03 19:18:48 +0000 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2023-01-03 19:18:48 +0000 |
commit | 68c88ddf3d41bc310e307663ac95ff1ec0353a38 (patch) | |
tree | 5935c2c736bb14f05aba5850812377686750bc58 /sys/src/cmd/aux | |
parent | 916c7f0bd9295c649ce8f6f8245475d083f4b7bd (diff) |
dial(1): add dial command similar to plan9port
This is similar to plan9port dial(1), but names aux/dial
because we already have the expect(1) commands in
/bin/dial.
One difference is that our dial allows specifying a
command, similar to aux/listen1 that will get connected
it standard input and output to the network connection.
Diffstat (limited to 'sys/src/cmd/aux')
-rw-r--r-- | sys/src/cmd/aux/dial.c | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/sys/src/cmd/aux/dial.c b/sys/src/cmd/aux/dial.c new file mode 100644 index 000000000..b251daf47 --- /dev/null +++ b/sys/src/cmd/aux/dial.c @@ -0,0 +1,87 @@ +#include <u.h> +#include <libc.h> + +int eflag; +int nopts; +char *opts[16]; + +void +xfer(int from, int to) +{ + char buf[8192]; + int n; + + while((n = read(from, buf, sizeof buf)) > 0) + if(write(to, buf, n) < 0) + break; +} + +void +usage(void) +{ + fprint(2, "usage: %s [-e] [-o msg]... addr [cmd [args]...]\n", argv0); + exits("usage"); +} + +void +main(int argc, char *argv[]) +{ + int i, fd, cfd, pid; + + ARGBEGIN { + case 'e': + eflag = 1; + break; + case 'o': + if(nopts >= nelem(opts)){ + fprint(2, "%s: too many -o options\n", argv0); + exits("opts"); + } + opts[nopts++] = EARGF(usage()); + break; + default: + usage(); + } ARGEND; + + if(--argc < 0) + usage(); + fd = dial(*argv++, nil, nil, &cfd); + if(fd < 0){ + fprint(2, "%s: dial: %r\n", argv0); + exits("dial"); + } + for(i = 0; i < nopts; i++) + write(cfd, opts[i], strlen(opts[i])); + close(cfd); + + if(argc > 0){ + dup(fd, 0); + dup(fd, 1); + /* dup(fd, 2); keep stderr */ + if(fd > 2) close(fd); + + exec(argv[0], argv); + if(argv[0][0] != '/') + exec(smprint("/bin/%s", argv[0]), argv); + fprint(2, "%s: exec: %r\n", argv0); + exits("exec"); + } + + pid = fork(); + switch(pid){ + case -1: + fprint(2, "%s: fork: %r", argv0); + exits("fork"); + case 0: + xfer(0, fd); + if(eflag) exits(nil); + pid = getppid(); + break; + default: + xfer(fd, 1); + break; + } + postnote(PNPROC, pid, "kill"); + waitpid(); + exits(nil); +} |