aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2026-04-01 00:56:53 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2026-04-01 00:56:53 +0000
commitc867dad6b9ad48f85cf1ca9182ac4d55c2d1acf7 (patch)
tree6030e710db987746bbea594ed05cbeea4d8ae026 /src
parentaa270d5e3ed791f77f6ceda9cee15276c6a1692f (diff)
downloadexecline-c867dad6b9ad48f85cf1ca9182ac4d55c2d1acf7.tar.gz
Add -v option to redirfd
Diffstat (limited to 'src')
-rw-r--r--src/execline/deps-exe/redirfd1
-rw-r--r--src/execline/redirfd.c122
2 files changed, 81 insertions, 42 deletions
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) ;
}