|
1 // Copyright (C) 1999,2000 Bruce Guenter <bruceg@em.ca> |
|
2 // |
|
3 // This program is free software; you can redistribute it and/or modify |
|
4 // it under the terms of the GNU General Public License as published by |
|
5 // the Free Software Foundation; either version 2 of the License, or |
|
6 // (at your option) any later version. |
|
7 // |
|
8 // This program is distributed in the hope that it will be useful, |
|
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
11 // GNU General Public License for more details. |
|
12 // |
|
13 // You should have received a copy of the GNU General Public License |
|
14 // along with this program; if not, write to the Free Software |
|
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
16 |
|
17 #include <config.h> |
|
18 #include <errno.h> |
|
19 #include <stdlib.h> |
|
20 #include <sys/stat.h> |
|
21 #include <sys/types.h> |
|
22 #include <sys/wait.h> |
|
23 #include <unistd.h> |
|
24 #include "exec.h" |
|
25 #include "config/configrc.h" |
|
26 |
|
27 int presetenv(const char* prefix, const mystring& value) |
|
28 { |
|
29 unsigned plen = strlen(prefix); |
|
30 char* tmp = new char[plen+value.length()+1]; |
|
31 strcpy(tmp, prefix); |
|
32 strcpy(tmp+plen, value.c_str()); |
|
33 return putenv(tmp); |
|
34 |
|
35 // Note that tmp is never freed. This was done as a result of problems |
|
36 // using putenv with glibc 2.1, where freeing the pointer passed to |
|
37 // putenv appeared to cause garbage to enter the environment. |
|
38 //mystring tmp = prefix + value; |
|
39 //return putenv(tmp.c_str()); |
|
40 } |
|
41 |
|
42 int execute_one(const char* args[]) |
|
43 { |
|
44 int pid = fork(); |
|
45 switch(pid) { |
|
46 case -1: |
|
47 return -1; |
|
48 case 0: |
|
49 execvp(args[0], (char**)args); |
|
50 exit(127); |
|
51 default: |
|
52 for(;;) { |
|
53 int status; |
|
54 if(waitpid(pid, &status, 0) == -1) { |
|
55 if(errno != EINTR) |
|
56 return -1; |
|
57 } else { |
|
58 if(WIFEXITED(status)) |
|
59 return WEXITSTATUS(status); |
|
60 else |
|
61 return -1; |
|
62 } |
|
63 } |
|
64 } |
|
65 return 0; |
|
66 } |
|
67 |
|
68 static int execute(const configuration* node, const mystring& name) |
|
69 { |
|
70 if(node->parent) { |
|
71 int i = execute(node->parent, name); |
|
72 if(i || (node->parent->directory == node->directory)) |
|
73 return i; |
|
74 } |
|
75 mystring path = node->directory + "/" + name; |
|
76 struct stat buf; |
|
77 if(stat(path.c_str(), &buf) != -1 && buf.st_mode & 0111) { |
|
78 const char* args[] = { path.c_str(), 0 }; |
|
79 return execute_one(args); |
|
80 } |
|
81 else |
|
82 return 0; |
|
83 } |
|
84 |
|
85 int execute(const mystring& name) |
|
86 { |
|
87 int i = execute(config, name); |
|
88 return (i == 99) ? 0 : i; |
|
89 } |