summaryrefslogtreecommitdiff
path: root/sys/src/cmd/aux
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2023-01-03 19:18:48 +0000
committercinap_lenrek <cinap_lenrek@felloff.net>2023-01-03 19:18:48 +0000
commit68c88ddf3d41bc310e307663ac95ff1ec0353a38 (patch)
tree5935c2c736bb14f05aba5850812377686750bc58 /sys/src/cmd/aux
parent916c7f0bd9295c649ce8f6f8245475d083f4b7bd (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.c87
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);
+}