summaryrefslogtreecommitdiff
path: root/pathexec_run.c
diff options
context:
space:
mode:
Diffstat (limited to 'pathexec_run.c')
-rw-r--r--pathexec_run.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/pathexec_run.c b/pathexec_run.c
new file mode 100644
index 0000000..1770ac7
--- /dev/null
+++ b/pathexec_run.c
@@ -0,0 +1,48 @@
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
9static stralloc tmp;
10
11void pathexec_run(const char *file,const char * const *argv,const char * const *envp)
12{
13 const char *path;
14 unsigned int split;
15 int savederrno;
16
17 if (file[str_chr(file,'/')]) {
18 execve(file,argv,envp);
19 return;
20 }
21
22 path = env_get("PATH");
23 if (!path) path = "/bin:/usr/bin";
24
25 savederrno = 0;
26 for (;;) {
27 split = str_chr(path,':');
28 if (!stralloc_copyb(&tmp,path,split)) return;
29 if (!split)
30 if (!stralloc_cats(&tmp,".")) return;
31 if (!stralloc_cats(&tmp,"/")) return;
32 if (!stralloc_cats(&tmp,file)) return;
33 if (!stralloc_0(&tmp)) return;
34
35 execve(tmp.s,argv,envp);
36 if (errno != error_noent) {
37 savederrno = errno;
38 if ((errno != error_acces) && (errno != error_perm) && (errno != error_isdir)) return;
39 }
40
41 if (!path[split]) {
42 if (savederrno) errno = savederrno;
43 return;
44 }
45 path += split;
46 path += 1;
47 }
48}