skalibs

Mirror/fork of https://skarnet.org/software/skalibs/
git clone https://ccx.te2000.cz/git/skalibs
Log | Files | Refs | README | LICENSE

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 }