diff options
author | Mattias Andrée <maandree@kth.se> | 2024-08-18 10:07:51 +0200 |
---|---|---|
committer | Mattias Andrée <maandree@kth.se> | 2024-08-18 10:07:51 +0200 |
commit | 2de8dae44c40d97e3947070353c1db709a35f92c (patch) | |
tree | 13a9827273a54b2a9235135c84eae735ced05009 /which.c | |
parent | Add @since for definitions added in version 1.5 (diff) | |
parent | Add missing .c files (diff) | |
download | libsimple-2de8dae44c40d97e3947070353c1db709a35f92c.tar.gz libsimple-2de8dae44c40d97e3947070353c1db709a35f92c.tar.bz2 libsimple-2de8dae44c40d97e3947070353c1db709a35f92c.tar.xz |
Merge tag '1.6' into since
Version 1.6
Diffstat (limited to '')
-rw-r--r-- | which.c | 92 |
1 files changed, 92 insertions, 0 deletions
@@ -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 |