summaryrefslogtreecommitdiff
path: root/src/posix
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2023-02-02 05:29:17 +0000
committerLaurent Bercot <ska@appnovation.com>2023-02-02 05:29:17 +0000
commit9d55d49dad0f4cb90e6ff2f9b1c3bc46a6fcf05f (patch)
treeea63cf6dd496942aa194e864f37cc56229d596fb /src/posix
parentedf81b0d16322e5d49ec22f394b669d9094daac1 (diff)
downloadexecline-9d55d49dad0f4cb90e6ff2f9b1c3bc46a6fcf05f.tar.xz
Multicall improvements
Signed-off-by: Laurent Bercot <ska@appnovation.com>
Diffstat (limited to 'src/posix')
-rw-r--r--src/posix/deps-exe/posix-cd1
-rw-r--r--src/posix/deps-exe/posix-umask1
-rw-r--r--src/posix/posix-cd.c160
-rw-r--r--src/posix/posix-umask.c174
-rw-r--r--src/posix/posix-umask.txt37
5 files changed, 0 insertions, 373 deletions
diff --git a/src/posix/deps-exe/posix-cd b/src/posix/deps-exe/posix-cd
deleted file mode 100644
index e7187fe..0000000
--- a/src/posix/deps-exe/posix-cd
+++ /dev/null
@@ -1 +0,0 @@
--lskarnet
diff --git a/src/posix/deps-exe/posix-umask b/src/posix/deps-exe/posix-umask
deleted file mode 100644
index e7187fe..0000000
--- a/src/posix/deps-exe/posix-umask
+++ /dev/null
@@ -1 +0,0 @@
--lskarnet
diff --git a/src/posix/posix-cd.c b/src/posix/posix-cd.c
deleted file mode 100644
index e9bfd35..0000000
--- a/src/posix/posix-cd.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/* ISC license. */
-
-#include <sys/stat.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <limits.h>
-#include <locale.h>
-
-#include <skalibs/bytestr.h>
-#include <skalibs/sgetopt.h>
-#include <skalibs/allreadwrite.h>
-#include <skalibs/strerr.h>
-#include <skalibs/stralloc.h>
-#include <skalibs/djbunix.h>
-#include <skalibs/env.h>
-#include <skalibs/exec.h>
-
-#define USAGE "posix-cd [ -L | -P ] [ - | path ] [ prog... ]"
-#define dieusage() strerr_dieusage(100, USAGE)
-#define dienomem() strerr_diefu1sys(111, "stralloc_catb")
-
-int main (int argc, char const **argv)
-{
- int phy = 0 ;
- int dopwd = 0 ;
- char const *where ;
- int got = 0 ;
- stralloc sa = STRALLOC_ZERO ;
- PROG = "posix-cd" ;
- setlocale(LC_ALL, "") ; /* yeah, as if */
-
- {
- subgetopt l = SUBGETOPT_ZERO ;
- for (;;)
- {
- int opt = subgetopt_r(argc, argv, "LP", &l) ;
- if (opt == -1) break ;
- switch (opt)
- {
- case 'L' : phy = 0 ; break ;
- case 'P' : phy = 1 ; break ;
- default : dieusage() ;
- }
- }
- argc -= l.ind ; argv += l.ind ;
- }
- if (!argc) where = getenv("HOME") ;
- else
- {
- where = *argv++ ;
- if (!strcmp(where, "-"))
- {
- where = getenv("OLDPWD") ;
- dopwd = 1 ;
- }
- }
- if (!where || !where[0]) dieusage() ;
-
- if (!(where[0] == '/' || (where[0] == '.' && (!where[1] || where[1] == '/' || (where[1] == '.' && (!where[2] || where[2] == '/'))))))
- {
- char const *cdpath = getenv("CDPATH") ;
- if (cdpath)
- {
- size_t pos = 0 ;
- size_t len = strlen(cdpath) ;
- while (pos < len)
- {
- struct stat st ;
- size_t m = byte_chr(cdpath + pos, len - pos, ':') ;
- sa.len = 0 ;
- if (m)
- {
- if (!stralloc_catb(&sa, cdpath + pos, m)) dienomem() ;
- if (cdpath[pos + m - 1] != '/' && !stralloc_catb(&sa, "/", 1)) dienomem() ;
- }
- else if (!stralloc_catb(&sa, "./", 2)) dienomem() ;
- if (!stralloc_cats(&sa, where) || !stralloc_0(&sa)) dienomem() ;
- if (!stat(sa.s, &st) && S_ISDIR(st.st_mode))
- {
- got = 1 ;
- dopwd = 1 ;
- break ;
- }
- pos += m+1 ;
- }
- }
- }
-
- if (!got && (!stralloc_cats(&sa, where) || !stralloc_0(&sa))) dienomem() ;
-
- {
- size_t sabase = sa.len ;
- if (sagetcwd(&sa) < 0) strerr_diefu1sys(111, "getcwd") ;
- if (!stralloc_0(&sa)) dienomem() ;
- if (!env_mexec("OLDPWD", sa.s + sabase)) dienomem() ;
- sa.len = sabase ;
- }
-
- if (!phy)
- {
- char const *x = getenv("PWD") ;
- if (x && sa.s[0] != '/')
- {
- size_t len = strlen(x) ;
- int doslash = len && x[len-1] != '/' ;
- if (!stralloc_insertb(&sa, 0, x, len + doslash)) dienomem() ;
- if (doslash) sa.s[len] = '/' ;
- }
- {
- stralloc tmp = STRALLOC_ZERO ;
- if (!stralloc_ready(&tmp, sa.len + 2)) dienomem() ;
- tmp.len = path_canonicalize(tmp.s, sa.s, 1) ;
- if (!tmp.len++)
- strerr_diefu4sys(111, "canonicalize ", sa.s, ": problem with ", tmp.s) ;
- stralloc_free(&sa) ;
- sa = tmp ;
- }
- if (!env_mexec("PWD", sa.s)) dienomem() ;
-#ifdef PATH_MAX
- if (sa.len > PATH_MAX && strlen(where) < PATH_MAX && x && *x)
- {
- size_t len = strlen(x) ;
- int hasslash = x[len-1] == '/' ;
- if (!strncmp(sa.s, x, len))
- {
- if (hasslash || (sa.len > len && sa.s[len] == '/'))
- {
- sa.len -= len + !hasslash ;
- memmove(sa.s, sa.s + len + !hasslash, sa.len) ;
- }
- }
- }
-#endif
- }
-
- /* fking finally */
-
- if (chdir(sa.s) < 0)
- strerr_diefu2sys(111, "chdir to ", where) ;
-
- /* and there's still more nonsense to do afterwards! */
-
- if (phy)
- {
- sa.len = 0 ;
- if (sagetcwd(&sa) < 0) strerr_diefu1sys(111, "getcwd") ;
- if (!stralloc_0(&sa)) dienomem() ;
- if (!env_mexec("PWD", sa.s)) dienomem() ;
- }
-
- if (dopwd)
- {
- sa.s[sa.len - 1] = '\n' ;
- if (allwrite(1, sa.s, sa.len) < sa.len)
- strerr_diefu1sys(111, "write to stdout") ;
- }
-
- xmexec0(argv) ;
-}
diff --git a/src/posix/posix-umask.c b/src/posix/posix-umask.c
deleted file mode 100644
index 8785bed..0000000
--- a/src/posix/posix-umask.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/* ISC license. */
-
-#include <stdint.h>
-#include <sys/stat.h>
-#include <locale.h>
-
-#include <skalibs/gccattributes.h>
-#include <skalibs/bytestr.h>
-#include <skalibs/types.h>
-#include <skalibs/sgetopt.h>
-#include <skalibs/buffer.h>
-#include <skalibs/strerr.h>
-#include <skalibs/exec.h>
-
-#define USAGE "posix-umask [ -S ] [ mask ] [ prog... ]"
-#define dieusage() strerr_dieusage(100, USAGE)
-#define dieout() strerr_diefu1sys(111, "write to stdout")
-
-
- /* well, unlike posix-cd, at least this one was fun to write */
-
-static inline int output (int sym)
-{
- mode_t mode = umask(0) ;
- size_t m = 0 ;
- char fmt[18] ;
- if (sym)
- {
- unsigned int i = 3 ;
- while (i--)
- {
- unsigned int mask = ~(mode >> (3*i)) ;
- fmt[m++] = "ogu"[i] ; fmt[m++] = '=' ;
- if (mask & 4) fmt[m++] = 'r' ;
- if (mask & 2) fmt[m++] = 'w' ;
- if (mask & 1) fmt[m++] = 'x' ;
- if (i) fmt[m++] = ',' ;
- }
- }
- else m += uint0_ofmt(fmt, mode, 4) ;
- fmt[m++] = '\n' ;
- if (buffer_putflush(buffer_1, fmt, m) < 0) dieout() ;
- return 0 ;
-}
-
-static void diesyntax (char const *) gccattr_noreturn ;
-static void diesyntax (char const *s)
-{
- strerr_dief3x(101, "internal parsing error: bad ", s, ". Please submit a bug-report.") ;
-}
-
-static inline uint8_t cclass (char c)
-{
- /* char tables may be more efficient, but this is way more readable */
- switch (c)
- {
- case 0 : return 0 ;
- case ',' : return 1 ;
- case '+' :
- case '-' :
- case '=' : return 2 ;
- case 'u' :
- case 'g' :
- case 'o' : return 3 ;
- case 'a' : return 4 ;
- case 'r' :
- case 'w' :
- case 'x' :
- case 'X' :
- case 's' :
- case 't' : return 5 ;
- default : return 6 ;
- }
-}
-
-static inline uint8_t who_value (char c)
-{
- switch (c)
- {
- case 'u' : return 4 ;
- case 'g' : return 2 ;
- case 'o' : return 1 ;
- case 'a' :
- case '+' : /* shortcut for when who is empty */
- case '-' :
- case '=' : return 7 ;
- default : diesyntax("who") ;
- }
-}
-
-static inline uint8_t perm_value (char c)
-{
- switch (c)
- {
- case 'r' : return 4 ;
- case 'w' : return 2 ;
- case 'x' :
- case 'X' : return 1 ;
- case 's' :
- case 't' : return 0 ;
- default : diesyntax("perm") ;
- }
-}
-
-static inline unsigned int parsemode (char const *s)
-{
- static uint16_t const table[5][7] =
- {
- { 0x005, 0x000, 0x064, 0x021, 0x021, 0x006, 0x006 },
- { 0x005, 0x006, 0x042, 0x021, 0x021, 0x006, 0x006 },
- { 0x005, 0x200, 0x042, 0x083, 0x006, 0x104, 0x006 },
- { 0x805, 0xe00, 0xc42, 0x006, 0x006, 0x006, 0x006 },
- { 0x805, 0xe00, 0xc42, 0x006, 0x006, 0x104, 0x006 }
- } ;
- unsigned int oldmode = ~umask(0) ;
- uint8_t modes[3] = { oldmode & 7, (oldmode >> 3) & 7, (oldmode >> 6) & 7 } ;
- uint8_t who = 0 ;
- uint8_t perm = 0 ;
- uint8_t state = 0 ;
- char op = 0 ;
- while (state < 5)
- {
- char c = *s++ ;
- uint16_t what = table[state][cclass(c)] ;
- state = what & 7 ;
- if (what & 0x020) who |= who_value(c) ;
- if (what & 0x080) perm = modes[byte_chr("ogu", 3, c)] ;
- if (what & 0x100) perm |= perm_value(c) ;
- if (what & 0x800)
- {
- unsigned int i = 3 ;
- while (i--) if (who & (1 << i))
- switch (op)
- {
- case '-' : modes[i] &= ~perm ; break ;
- case '+' : modes[i] |= perm ; break ;
- case '=' : modes[i] = perm ; break ;
- default : diesyntax("op") ;
- }
- }
- if (what & 0x040) op = c ;
- if (what & 0x200) who = 0 ;
- if (what & 0x400) perm = 0 ;
- }
- if (state > 5) strerr_dief1x(1, "invalid mode string") ;
- return ((unsigned int)modes[2] << 6) | ((unsigned int)modes[1] << 3) | modes[0] ;
-}
-
-int main (int argc, char const **argv)
-{
- int sym = 0 ;
- unsigned int mode ;
- PROG = "posix-umask" ;
- setlocale(LC_ALL, "") ; /* totally supported, I swear */
-
- {
- subgetopt l = SUBGETOPT_ZERO ;
- for (;;)
- {
- int opt = subgetopt_r(argc, argv, "S", &l) ;
- if (opt == -1) break ;
- switch (opt)
- {
- case 'S' : sym = 1 ; break ;
- default : dieusage() ;
- }
- }
- argc -= l.ind ; argv += l.ind ;
- }
- if (!argc) return output(sym) ;
- if (!uint0_oscan(argv[0], &mode)) mode = ~parsemode(argv[0]) ;
- umask(mode & 00777) ;
- xexec0(argv+1) ;
-}
diff --git a/src/posix/posix-umask.txt b/src/posix/posix-umask.txt
deleted file mode 100644
index 5bf49a2..0000000
--- a/src/posix/posix-umask.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-
- parsemode() function for posix-umask
-
- goal: parse the "u+r,g-wx,o=u" symbolic mode string and convert it
-to a numeric value suitable for umask().
- In the purest skarnet.org tradition, we implement the parser via a DFA.
-
-class | 0 1 2 3 4 5 6
-st\ev | \0 , +-= ugo a rwxXst other
-------------------------------------------------------------------------
-START | wo w w
-0 | END START OP WHO WHO X X
-
-WHO | o w w
-1 | END X OP WHO WHO X X
-
-OP | r o c p
-2 | END START OP PERMCPY X PERM X
-
-PERMCPY | ! !rR !Ro
-3 | END START OP X X X X
-
-PERM | ! !rR !Ro p
-4 | END START OP X X PERM X
-------------------------------------------------------------------------
-
-END=5, X=6. -> states: 3 bits
-7 actions -> 10 bits total, need uint16_t
-
- w: 0x020: who |= c
- o: 0x040: store op
- c: 0x080: copy perm from c
- p: 0x100: perm |= c
- r: 0x200: reset who
- R: 0x400: reset perm
- !: 0x800: apply (who, op, perm) change
-