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