From 18e43565574b700befc832ed4d25d25e40951f68 Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Tue, 24 Nov 2020 21:45:56 +0000 Subject: Complete revamp of the pathexec functions - pathexec_run is now called exec_ae a for provided file name (default: argv[0]) e for provided envp (default: environ) - pathexec is now called mexec. m for merge environment. Option letters are: a for provided file name (default: argv[0]) e for provided envp (default: environ) f for provided envp *and* length of the envp m for provided modif string plus its length (the length is always needed because the modifs are null-terminated) n for provided modif string, length *and* number of modifs - functions have a foo0 version for _exit(0) when argv[0] is null - functions have a xfoo version to die if the exec fails - and a xfoo0 - Compatibility #defines and #includes are there until the next major bump --- src/libenvexec/envdir.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 src/libenvexec/envdir.c (limited to 'src/libenvexec/envdir.c') diff --git a/src/libenvexec/envdir.c b/src/libenvexec/envdir.c new file mode 100644 index 0000000..6992654 --- /dev/null +++ b/src/libenvexec/envdir.c @@ -0,0 +1,85 @@ +/* ISC license. */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAXVARSIZE 4095 + +int envdir_internal (char const *path, stralloc *modifs, unsigned int options, char nullis) +{ + char buf[MAXVARSIZE + 1] ; + unsigned int n = 0 ; + size_t pathlen = strlen(path) ; + size_t modifbase = modifs->len ; + int wasnull = !modifs->s ; + DIR *dir ; + if (!nullis) return (errno = EINVAL, -1) ; + dir = opendir(path) ; + if (!dir) return -1 ; + for (;;) + { + direntry *d ; + size_t len ; + ssize_t r ; + errno = 0 ; + d = readdir(dir) ; + if (!d) break ; + if (d->d_name[0] == '.') continue ; + len = strlen(d->d_name) ; + if (str_chr(d->d_name, '=') < len) continue ; + { + char tmp[pathlen + len + 2] ; + memcpy(tmp, path, pathlen) ; + tmp[pathlen] = '/' ; + memcpy(tmp + pathlen + 1, d->d_name, len + 1) ; + r = openreadnclose(tmp, buf, MAXVARSIZE) ; + } + if (r < 0) + { + if (errno == ENOENT) errno = EIDRM ; + goto err ; + } + else if (r > 0) + { + if (options & SKALIBS_ENVDIR_VERBATIM) + { + if (!(options & SKALIBS_ENVDIR_NOCHOMP) && (buf[r-1] == '\n')) r-- ; + } + else + { + r = byte_chr(buf, r, '\n') ; + if (!(options & SKALIBS_ENVDIR_NOCHOMP)) + { + while (r--) if ((buf[r] != ' ') && (buf[r] != '\t') && (buf[r] != '\r')) break ; + r++ ; + } + } + { + size_t i = 0 ; + for (; i < (size_t)r ; i++) if (!buf[i]) buf[i] = nullis ; + } + buf[r++] = 0 ; + if (!env_addmodif(modifs, d->d_name, buf)) goto err ; + } + else if (!env_addmodif(modifs, d->d_name, 0)) goto err ; + n++ ; + } + if (errno) goto err ; + dir_close(dir) ; + return n ; + + err: + { + int e = errno ; + dir_close(dir) ; + if (wasnull) stralloc_free(modifs) ; else modifs->len = modifbase ; + errno = e ; + return -1 ; + } +} -- cgit v1.2.3