execvep_internal.c (1008B)
1 /* ISC license. */ 2 3 #include <unistd.h> 4 #include <string.h> 5 #include <errno.h> 6 #include <skalibs/bytestr.h> 7 #include <skalibs/posixplz.h> 8 9 void execvep_internal (char const *file, char const *const *argv, char const *const *envp, char const *path) 10 { 11 if (!path) errno = EINVAL ; 12 else 13 { 14 size_t pathlen = strlen(path) + 1 ; 15 size_t filelen = strlen(file) ; 16 int savederrno = 0 ; 17 while (pathlen) 18 { 19 size_t split = byte_chr(path, pathlen - 1, ':') ; 20 if (split) 21 { 22 char tmp[split + 2 + filelen] ; 23 memcpy(tmp, path, split) ; 24 tmp[split] = '/' ; 25 memcpy(tmp + split + 1, file, filelen + 1) ; 26 execve(tmp, (char *const *)argv, (char *const *)envp) ; 27 if (errno != ENOENT) 28 { 29 savederrno = errno ; 30 if ((errno != EACCES) && (errno != EPERM) && (errno != EISDIR) && (errno != ENOTDIR)) break ; 31 } 32 } 33 path += split+1 ; pathlen -= split+1 ; 34 } 35 if (savederrno) errno = savederrno ; 36 } 37 }