]> git.ipfire.org Git - people/ms/ipfire-3.x.git/blob - pkgs/core/pyfire/src/executil.py
Remove legacy build system.
[people/ms/ipfire-3.x.git] / pkgs / core / pyfire / src / executil.py
1 #
2 # executil.py - generic utility functions for executing programs
3 #
4 # Erik Troan <ewt@redhat.com>
5 #
6 # Copyright 1999-2002 Red Hat, Inc.
7 #
8 # This software may be freely redistributed under the terms of the GNU
9 # library public license.
10 #
11 # You should have received a copy of the GNU Library Public License
12 # along with this program; if not, write to the Free Software
13 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
14 #
15 import os
16 import sys
17 import types
18 import select
19 import signal
20
21 def getfd(filespec, readOnly = 0):
22 if type(filespec) == types.IntType:
23 return filespec
24 if filespec == None:
25 filespec = "/dev/null"
26
27 flags = os.O_RDWR | os.O_CREAT
28 if (readOnly):
29 flags = os.O_RDONLY
30 return os.open(filespec, flags)
31
32 def execWithRedirect(command, argv, stdin = 0, stdout = 1, stderr = 2,
33 searchPath = 0, root = '/', newPgrp = 0, ignoreTermSigs = 0):
34 stdin = getfd(stdin)
35 if stdout == stderr:
36 stdout = getfd(stdout)
37 stderr = stdout
38 else:
39 stdout = getfd(stdout)
40 stderr = getfd(stderr)
41
42 childpid = os.fork()
43 if (not childpid):
44 if (root and root != '/'):
45 os.chroot(root)
46 os.chdir("/")
47
48 if ignoreTermSigs:
49 signal.signal(signal.SIGTSTP, signal.SIG_IGN)
50 signal.signal(signal.SIGINT, signal.SIG_IGN)
51
52 if type(stdin) == type("a"):
53 stdin = os.open(stdin, os.O_RDONLY)
54 if type(stdout) == type("a"):
55 stdout = os.open(stdout, os.O_RDWR)
56 if type(stderr) == type("a"):
57 stderr = os.open(stderr, os.O_RDWR)
58
59 if stdin != 0:
60 os.dup2(stdin, 0)
61 os.close(stdin)
62 if stdout != 1:
63 os.dup2(stdout, 1)
64 if stdout != stderr:
65 os.close(stdout)
66 if stderr != 2:
67 os.dup2(stderr, 2)
68 os.close(stderr)
69
70 if (searchPath):
71 os.execvp(command, argv)
72 else:
73 os.execv(command, argv)
74
75 sys.exit(1)
76
77 if newPgrp:
78 os.setpgid(childpid, childpid)
79 oldPgrp = os.tcgetpgrp(0)
80 os.tcsetpgrp(0, childpid)
81
82 status = -1
83 try:
84 (pid, status) = os.waitpid(childpid, 0)
85 except OSError, (errno, msg):
86 print __name__, "waitpid:", msg
87
88 if newPgrp:
89 os.tcsetpgrp(0, oldPgrp)
90
91 return status
92
93 ## Run an external program and capture standard out.
94 # @param command The command to run.
95 # @param argv A list of arguments.
96 # @param stdin The file descriptor to read stdin from.
97 # @param stderr The file descriptor to redirect stderr to.
98 # @param root The directory to chroot to before running command.
99 # @return The output of command from stdout.
100 def execWithCapture(command, argv, stdin = 0, stderr = 2, root='/'):
101 def chroot():
102 os.chroot(root)
103
104 argv = list(argv)
105 if type(stdin) == type("string"):
106 if os.access(stdin, os.R_OK):
107 stdin = open(stdin)
108 else:
109 stdin = 0
110 if type(stderr) == type("string"):
111 stderr = open(stderr, "w")
112
113 try:
114 pipe = subprocess.Popen([command] + argv, stdin=stdin,
115 stdout=subprocess.PIPE,
116 stderr=subprocess.STDOUT,
117 preexec_fn=chroot, cwd=root)
118 except OSError, (errno, msg):
119 log.error ("Error running " + command + ": " + msg)
120 raise RuntimeError, "Error running " + command + ": " + msg
121
122 rc = pipe.stdout.read()
123 pipe.wait()
124 return rc
125
126 def execWithCaptureStatus(command, argv, searchPath = 0, root = '/', stdin = 0,
127 catchfd = 1, closefd = -1):
128
129 if not os.access (root + command, os.X_OK):
130 raise RuntimeError, command + " can not be run"
131
132 (read, write) = os.pipe()
133
134 childpid = os.fork()
135 if (not childpid):
136 if (root and root != '/'): os.chroot (root)
137 if isinstance(catchfd, tuple):
138 for fd in catchfd:
139 os.dup2(write, fd)
140 else:
141 os.dup2(write, catchfd)
142 os.close(write)
143 os.close(read)
144
145 if closefd != -1:
146 os.close(closefd)
147
148 if stdin:
149 os.dup2(stdin, 0)
150 os.close(stdin)
151
152 if (searchPath):
153 os.execvp(command, argv)
154 else:
155 os.execv(command, argv)
156
157 sys.exit(1)
158
159 os.close(write)
160
161 rc = ""
162 s = "1"
163 while (s):
164 select.select([read], [], [])
165 s = os.read(read, 1000)
166 rc = rc + s
167
168 os.close(read)
169
170 status = None
171
172 try:
173 (pid, status) = os.waitpid(childpid, 0)
174 except OSError, (errno, msg):
175 print __name__, "waitpid:", msg
176
177 if os.WIFEXITED(status) and (os.WEXITSTATUS(status) == 0):
178 status = os.WEXITSTATUS(status)
179 else:
180 status = -1
181
182 return (rc, status)
183
184 def execWithCaptureErrorStatus(command, argv, searchPath = 0, root = '/',
185 stdin = 0, catchfd = 1, catcherrfd = 2, closefd = -1):
186
187 if not os.access (root + command, os.X_OK):
188 raise RuntimeError, command + " can not be run"
189
190 (read, write) = os.pipe()
191 (read_err,write_err) = os.pipe()
192
193 childpid = os.fork()
194 if (not childpid):
195 if (root and root != '/'): os.chroot (root)
196 if isinstance(catchfd, tuple):
197 for fd in catchfd:
198 os.dup2(write, fd)
199 else:
200 os.dup2(write, catchfd)
201 os.close(write)
202 os.close(read)
203
204 if isinstance(catcherrfd, tuple):
205 for fd in catcherrfd:
206 os.dup2(write_err, fd)
207 else:
208 os.dup2(write_err, catcherrfd)
209 os.close(write_err)
210 os.close(read_err)
211
212 if closefd != -1:
213 os.close(closefd)
214
215 if stdin:
216 os.dup2(stdin, 0)
217 os.close(stdin)
218
219 if (searchPath):
220 os.execvp(command, argv)
221 else:
222 os.execv(command, argv)
223
224 sys.exit(1)
225
226 os.close(write)
227 os.close(write_err)
228
229 rc = ""
230 rc_err = ""
231 s = "1"
232 t = "1"
233 while (s or t):
234 select.select([read], [], [])
235 s = os.read(read, 1000)
236 t = os.read(read_err, 1000)
237 rc = rc + s
238 rc_err = rc_err + t
239
240 os.close(read)
241 os.close(read_err)
242
243 status = None
244
245 try:
246 (pid, status) = os.waitpid(childpid, 0)
247 except OSError, (errno, msg):
248 print __name__, "waitpid:", msg
249
250 if os.WIFEXITED(status) and (os.WEXITSTATUS(status) == 0):
251 status = os.WEXITSTATUS(status)
252 else:
253 status = -1
254
255 return (rc, rc_err, status)