From d33c5c0a18017ae658feb4a3344dd810cc87050b Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Sun, 5 May 2024 10:28:31 +0200 Subject: m + add ascii.h and exec.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- which.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 which.c (limited to 'which.c') diff --git a/which.c b/which.c new file mode 100644 index 0000000..96a3ece --- /dev/null +++ b/which.c @@ -0,0 +1,92 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +const char * +libsimple_which(const char *file, int cwdfd, const char *path, char **free_this_out) +{ + const char *p, *q; + char *buf = NULL; + size_t bufsize, len, filelen; + int got_eacces = 0, saved_errno = errno; + + free_this_out = NULL; + + if (!file || !free_this_out) { + errno = EINVAL; + return NULL; + } + + if (strchr(file, '/')) + return file; + + if (!path) { + path = getenv("PATH"); + if (!path) + path = ""; + } + if (!*path) { + errno = ENOENT; + return NULL; + } + + bufsize = 0; + for (p = path; p; p = q) { + q = strchr(p, ':'); + if (q) + len = (size_t)(q++ - p); + else + len = strlen(p); + if (len > bufsize) + bufsize = len; + } + if (bufsize) { + filelen = strlen(file) + 1U; + bufsize += 1U + filelen; + buf = malloc(bufsize); + if (!buf) + return NULL; + } + + for (p = path; p; p = q) { + q = strchr(p, ':'); + if (q) + len = (size_t)(q++ - p); + else + len = strlen(p); + if (len) { + memcpy(buf, p, len); + buf[len] = '/'; + memcpy(&buf[len + 1], file, filelen); + if (!faccessat(cwdfd, buf, X_OK, AT_EACCESS)) { + *free_this_out = buf; + errno = saved_errno; + return buf; + } + } else { + if (!faccessat(cwdfd, file, X_OK, AT_EACCESS)) { + errno = saved_errno; + return file; + } + } + if (errno == EACCES) + got_eacces = 1; + } + + free(buf); + errno = got_eacces ? EACCES : ENOENT; + return NULL; +} + + +#else +#include "test.h" + +int +main(void) +{ + return 0; +} + +#endif -- cgit v1.2.3-70-g09d2