source: branches/1.4/lang/python/Rappture/tools.py @ 6034

Last change on this file since 6034 was 6034, checked in by gah, 8 years ago

update tool.py from clarks

File size: 6.5 KB
Line 
1# ----------------------------------------------------------------------
2#
3# ======================================================================
4#  AUTHOR:  Derrick S. Kearney, Purdue University
5#  AUTHOR:  Steve Clark, Purdue University
6#  Copyright (c) 2004-2012  HUBzero Foundation, LLC
7# ======================================================================
8
9import sys
10import os
11import re
12import subprocess
13import shlex
14import select
15import signal
16import traceback
17import time
18
19commandPid = 0
20
21def sig_handler(signalType, frame):
22    global commandPid
23    if commandPid:
24        os.kill(commandPid,signal.SIGTERM)
25
26
27def executeCommand(command,
28                   stdin=None,
29                   streamOutput=False):
30    global commandPid
31
32    exitStatus = 0
33    fpStdin = None
34    outData = []
35    errData = []
36
37    try:
38       sig_INT_handler = signal.signal(signal.SIGINT,sig_handler)
39       sig_HUP_handler = signal.signal(signal.SIGHUP,sig_handler)
40       sig_TERM_handler = signal.signal(signal.SIGTERM,sig_handler)
41    except ValueError:
42#      happens when used in a thread
43       pass
44    except:
45       print traceback.format_exc()
46
47    if stdin == None:
48       commandStdin = None
49    else:
50       if   isinstance(stdin,file):
51          commandStdin = stdin
52       elif isinstance(stdin,int):
53          commandStdin = stdin
54       else:
55          try:
56             stdinPath = str(stdin)
57          except UnicodeEncodeError:
58             try:
59                stdinPath = unicode(stdin).encode('unicode_escape')
60             except:
61                stdinPath = None
62          except:
63             stdinPath = None
64          if stdinPath:
65             if os.path.isfile(stdinPath):
66                try:
67                   fpStdin = open(stdinPath,'r')
68                except (IOError,OSError):
69                   exitStatus = 1
70                   errData.append("File %s could not be opened.\n" % (stdinPath))
71                   if streamOutput:
72                      sys.stderr.write("File %s could not be opened.\n" % (stdinPath))
73                      sys.stderr.flush()
74                else:
75                   commandStdin = fpStdin
76             else:
77                exitStatus = 1
78                errData.append("File %s does not exist.\n" % (stdinPath))
79                if streamOutput:
80                   sys.stderr.write("File %s does not exist.\n" % (stdinPath))
81                   sys.stderr.flush()
82          else:
83             exitStatus = 1
84             errData.append("Bad argument type specified for stdin.\n")
85             if streamOutput:
86                sys.stderr.write("Bad argument type specified for stdin.\n")
87                sys.stderr.flush()
88
89    if not exitStatus:
90       BUFSIZ = 4096
91       if isinstance(command,list):
92          child = subprocess.Popen(command,bufsize=BUFSIZ, \
93                                   stdin=commandStdin, \
94                                   stdout=subprocess.PIPE, \
95                                   stderr=subprocess.PIPE, \
96                                   close_fds=True)
97       else:
98          try:
99             commandStr = str(command)
100          except UnicodeEncodeError:
101             commandStr = unicode(command).encode('unicode_escape')
102          commandArgs = shlex.split(commandStr)
103          child = subprocess.Popen(commandArgs,bufsize=BUFSIZ, \
104                                   stdin=commandStdin, \
105                                   stdout=subprocess.PIPE, \
106                                   stderr=subprocess.PIPE, \
107                                   close_fds=True)
108       commandPid = child.pid
109       childout   = child.stdout
110       childoutFd = childout.fileno()
111       childerr   = child.stderr
112       childerrFd = childerr.fileno()
113   
114       outEOF = False
115       errEOF = False
116   
117       while True:
118           toCheck = []
119           if not outEOF:
120               toCheck.append(childoutFd)
121           if not errEOF:
122               toCheck.append(childerrFd)
123           try:
124               readyRead,readyWrite,readyException = select.select(toCheck,[],[]) # wait for input
125           except select.error,err:
126               readyRead = []
127               readyWrite = []
128               readyException = []
129           if childoutFd in readyRead:
130               outChunk = os.read(childoutFd,BUFSIZ)
131               if outChunk == '':
132                   outEOF = True
133               outData.append(outChunk)
134               if streamOutput:
135                   sys.stdout.write(outChunk)
136                   sys.stdout.flush()
137   
138           if childerrFd in readyRead:
139               errChunk = os.read(childerrFd,BUFSIZ)
140               if errChunk == '':
141                   errEOF = True
142               errData.append(errChunk)
143               if streamOutput:
144                   sys.stderr.write(errChunk)
145                   sys.stderr.flush()
146   
147           if outEOF and errEOF:
148               break
149   
150       pid,exitStatus = os.waitpid(commandPid,0)
151       commandPid = 0
152       if fpStdin:
153          try:
154             fpStdin.close()
155          except:
156             pass
157   
158       try:
159          signal.signal(signal.SIGINT,sig_INT_handler)
160          signal.signal(signal.SIGHUP,sig_HUP_handler)
161          signal.signal(signal.SIGTERM,sig_TERM_handler)
162       except UnboundLocalError:
163   #      happens when used in a thread
164          pass
165       except:
166          print traceback.format_exc()
167   
168       if exitStatus != 0:
169           if   os.WIFSIGNALED(exitStatus):
170              sys.stderr.write("%s failed w/ signal %d\n" % (command,os.WTERMSIG(exitStatus)))
171           else:
172              if os.WIFEXITED(exitStatus):
173                  exitStatus = os.WEXITSTATUS(exitStatus)
174              sys.stderr.write("%s failed w/ exit code %d\n" % (command,exitStatus))
175           if not streamOutput:
176              sys.stderr.write("%s\n" % ("".join(errData)))
177
178    return exitStatus,"".join(outData),"".join(errData)
179
180
181def getCommandOutput(command,
182                     streamOutput=False):
183    exitStatus,stdOut,stdErr = executeCommand(command,
184                                              streamOutput=streamOutput)
185
186    return exitStatus,stdOut,stdErr
187
188
189def getDriverNumber(driverFileName):
190    driverNumRslt = re.search(r'[0-9]+',os.path.split(driverFileName)[1])
191    if driverNumRslt == None:
192        return None
193    return driverNumRslt.group()
194
195
196def writeFile(fileName,text):
197    file_object = open(fileName, "w")
198    if file_object:
199        file_object.write(text)
200        file_object.close()
201    else:
202        raise RuntimeError, 'could not open %s for writing' % (fileName)
203
Note: See TracBrowser for help on using the repository browser.