diff options
author | Mattias Andrée <maandree@kth.se> | 2024-05-05 10:28:31 +0200 |
---|---|---|
committer | Mattias Andrée <maandree@kth.se> | 2024-05-05 10:28:31 +0200 |
commit | d33c5c0a18017ae658feb4a3344dd810cc87050b (patch) | |
tree | 020748a839ab162379a3235ed59d126c43491cc6 /execveat.c | |
parent | libsimple_abspath: accept NULL for cwd (diff) | |
download | libsimple-d33c5c0a18017ae658feb4a3344dd810cc87050b.tar.gz libsimple-d33c5c0a18017ae658feb4a3344dd810cc87050b.tar.bz2 libsimple-d33c5c0a18017ae658feb4a3344dd810cc87050b.tar.xz |
m + add ascii.h and exec.h
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to '')
-rw-r--r-- | execveat.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/execveat.c b/execveat.c new file mode 100644 index 0000000..ed7b11e --- /dev/null +++ b/execveat.c @@ -0,0 +1,56 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +int +libsimple_execveat(int dirfd, const char *pathname, char *const argv[], char *const envp[], int flags) +{ + struct stat st; + int fd, saved_errno; + +#if defined(__linux__) + execveat(dirfd, pathname, argv, envp, flags); + if (errno != ENOSYS) + return -1; +#endif + + if (flags & AT_EMPTY_PATH) + return fexecve(dirfd, argv, envp); + +#ifndef O_PATH +# define O_PATH O_RDONLY +#endif + + fd = openat(dirfd, pathname, O_PATH | ((flags & AT_SYMLINK_NOFOLLOW) ? O_NOFOLLOW : 0)); + if (fd < 0) + return -1; + + if (flags & AT_SYMLINK_NOFOLLOW) { + if (fstat(fd, &st)) { + saved_errno = errno; + close(fd); + errno = saved_errno; + return -1; + } + if (S_ISLNK(st.st_mode)) { + close(fd); + errno = ELOOP; + return -1; + } + } + + return fexecve(fd, argv, envp); +} + + +#else +#include "test.h" + +int +main(void) +{ + return 0; +} + +#endif |