1 /* Public domain. */
2 
3 #include "error.h"
4 #include "stralloc.h"
5 #include "str.h"
6 #include "env.h"
7 #include "pathexec.h"
8 #include <unistd.h>
9 
10 static stralloc tmp;
11 
pathexec_run(const char * file,const char * const * argv,const char * const * envp)12 void pathexec_run(const char *file,const char * const *argv,const char * const *envp)
13 {
14   const char *path;
15   unsigned int split;
16   int savederrno;
17 
18   if (file[str_chr(file,'/')]) {
19     execve(file,(char *const *)argv,(char *const *)envp);
20     return;
21   }
22 
23   path = env_get("PATH");
24   if (!path) path = "/bin:/usr/bin";
25 
26   savederrno = 0;
27   for (;;) {
28     split = str_chr(path,':');
29     if (!stralloc_copyb(&tmp,path,split)) return;
30     if (!split)
31       if (!stralloc_cats(&tmp,".")) return;
32     if (!stralloc_cats(&tmp,"/"))  return;
33     if (!stralloc_cats(&tmp,file)) return;
34     if (!stralloc_0(&tmp)) return;
35 
36     execve(tmp.s,(char *const *)argv,(char * const *)envp);
37     if (errno != error_noent) {
38       savederrno = errno;
39       if ((errno != error_acces) && (errno != error_perm) && (errno != error_isdir)) return;
40     }
41 
42     if (!path[split]) {
43       if (savederrno) errno = savederrno;
44       return;
45     }
46     path += split;
47     path += 1;
48   }
49 }
50