#!/usr/bin/python --
## Process.py
##
## Dru Nelson <dru@egroups.com>
## 7-15-99
'''
Process.py -- an objects for manipulating unix processes
''' # '
import os, sys, select
class Process:
def __init__(self):
self.stdinFd = []
self.stdoutFd = []
self.stderrFd = []
self.envDict = None
self.cmd = ''
self.pid = -1
# Default: merge stdout and stderr
self.merge = 1
self.fdClosed = 0
def mergeStderr(self, i):
if i:
self.merge = 1
else:
self.merge = 0
def markFdClosed(self):
self.fdClosed = 1
def pipeWrite(self):
return self.stdinFd[1]
def pipeRead(self):
#print "Read fd = %s" %self.stdoutFd[0]
return self.stdoutFd[0]
def pipeError(self):
return self.stderrFd[0]
def getPid(self):
return self.pid
def clean(self):
#os.close(self.stdinFd[1])
if not self.fdClosed:
os.close(self.stdoutFd[0])
os.close(self.stderrFd[0])
# Return the exit code
return os.waitpid(self.pid, 0)[1]
def closeAll(self, num):
while (num < 64):
try:
os.close(num)
except:
pass
num = num + 1
def setEnv(self, dict):
self.envDict = dict
def pipe(self, command):
self.cmd = command
#print " Command: %s " % command
self.stdinFd = os.pipe()
#print "stdin %s" %repr(self.stdinFd)
self.stdoutFd = os.pipe()
#print "stdout %s" %repr(self.stdoutFd)
self.stderrFd = os.pipe()
#print "stderr %s" %repr(self.stderrFd)
self.pid = os.fork()
if self.pid < 0:
print "Error couldn't fork"
sys.exit(1)
if self.pid == 0:
os.chdir('/tmp')
# This is the child
os.dup2(self.stdinFd[0], 0)
os.dup2(self.stdoutFd[1], 1)
if self.merge == 1:
os.dup2(self.stdoutFd[1], 2)
else:
os.dup2(self.stderrFd[1], 2)
self.closeAll(3)
if self.envDict == None:
os.execv("/bin/sh", ('sh', '-c', command))
else:
os.execve("/bin/sh", ('sh', '-c', command), self.envDict)
print "Wierd"
sys.exit(127) # This is only reached on error
else:
#print "Parent child = %s " % self.pid
os.close(self.stdinFd[0])
os.close(self.stdinFd[1]) # close the stdin pipe
os.close(self.stdoutFd[1])
os.close(self.stderrFd[1])
return self.pid;
def readDescriptor(desc):
result = ''
while 1:
data = os.read(desc, 16384)
if data == '':
break
result = result + data
return result
# Return a status code and output
def doCommandWithTimeout(cmd, timeout, envDict=None):
proc = Process()
proc.setEnv(envDict)
proc.pipe(cmd)
fd = proc.pipeRead()
x = select.select([fd], [], [], timeout)
# timeout reached
if ([], [], []) == x:
os.kill(proc.getPid(), 9)
proc.clean()
return -1, ''
# This has a problem - it can get hung
# on a stuck process... need to fix
outData = readDescriptor(fd)
# Don't actually read the data
i = proc.clean()
return i, outData
# From D'Arcy J.M. Cain
def daemon(nochdir = None, noclose = None):
""" run server as a daemon. """
if os.fork():
os._exit(0)
os.setsid()
if nochdir == None:
os.chdir("/")
if noclose == None:
fp = open("/dev/null", "rw")
sys.stdin = sys.__stdin__ = fp
sys.stdout = sys.__stdout__ = fp
sys.stderr = sys.__stderr__ = fp
del fp
if os.fork():
os._exit(0)