| Home | Trees | Indices | Help |
|
|---|
|
|
1 __doc__ = """GNUmed general tools."""
2
3 #===========================================================================
4 __version__ = "$Revision: 1.13 $"
5 __author__ = "K. Hilbert <Karsten.Hilbert@gmx.net>"
6 __license__ = "GPL (details at http://www.gnu.org)"
7
8
9 # stdlib
10 import os, sys, logging
11
12
13 _log = logging.getLogger('gm.shell')
14 _log.info(__version__)
15
16 #===========================================================================
18 _log.debug('detecting [%s]', binary)
19
20 # is it a sufficiently qualified path ?
21 if os.access(binary, os.X_OK):
22 return (True, binary)
23
24 # try "which" to find the full path
25 cmd = 'which %s' % binary
26 pipe = os.popen(cmd.encode(sys.getfilesystemencoding()), "r")
27 result = pipe.readline()
28 ret_code = pipe.close()
29 if ret_code is not None:
30 _log.debug('[%s] failed, exit code: %s', cmd, ret_code)
31 else:
32 result = result.strip('\r\n')
33 _log.debug('[%s] returned: %s', cmd, result)
34 # redundant on Linux but apparently necessary on MacOSX
35 if os.access(result, os.X_OK):
36 return (True, result)
37 else:
38 _log.debug('[%s] not detected with "which"', binary)
39
40 # consider "d/m/s/locate" to find the full path
41
42 tmp = binary.lstrip()
43 # to be run by wine ?
44 if tmp.startswith('wine'):
45
46 tmp = tmp[4:].strip().strip('"')
47
48 # "wine /standard/unix/path/to/binary" ?
49 if os.access(tmp, os.R_OK):
50 _log.debug('wine call with UNIX path')
51 return (True, binary)
52
53 # 'wine "drive:\a\windows\path\to\binary"' ?
54 cmd = 'winepath -u "%s"' % tmp
55 pipe = os.popen(cmd.encode(sys.getfilesystemencoding()), "r")
56 result = pipe.readline()
57 ret_code = pipe.close()
58 if ret_code is not None:
59 _log.debug('winepath failed')
60 else:
61 result = result.strip('\r\n')
62 if os.access(result, os.R_OK):
63 _log.debug('wine call with Windows path')
64 return (True, binary)
65 else:
66 _log.warning('"winepath -u %s" returned [%s] but the UNIX path is not verifiable', tmp, result)
67
68 return (False, None)
69 #===========================================================================
71
72 found = False
73 binary = None
74
75 for cmd in binaries:
76 _log.debug('looking for [%s]', cmd)
77
78 if cmd is None:
79 continue
80
81 found, binary = detect_external_binary(binary = cmd)
82 if found:
83 break
84
85 return (found, binary)
86 #===========================================================================
88 """Runs a command in a subshell via standard-C system().
89
90 <command>
91 The shell command to run including command line options.
92 <blocking>
93 This will make the code *block* until the shell command exits.
94 It will likely only work on UNIX shells where "cmd &" makes sense.
95 """
96 _log.debug('shell command >>>%s<<<', command)
97 _log.debug('blocking: %s', blocking)
98
99 # FIXME: command should be checked for shell exploits
100 command = command.strip()
101
102 # what the following hack does is this: the user indicated
103 # whether she wants non-blocking external display of files
104 # - the real way to go about this is to have a non-blocking command
105 # in the line in the mailcap file for the relevant mime types
106 # - as non-blocking may not be desirable when *not* displaying
107 # files from within GNUmed the really right way would be to
108 # add a "test" clause to the non-blocking mailcap entry which
109 # yields true if and only if GNUmed is running
110 # - however, this is cumbersome at best and not supported in
111 # some mailcap implementations
112 # - so we allow the user to attempt some control over the process
113 # from within GNUmed by setting a configuration option
114 # - leaving it None means to use the mailcap default or whatever
115 # was specified in the command itself
116 # - True means: tack " &" onto the shell command if necessary
117 # - False means: remove " &" from the shell command if its there
118 # - all this, of course, only works in shells which support
119 # detaching jobs with " &" (so, most POSIX shells)
120 if blocking is True:
121 if command[-2:] == ' &':
122 command = command[:-2]
123 elif blocking is False:
124 if command[-2:] != ' &':
125 command += ' &'
126
127 _log.info('running shell command >>>%s<<<', command)
128 # FIXME: use subprocess.Popen()
129 ret_val = os.system(command.encode(sys.getfilesystemencoding()))
130 _log.debug('os.system() returned: [%s]', ret_val)
131
132 exited_normally = False
133
134 if not hasattr(os, 'WIFEXITED'):
135 _log.debug('platform does not support exit status differentiation')
136 return exited_normally
137
138 _log.debug('exited via exit(): %s', os.WIFEXITED(ret_val))
139 if os.WIFEXITED(ret_val):
140 _log.debug('exit code: [%s]', os.WEXITSTATUS(ret_val))
141 exited_normally = (os.WEXITSTATUS(ret_val) == 0)
142 _log.debug('normal exit: %s', exited_normally)
143 _log.debug('dumped core: %s', os.WCOREDUMP(ret_val))
144 _log.debug('stopped by signal: %s', os.WIFSIGNALED(ret_val))
145 if os.WIFSIGNALED(ret_val):
146 _log.debug('STOP signal was: [%s]', os.STOPSIG(ret_val))
147 _log.debug('TERM signal was: [%s]', os.TERMSIG(ret_val))
148
149 return exited_normally
150 #===========================================================================
151 -def run_first_available_in_shell(binaries=None, args=None, blocking=False, run_last_one_anyway=False):
152
153 found, binary = find_first_binary(binaries = binaries)
154
155 if not found:
156 if run_last_one_anyway:
157 binary = binaries[-1]
158 else:
159 _log.warning('cannot find any of: %s', binaries)
160 return False
161
162 return run_command_in_shell(command = '%s %s' % (binary, args), blocking = blocking)
163 #===========================================================================
164 # main
165 #---------------------------------------------------------------------------
166 if __name__ == '__main__':
167
168 if len(sys.argv) < 2:
169 sys.exit()
170
171 if sys.argv[1] != u'test':
172 sys.exit()
173
174 logging.basicConfig(level = logging.DEBUG)
175 #---------------------------------------------------------
177 found, path = detect_external_binary(binary = sys.argv[2])
178 if found:
179 print "found as:", path
180 else:
181 print sys.argv[2], "not found"
182 #---------------------------------------------------------
184 print "-------------------------------------"
185 print "running:", sys.argv[2]
186 if run_command_in_shell(command=sys.argv[2], blocking=True):
187 print "-------------------------------------"
188 print "success"
189 else:
190 print "-------------------------------------"
191 print "failure, consult log"
192 #---------------------------------------------------------
193 test_run_command_in_shell()
194 #test_detect_external_binary()
195
196 #===========================================================================
197
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Mon Nov 29 04:04:53 2010 | http://epydoc.sourceforge.net |