diff options
| author | Laurent Bercot <ska-skaware@skarnet.org> | 2026-04-01 00:56:53 +0000 |
|---|---|---|
| committer | Laurent Bercot <ska-skaware@skarnet.org> | 2026-04-01 00:56:53 +0000 |
| commit | c867dad6b9ad48f85cf1ca9182ac4d55c2d1acf7 (patch) | |
| tree | 6030e710db987746bbea594ed05cbeea4d8ae026 | |
| parent | aa270d5e3ed791f77f6ceda9cee15276c6a1692f (diff) | |
| download | execline-c867dad6b9ad48f85cf1ca9182ac4d55c2d1acf7.tar.gz | |
Add -v option to redirfd
| -rw-r--r-- | doc/redirfd.html | 18 | ||||
| -rw-r--r-- | package/deps-build | 4 | ||||
| -rw-r--r-- | package/deps.mak | 4 | ||||
| -rw-r--r-- | src/execline/deps-exe/redirfd | 1 | ||||
| -rw-r--r-- | src/execline/redirfd.c | 122 |
5 files changed, 102 insertions, 47 deletions
diff --git a/doc/redirfd.html b/doc/redirfd.html index 9dbe409..17b7303 100644 --- a/doc/redirfd.html +++ b/doc/redirfd.html @@ -26,7 +26,8 @@ executes a program. <h2> Interface </h2> <pre> - redirfd [ -r | -w | -u | -a | -x ] [ -n ] [ -b ] <em>fd</em> <em>file</em> <em>prog...</em> + redirfd [ -r | -w | -u | -a | -x ] [ -n ] [ -b ] <em>fd</em> <em>file</em> <em>prog...</em><br> + redirfd [ -r | -w | -u | -a | -x ] [ -n ] [ -b ] [ -v ] [ -e | -E ] <em>var</em> <em>file</em> <em>prog...</em><br> </pre> <p> @@ -34,6 +35,13 @@ executes a program. to <em>file</em>, then execs into <em>prog...</em>. </p> +<p> +When run with the <tt>-v</tt> option, the first argument is instead +interpreted as an environment variable. <tt>redirfd</tt> opens <em>file</em>, +stores the obtained file descriptor into environment variable <em>var</em>, +then execs into <em>prog...</em>. +</p> + <h2> Options </h2> <p> @@ -51,6 +59,14 @@ the -n and -b options may be added in any case. <li> <tt>-b</tt> : change mode of <em>file</em> after opening it: to non-blocking mode if the <tt>-n</tt> option was not given, to blocking mode if it was. </li> + <li> <tt>-v</tt> : interpret the first argument as an environment variable, +and stores the new file descriptor into that variable before execing. </li> + <li> <tt>-e</tt> : no autoimport. This is the default. </li> + <li> <tt>-E</tt> : autoimport. This is only useful with the <tt>-v</tt> option. +Instead of executing +<em>prog...</em>, execute <tt>importas -uSi <em>var</em> <em>prog...</em></tt>. +This substitutes <em>var</em> into the command line instead of putting it into +the environment. </li> </ul> <h2> Notes </h2> diff --git a/package/deps-build b/package/deps-build index 9f5db2d..6381375 100644 --- a/package/deps-build +++ b/package/deps-build @@ -1,2 +1,2 @@ -true true /package/prog/skalibs 2.14.5.0 libskarnet -$usensss false /package/admin/nsss 0.2.1.1 libnsss +true true /package/prog/skalibs 2.15.0.0 libskarnet +$usensss false /package/admin/nsss 0.2.1.2 libnsss diff --git a/package/deps.mak b/package/deps.mak index a1ef3ab..44338fd 100644 --- a/package/deps.mak +++ b/package/deps.mak @@ -45,7 +45,7 @@ src/execline/pipeline.o src/execline/pipeline.lo: src/execline/pipeline.c src/in src/execline/piperw.o src/execline/piperw.lo: src/execline/piperw.c src/execline/posix-cd.o src/execline/posix-cd.lo: src/execline/posix-cd.c src/execline/posix-umask.o src/execline/posix-umask.lo: src/execline/posix-umask.c -src/execline/redirfd.o src/execline/redirfd.lo: src/execline/redirfd.c +src/execline/redirfd.o src/execline/redirfd.lo: src/execline/redirfd.c src/include/execline/execline.h src/execline/runblock.o src/execline/runblock.lo: src/execline/runblock.c src/include/execline/execline.h src/execline/shift.o src/execline/shift.lo: src/execline/shift.c src/include/execline/execline.h src/execline/trap.o src/execline/trap.lo: src/execline/trap.c src/include/execline/execline.h @@ -170,7 +170,7 @@ posix-cd: src/execline/posix-cd.o -lskarnet posix-umask: EXTRA_LIBS := posix-umask: src/execline/posix-umask.o -lskarnet redirfd: EXTRA_LIBS := -redirfd: src/execline/redirfd.o -lskarnet +redirfd: src/execline/redirfd.o ${LIBEXECLINE} -lskarnet runblock: EXTRA_LIBS := runblock: src/execline/runblock.o ${LIBEXECLINE} -lskarnet shift: EXTRA_LIBS := diff --git a/src/execline/deps-exe/redirfd b/src/execline/deps-exe/redirfd index e7187fe..97021b5 100644 --- a/src/execline/deps-exe/redirfd +++ b/src/execline/deps-exe/redirfd @@ -1 +1,2 @@ +${LIBEXECLINE} -lskarnet diff --git a/src/execline/redirfd.c b/src/execline/redirfd.c index 4dc829d..e7f491b 100644 --- a/src/execline/redirfd.c +++ b/src/execline/redirfd.c @@ -3,64 +3,102 @@ #include <fcntl.h> #include <errno.h> -#include <skalibs/sgetopt.h> +#include <skalibs/uint64.h> #include <skalibs/types.h> -#include <skalibs/strerr.h> #include <skalibs/djbunix.h> -#include <skalibs/exec.h> +#include <skalibs/envexec.h> -#define USAGE "redirfd -[ r | w | u | a | x ] [ -n ] [ -b ] fd file prog..." +#include <execline/execline.h> + +#define USAGE "redirfd -[ r | w | u | a | x ] [ -N | -n ] [ -b ] [ -v ] [ -E | -e ] fd file prog..." #define dieusage() strerr_dieusage(100, USAGE) +enum golb_e +{ + GOLB_READ = 0x0001, + GOLB_WRITE = 0x0002, + GOLB_CREAT = 0x0004, + GOLB_APPEND = 0x0008, + GOLB_TRUNC = 0x0010, + GOLB_EXCL = 0x0020, + GOLB_NONBLOCK = 0x0040, + GOLB_CHANGEMODE = 0x0100, + GOLB_VAR = 0x0200, + GOLB_AUTOIMPORT = 0x0400, +} ; + int main (int argc, char const *const *argv) { - int fd, fd2 ; - unsigned int flags = 0 ; - int what = -1 ; - int changemode = 0 ; - PROG = "redirfd" ; + static gol_bool const rgolb[] = { - subgetopt l = SUBGETOPT_ZERO ; - for (;;) - { - int opt = subgetopt_r(argc, argv, "rwuaxnb", &l) ; - if (opt == -1) break ; - switch (opt) - { - case 'r' : what = O_RDONLY ; flags &= ~(O_APPEND|O_CREAT|O_TRUNC|O_EXCL) ; break ; - case 'w' : what = O_WRONLY ; flags |= O_CREAT|O_TRUNC ; flags &= ~(O_APPEND|O_EXCL) ; break ; - case 'u' : what = O_RDWR ; flags &= ~(O_APPEND|O_CREAT|O_TRUNC|O_EXCL) ; break ; - case 'a' : what = O_WRONLY ; flags |= O_CREAT|O_APPEND ; flags &= ~(O_TRUNC|O_EXCL) ; break ; - case 'x' : what = O_WRONLY ; flags |= O_CREAT|O_EXCL ; flags &= ~(O_APPEND|O_TRUNC) ; break ; - case 'n' : flags |= O_NONBLOCK ; break ; - case 'b' : changemode = 1 ; break ; - default : dieusage() ; - } - } - argc -= l.ind ; argv += l.ind ; - } - if ((argc < 3) || (what == -1)) dieusage() ; - if (!uint0_scan(argv[0], (unsigned int *)&fd)) dieusage() ; - flags |= what ; - fd2 = open3(argv[1], flags, 0666) ; - if ((fd2 == -1) && (what == O_WRONLY) && (errno == ENXIO)) + { .so = 'r', .lo = 0, .clear = GOLB_WRITE | GOLB_APPEND | GOLB_CREAT | GOLB_TRUNC | GOLB_EXCL, .set = GOLB_READ }, + { .so = 'w', .lo = 0, .clear = GOLB_READ | GOLB_APPEND | GOLB_EXCL, .set = GOLB_WRITE | GOLB_CREAT | GOLB_TRUNC }, + { .so = 'u', .lo = 0, .clear = GOLB_APPEND | GOLB_CREAT | GOLB_TRUNC | GOLB_EXCL, .set = GOLB_READ | GOLB_WRITE }, + { .so = 'a', .lo = 0, .clear = GOLB_READ | GOLB_TRUNC | GOLB_EXCL, .set = GOLB_WRITE | GOLB_CREAT | GOLB_APPEND }, + { .so = 'x', .lo = 0, .clear = GOLB_READ | GOLB_APPEND | GOLB_TRUNC, .set = GOLB_WRITE | GOLB_CREAT | GOLB_EXCL }, + { .so = 'N', .lo = "block", .clear = GOLB_NONBLOCK, .set = 0 }, + { .so = 'n', .lo = "nonblock", .clear = 0, .set = GOLB_NONBLOCK }, + { .so = 'b', .lo = "switch-block", .clear = 0, .set = GOLB_CHANGEMODE }, + { .so = 'v', .lo = "variable", .clear = 0, .set = GOLB_VAR }, + { .so = 'e', .lo = "no-autoimport", .clear = GOLB_AUTOIMPORT, .set = 0 }, + { .so = 'E', .lo = "autoimport", .clear = 0, .set = GOLB_AUTOIMPORT }, + { .so = 0, .lo = "no-read", .clear = GOLB_READ, .set = 0 }, + { .so = 0, .lo = "read", .clear = 0, .set = GOLB_READ }, + { .so = 0, .lo = "no-write", .clear = GOLB_WRITE, .set = 0 }, + { .so = 0, .lo = "write", .clear = 0, .set = GOLB_WRITE }, + { .so = 0, .lo = "no-create", .clear = GOLB_CREAT, .set = 0 }, + { .so = 0, .lo = "create", .clear = 0, .set = GOLB_CREAT }, + { .so = 0, .lo = "no-append", .clear = GOLB_APPEND, .set = 0 }, + { .so = 0, .lo = "append", .clear = 0, .set = GOLB_APPEND }, + { .so = 0, .lo = "no-trunc", .clear = GOLB_TRUNC, .set = 0 }, + { .so = 0, .lo = "trunc", .clear = 0, .set = GOLB_TRUNC }, + { .so = 0, .lo = "no-excl", .clear = GOLB_EXCL, .set = 0 }, + { .so = 0, .lo = "excl", .clear = 0, .set = GOLB_EXCL }, + } ; + uint64_t wgolb = 0 ; + unsigned int golc ; + int fd ; + unsigned int fdto ; + unsigned int flags ; + PROG = "redirfd" ; + + golc = gol_main(argc, argv, rgolb, sizeof(rgolb)/sizeof(gol_bool), 0, 0, &wgolb, 0) ; + argc -= golc ; argv += golc ; + if (argc < 3) dieusage() ; + if (!(wgolb & (GOLB_READ | GOLB_WRITE))) dieusage() ; + if (!(wgolb & GOLB_VAR)) + if (!uint0_scan(argv[0], &fdto)) dieusage() ; + + flags = + (wgolb & GOLB_WRITE ? wgolb & GOLB_READ ? O_RDWR : O_WRONLY : O_RDONLY) | + (wgolb & GOLB_CREAT ? O_CREAT : 0) | + (wgolb & GOLB_APPEND ? O_APPEND : 0) | + (wgolb & GOLB_TRUNC ? O_TRUNC : 0) | + (wgolb & GOLB_EXCL ? O_EXCL : 0) | + (wgolb & GOLB_NONBLOCK ? O_NONBLOCK : 0) ; + + fd = open3(argv[1], flags, 0666) ; + if (fd == -1 && wgolb & GOLB_WRITE && errno == ENXIO) { int fdr = open_read(argv[1]) ; if (fdr == -1) strerr_diefu2sys(111, "open_read ", argv[1]) ; - fd2 = open3(argv[1], flags, 0666) ; + fd = open3(argv[1], flags, 0666) ; fd_close(fdr) ; } - if (fd2 == -1) strerr_diefu2sys(111, "open ", argv[1]) ; - if (fd_move(fd, fd2) == -1) + if (fd == -1) strerr_diefu2sys(111, "open ", argv[1]) ; + + if (wgolb & GOLB_CHANGEMODE) + if ((wgolb & GOLB_NONBLOCK ? ndelay_off(fd) : ndelay_on(fd)) == -1) + strerr_diefu1sys(111, "change blocking mode") ; + if (wgolb & GOLB_VAR) { char fmt[UINT_FMT] ; - fmt[uint_fmt(fmt, fd2)] = 0 ; - strerr_diefu4sys(111, "move fd ", fmt, " to fd ", argv[0]) ; + fmt[uint_fmt(fmt, fd)] = 0 ; + el_modif_and_exec(argv+2, argv[0], fmt, !!(wgolb & GOLB_AUTOIMPORT)) ; } - if (changemode) + else { - if (((flags & O_NONBLOCK) ? ndelay_off(fd) : ndelay_on(fd)) < 0) - strerr_diefu1sys(111, "change blocking mode") ; + if (fd_move(fdto, fd) == -1) strerr_diefu1sys(111, "fd_move") ; + xexec(argv+2) ; } - xexec(argv+2) ; } |
