source: trunk/lang/python/Rappture/tools.py @ 3184

Last change on this file since 3184 was 3184, checked in by clarksm, 10 years ago

Do a better job when command is given as string. Eliminating the intermediate shell script allows the kill signal to propagate.

File size: 3.7 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
16
17commandPid = 0
18
19def sig_handler(signalType, frame):
20    global commandPid
21    if commandPid:
22        os.kill(commandPid,signal.SIGTERM)
23
24
25def getCommandOutput(command,
26                     streamOutput=False):
27    global commandPid
28
29    sig_INT_handler = signal.signal(signal.SIGINT,sig_handler)
30    sig_HUP_handler = signal.signal(signal.SIGHUP,sig_handler)
31    sig_TERM_handler = signal.signal(signal.SIGTERM,sig_handler)
32
33    BUFSIZ = 4096
34    if isinstance(command,list):
35       child = subprocess.Popen(command,bufsize=BUFSIZ, \
36                                stdout=subprocess.PIPE, \
37                                stderr=subprocess.PIPE, \
38                                close_fds=True)
39    else:
40       commandArgs = shlex.split(command)
41       child = subprocess.Popen(commandArgs,bufsize=BUFSIZ, \
42                                stdout=subprocess.PIPE, \
43                                stderr=subprocess.PIPE, \
44                                close_fds=True)
45    commandPid = child.pid
46    childout   = child.stdout
47    childoutFd = childout.fileno()
48    childerr   = child.stderr
49    childerrFd = childerr.fileno()
50
51    outEOF = False
52    errEOF = False
53
54    outData = []
55    errData = []
56
57    while True:
58        toCheck = []
59        if not outEOF:
60            toCheck.append(childoutFd)
61        if not errEOF:
62            toCheck.append(childerrFd)
63        try:
64            readyRead,readyWrite,readyException = select.select(toCheck,[],[]) # wait for input
65        except select.error,err:
66            readyRead = []
67            readyWrite = []
68            readyException = []
69        if childoutFd in readyRead:
70            outChunk = os.read(childoutFd,BUFSIZ)
71            if outChunk == '':
72                outEOF = True
73            outData.append(outChunk)
74            if streamOutput:
75                sys.stdout.write(outChunk)
76                sys.stdout.flush()
77
78        if childerrFd in readyRead:
79            errChunk = os.read(childerrFd,BUFSIZ)
80            if errChunk == '':
81                errEOF = True
82            errData.append(errChunk)
83            if streamOutput:
84                sys.stderr.write(errChunk)
85                sys.stderr.flush()
86
87        if outEOF and errEOF:
88            break
89
90    pid,err = os.waitpid(commandPid,0)
91    commandPid = 0
92
93    signal.signal(signal.SIGINT,sig_INT_handler)
94    signal.signal(signal.SIGHUP,sig_HUP_handler)
95    signal.signal(signal.SIGTERM,sig_TERM_handler)
96
97    if err != 0:
98        if   os.WIFSIGNALED(err):
99           sys.stderr.write("%s failed w/ signal %d\n" % (command,os.WTERMSIG(err)))
100        else:
101           if os.WIFEXITED(err):
102               err = os.WEXITSTATUS(err)
103           sys.stderr.write("%s failed w/ exit code %d\n" % (command,err))
104        if not streamOutput:
105           sys.stderr.write("%s\n" % ("".join(errData)))
106
107    return err,"".join(outData),"".join(errData)
108
109
110def getDriverNumber(driverFileName):
111    driverNumRslt = re.search(r'[0-9]+',os.path.split(driverFileName)[1])
112    if driverNumRslt == None:
113        return None
114    return driverNumRslt.group()
115
116
117def writeFile(fileName,text):
118    file_object = open(fileName, "w")
119    if file_object:
120        file_object.write(text)
121        file_object.close()
122    else:
123        raise RuntimeError, 'could not open %s for writing' % (fileName)
124
Note: See TracBrowser for help on using the repository browser.