source: trunk/src/testing/bin/subprocess.py @ 4

Revision 4, 39.5 KB checked in by ajaworski, 13 years ago (diff)

Added modified SAGE sources

Line 
1# subprocess - Subprocesses with accessible I/O streams
2#
3# For more information about this module, see PEP 324.
4#
5# Copyright (c) 2003-2004 by Peter Astrand <astrand@lysator.liu.se>
6#
7# By obtaining, using, and/or copying this software and/or its
8# associated documentation, you agree that you have read, understood,
9# and will comply with the following terms and conditions:
10#
11# Permission to use, copy, modify, and distribute this software and
12# its associated documentation for any purpose and without fee is
13# hereby granted, provided that the above copyright notice appears in
14# all copies, and that both that copyright notice and this permission
15# notice appear in supporting documentation, and that the name of the
16# author not be used in advertising or publicity pertaining to
17# distribution of the software without specific, written prior
18# permission.
19#
20# THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
21# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
22# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR
23# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
24# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
25# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
26# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
27
28"""subprocess - Subprocesses with accessible I/O streams
29
30This module allows you to spawn processes and connect to their
31input/output/error pipes and obtain their return codes under Unix.
32This module intends to replace several other, older modules and
33functions, like:
34
35os.system
36os.spawn*
37os.popen*
38popen2.*
39commands.*
40
41Information about how the subprocess module can be used to replace these
42modules and functions can be found below.
43
44
45
46Using the subprocess module
47===========================
48This module defines one class called Popen:
49
50class Popen(args, bufsize=0, executable=None,
51            stdin=None, stdout=None, stderr=None,
52            preexec_fn=None, close_fds=False, shell=False,
53            cwd=None, env=None, universal_newlines=False,
54            startupinfo=None, creationflags=0):
55
56
57Arguments are:
58
59args should be a string, or a sequence of program arguments.  The
60program to execute is normally the first item in the args sequence or
61string, but can be explicitly set by using the executable argument.
62
63On UNIX, with shell=False (default): In this case, the Popen class
64uses os.execvp() to execute the child program.  args should normally
65be a sequence.  A string will be treated as a sequence with the string
66as the only item (the program to execute).
67
68On UNIX, with shell=True: If args is a string, it specifies the
69command string to execute through the shell.  If args is a sequence,
70the first item specifies the command string, and any additional items
71will be treated as additional shell arguments.
72
73On Windows: the Popen class uses CreateProcess() to execute the child
74program, which operates on strings.  If args is a sequence, it will be
75converted to a string using the list2cmdline method.  Please note that
76not all MS Windows applications interpret the command line the same
77way: The list2cmdline is designed for applications using the same
78rules as the MS C runtime.
79
80bufsize, if given, has the same meaning as the corresponding argument
81to the built-in open() function: 0 means unbuffered, 1 means line
82buffered, any other positive value means use a buffer of
83(approximately) that size.  A negative bufsize means to use the system
84default, which usually means fully buffered.  The default value for
85bufsize is 0 (unbuffered).
86
87stdin, stdout and stderr specify the executed programs' standard
88input, standard output and standard error file handles, respectively.
89Valid values are PIPE, an existing file descriptor (a positive
90integer), an existing file object, and None.  PIPE indicates that a
91new pipe to the child should be created.  With None, no redirection
92will occur; the child's file handles will be inherited from the
93parent.  Additionally, stderr can be STDOUT, which indicates that the
94stderr data from the applications should be captured into the same
95file handle as for stdout.
96
97If preexec_fn is set to a callable object, this object will be called
98in the child process just before the child is executed.
99
100If close_fds is true, all file descriptors except 0, 1 and 2 will be
101closed before the child process is executed.
102
103if shell is true, the specified command will be executed through the
104shell.
105
106If cwd is not None, the current directory will be changed to cwd
107before the child is executed.
108
109If env is not None, it defines the environment variables for the new
110process.
111
112If universal_newlines is true, the file objects stdout and stderr are
113opened as a text files, but lines may be terminated by any of '\n',
114the Unix end-of-line convention, '\r', the Macintosh convention or
115'\r\n', the Windows convention.  All of these external representations
116are seen as '\n' by the Python program.  Note: This feature is only
117available if Python is built with universal newline support (the
118default).  Also, the newlines attribute of the file objects stdout,
119stdin and stderr are not updated by the communicate() method.
120
121The startupinfo and creationflags, if given, will be passed to the
122underlying CreateProcess() function.  They can specify things such as
123appearance of the main window and priority for the new process.
124(Windows only)
125
126
127This module also defines two shortcut functions:
128
129call(*args, **kwargs):
130    Run command with arguments.  Wait for command to complete, then
131    return the returncode attribute.
132
133    The arguments are the same as for the Popen constructor.  Example:
134
135    retcode = call(["ls", "-l"])
136
137
138Exceptions
139----------
140Exceptions raised in the child process, before the new program has
141started to execute, will be re-raised in the parent.  Additionally,
142the exception object will have one extra attribute called
143'child_traceback', which is a string containing traceback information
144from the childs point of view.
145
146The most common exception raised is OSError.  This occurs, for
147example, when trying to execute a non-existent file.  Applications
148should prepare for OSErrors.
149
150A ValueError will be raised if Popen is called with invalid arguments.
151
152
153Security
154--------
155Unlike some other popen functions, this implementation will never call
156/bin/sh implicitly.  This means that all characters, including shell
157metacharacters, can safely be passed to child processes.
158
159
160Popen objects
161=============
162Instances of the Popen class have the following methods:
163
164poll()
165    Check if child process has terminated.  Returns returncode
166    attribute.
167
168wait()
169    Wait for child process to terminate.  Returns returncode attribute.
170
171communicate(input=None)
172    Interact with process: Send data to stdin.  Read data from stdout
173    and stderr, until end-of-file is reached.  Wait for process to
174    terminate.  The optional stdin argument should be a string to be
175    sent to the child process, or None, if no data should be sent to
176    the child.
177
178    communicate() returns a tuple (stdout, stderr).
179
180    Note: The data read is buffered in memory, so do not use this
181    method if the data size is large or unlimited.
182
183The following attributes are also available:
184
185stdin
186    If the stdin argument is PIPE, this attribute is a file object
187    that provides input to the child process.  Otherwise, it is None.
188
189stdout
190    If the stdout argument is PIPE, this attribute is a file object
191    that provides output from the child process.  Otherwise, it is
192    None.
193
194stderr
195    If the stderr argument is PIPE, this attribute is file object that
196    provides error output from the child process.  Otherwise, it is
197    None.
198
199pid
200    The process ID of the child process.
201
202returncode
203    The child return code.  A None value indicates that the process
204    hasn't terminated yet.  A negative value -N indicates that the
205    child was terminated by signal N (UNIX only).
206
207
208Replacing older functions with the subprocess module
209====================================================
210In this section, "a ==> b" means that b can be used as a replacement
211for a.
212
213Note: All functions in this section fail (more or less) silently if
214the executed program cannot be found; this module raises an OSError
215exception.
216
217In the following examples, we assume that the subprocess module is
218imported with "from subprocess import *".
219
220
221Replacing /bin/sh shell backquote
222---------------------------------
223output=`mycmd myarg`
224==>
225output = Popen(["mycmd", "myarg"], stdout=PIPE).communicate()[0]
226
227
228Replacing shell pipe line
229-------------------------
230output=`dmesg | grep hda`
231==>
232p1 = Popen(["dmesg"], stdout=PIPE)
233p2 = Popen(["grep", "hda"], stdin=p1.stdout)
234output = p2.communicate()[0]
235
236
237Replacing os.system()
238---------------------
239sts = os.system("mycmd" + " myarg")
240==>
241p = Popen("mycmd" + " myarg", shell=True)
242sts = os.waitpid(p.pid, 0)
243
244Note:
245
246* Calling the program through the shell is usually not required.
247
248* It's easier to look at the returncode attribute than the
249  exitstatus.
250
251A more real-world example would look like this:
252
253try:
254    retcode = call("mycmd" + " myarg", shell=True)
255    if retcode < 0:
256        print >>sys.stderr, "Child was terminated by signal", -retcode
257    else:
258        print >>sys.stderr, "Child returned", retcode
259except OSError, e:
260    print >>sys.stderr, "Execution failed:", e
261
262
263Replacing os.spawn*
264-------------------
265P_NOWAIT example:
266
267pid = os.spawnlp(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg")
268==>
269pid = Popen(["/bin/mycmd", "myarg"]).pid
270
271
272P_WAIT example:
273
274retcode = os.spawnlp(os.P_WAIT, "/bin/mycmd", "mycmd", "myarg")
275==>
276retcode = call(["/bin/mycmd", "myarg"])
277
278
279Vector example:
280
281os.spawnvp(os.P_NOWAIT, path, args)
282==>
283Popen([path] + args[1:])
284
285
286Environment example:
287
288os.spawnlpe(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg", env)
289==>
290Popen(["/bin/mycmd", "myarg"], env={"PATH": "/usr/bin"})
291
292
293Replacing os.popen*
294-------------------
295pipe = os.popen(cmd, mode='r', bufsize)
296==>
297pipe = Popen(cmd, shell=True, bufsize=bufsize, stdout=PIPE).stdout
298
299pipe = os.popen(cmd, mode='w', bufsize)
300==>
301pipe = Popen(cmd, shell=True, bufsize=bufsize, stdin=PIPE).stdin
302
303
304(child_stdin, child_stdout) = os.popen2(cmd, mode, bufsize)
305==>
306p = Popen(cmd, shell=True, bufsize=bufsize,
307          stdin=PIPE, stdout=PIPE, close_fds=True)
308(child_stdin, child_stdout) = (p.stdin, p.stdout)
309
310
311(child_stdin,
312 child_stdout,
313 child_stderr) = os.popen3(cmd, mode, bufsize)
314==>
315p = Popen(cmd, shell=True, bufsize=bufsize,
316          stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
317(child_stdin,
318 child_stdout,
319 child_stderr) = (p.stdin, p.stdout, p.stderr)
320
321
322(child_stdin, child_stdout_and_stderr) = os.popen4(cmd, mode, bufsize)
323==>
324p = Popen(cmd, shell=True, bufsize=bufsize,
325          stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
326(child_stdin, child_stdout_and_stderr) = (p.stdin, p.stdout)
327
328
329Replacing popen2.*
330------------------
331Note: If the cmd argument to popen2 functions is a string, the command
332is executed through /bin/sh.  If it is a list, the command is directly
333executed.
334
335(child_stdout, child_stdin) = popen2.popen2("somestring", bufsize, mode)
336==>
337p = Popen(["somestring"], shell=True, bufsize=bufsize
338          stdin=PIPE, stdout=PIPE, close_fds=True)
339(child_stdout, child_stdin) = (p.stdout, p.stdin)
340
341
342(child_stdout, child_stdin) = popen2.popen2(["mycmd", "myarg"], bufsize, mode)
343==>
344p = Popen(["mycmd", "myarg"], bufsize=bufsize,
345          stdin=PIPE, stdout=PIPE, close_fds=True)
346(child_stdout, child_stdin) = (p.stdout, p.stdin)
347
348The popen2.Popen3 and popen3.Popen4 basically works as subprocess.Popen,
349except that:
350
351* subprocess.Popen raises an exception if the execution fails
352* the capturestderr argument is replaced with the stderr argument.
353* stdin=PIPE and stdout=PIPE must be specified.
354* popen2 closes all filedescriptors by default, but you have to specify
355  close_fds=True with subprocess.Popen.
356
357
358"""
359
360import sys
361mswindows = (sys.platform == "win32")
362
363import os
364import types
365import traceback
366
367if mswindows:
368    import threading
369    import msvcrt
370    if 0: # <-- change this to use pywin32 instead of the _subprocess driver
371        import pywintypes
372        from win32api import GetStdHandle, STD_INPUT_HANDLE, \
373                             STD_OUTPUT_HANDLE, STD_ERROR_HANDLE
374        from win32api import GetCurrentProcess, DuplicateHandle, \
375                             GetModuleFileName, GetVersion
376        from win32con import DUPLICATE_SAME_ACCESS
377        from win32pipe import CreatePipe
378        from win32process import CreateProcess, STARTUPINFO, \
379                                 GetExitCodeProcess, STARTF_USESTDHANDLES, \
380                                 CREATE_NEW_CONSOLE
381        from win32event import WaitForSingleObject, INFINITE, WAIT_OBJECT_0
382    else:
383        from _subprocess import *
384        class STARTUPINFO:
385            dwFlags = 0
386            hStdInput = None
387            hStdOutput = None
388            hStdError = None
389        class pywintypes:
390            error = IOError
391else:
392    import select
393    import errno
394    import fcntl
395    import pickle
396
397__all__ = ["Popen", "PIPE", "STDOUT", "call"]
398
399try:
400    MAXFD = os.sysconf("SC_OPEN_MAX")
401except:
402    MAXFD = 256
403
404# True/False does not exist on 2.2.0
405try:
406    False
407except NameError:
408    False = 0
409    True = 1
410
411_active = []
412
413def _cleanup():
414    for inst in _active[:]:
415        inst.poll()
416
417PIPE = -1
418STDOUT = -2
419
420
421def call(*args, **kwargs):
422    """Run command with arguments.  Wait for command to complete, then
423    return the returncode attribute.
424
425    The arguments are the same as for the Popen constructor.  Example:
426
427    retcode = call(["ls", "-l"])
428    """
429    return Popen(*args, **kwargs).wait()
430
431
432def list2cmdline(seq):
433    """
434    Translate a sequence of arguments into a command line
435    string, using the same rules as the MS C runtime:
436
437    1) Arguments are delimited by white space, which is either a
438       space or a tab.
439
440    2) A string surrounded by double quotation marks is
441       interpreted as a single argument, regardless of white space
442       contained within.  A quoted string can be embedded in an
443       argument.
444
445    3) A double quotation mark preceded by a backslash is
446       interpreted as a literal double quotation mark.
447
448    4) Backslashes are interpreted literally, unless they
449       immediately precede a double quotation mark.
450
451    5) If backslashes immediately precede a double quotation mark,
452       every pair of backslashes is interpreted as a literal
453       backslash.  If the number of backslashes is odd, the last
454       backslash escapes the next double quotation mark as
455       described in rule 3.
456    """
457
458    # See
459    # http://msdn.microsoft.com/library/en-us/vccelng/htm/progs_12.asp
460    result = []
461    needquote = False
462    for arg in seq:
463        bs_buf = []
464
465        # Add a space to separate this argument from the others
466        if result:
467            result.append(' ')
468
469        needquote = (" " in arg) or ("\t" in arg)
470        if needquote:
471            result.append('"')
472
473        for c in arg:
474            if c == '\\':
475                # Don't know if we need to double yet.
476                bs_buf.append(c)
477            elif c == '"':
478                # Double backspaces.
479                result.append('\\' * len(bs_buf)*2)
480                bs_buf = []
481                result.append('\\"')
482            else:
483                # Normal char
484                if bs_buf:
485                    result.extend(bs_buf)
486                    bs_buf = []
487                result.append(c)
488
489        # Add remaining backspaces, if any.
490        if bs_buf:
491            result.extend(bs_buf)
492
493        if needquote:
494            result.append('"')
495
496    return ''.join(result)
497
498
499class Popen(object):
500    def __init__(self, args, bufsize=0, executable=None,
501                 stdin=None, stdout=None, stderr=None,
502                 preexec_fn=None, close_fds=False, shell=False,
503                 cwd=None, env=None, universal_newlines=False,
504                 startupinfo=None, creationflags=0):
505        """Create new Popen instance."""
506        _cleanup()
507
508        if mswindows:
509            if preexec_fn is not None:
510                raise ValueError("preexec_fn is not supported on Windows "
511                                 "platforms")
512            if close_fds:
513                raise ValueError("close_fds is not supported on Windows "
514                                 "platforms")
515        else:
516            # POSIX
517            if startupinfo is not None:
518                raise ValueError("startupinfo is only supported on Windows "
519                                 "platforms")
520            if creationflags != 0:
521                raise ValueError("creationflags is only supported on Windows "
522                                 "platforms")
523
524        self.stdin = None
525        self.stdout = None
526        self.stderr = None
527        self.pid = None
528        self.returncode = None
529        self.universal_newlines = universal_newlines
530
531        # Input and output objects. The general principle is like
532        # this:
533        #
534        # Parent                   Child
535        # ------                   -----
536        # p2cwrite   ---stdin--->  p2cread
537        # c2pread    <--stdout---  c2pwrite
538        # errread    <--stderr---  errwrite
539        #
540        # On POSIX, the child objects are file descriptors.  On
541        # Windows, these are Windows file handles.  The parent objects
542        # are file descriptors on both platforms.  The parent objects
543        # are None when not using PIPEs. The child objects are None
544        # when not redirecting.
545
546        (p2cread, p2cwrite,
547         c2pread, c2pwrite,
548         errread, errwrite) = self._get_handles(stdin, stdout, stderr)
549
550        self._execute_child(args, executable, preexec_fn, close_fds,
551                            cwd, env, universal_newlines,
552                            startupinfo, creationflags, shell,
553                            p2cread, p2cwrite,
554                            c2pread, c2pwrite,
555                            errread, errwrite)
556
557        if p2cwrite:
558            self.stdin = os.fdopen(p2cwrite, 'wb', bufsize)
559        if c2pread:
560            if universal_newlines:
561                self.stdout = os.fdopen(c2pread, 'rU', bufsize)
562            else:
563                self.stdout = os.fdopen(c2pread, 'rb', bufsize)
564        if errread:
565            if universal_newlines:
566                self.stderr = os.fdopen(errread, 'rU', bufsize)
567            else:
568                self.stderr = os.fdopen(errread, 'rb', bufsize)
569
570        _active.append(self)
571
572
573    def _translate_newlines(self, data):
574        data = data.replace("\r\n", "\n")
575        data = data.replace("\r", "\n")
576        return data
577
578
579    if mswindows:
580        #
581        # Windows methods
582        #
583        def _get_handles(self, stdin, stdout, stderr):
584            """Construct and return tupel with IO objects:
585            p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite
586            """
587            if stdin == None and stdout == None and stderr == None:
588                return (None, None, None, None, None, None)
589
590            p2cread, p2cwrite = None, None
591            c2pread, c2pwrite = None, None
592            errread, errwrite = None, None
593
594            if stdin == None:
595                p2cread = GetStdHandle(STD_INPUT_HANDLE)
596            elif stdin == PIPE:
597                p2cread, p2cwrite = CreatePipe(None, 0)
598                # Detach and turn into fd
599                p2cwrite = p2cwrite.Detach()
600                p2cwrite = msvcrt.open_osfhandle(p2cwrite, 0)
601            elif type(stdin) == types.IntType:
602                p2cread = msvcrt.get_osfhandle(stdin)
603            else:
604                # Assuming file-like object
605                p2cread = msvcrt.get_osfhandle(stdin.fileno())
606            p2cread = self._make_inheritable(p2cread)
607
608            if stdout == None:
609                c2pwrite = GetStdHandle(STD_OUTPUT_HANDLE)
610            elif stdout == PIPE:
611                c2pread, c2pwrite = CreatePipe(None, 0)
612                # Detach and turn into fd
613                c2pread = c2pread.Detach()
614                c2pread = msvcrt.open_osfhandle(c2pread, 0)
615            elif type(stdout) == types.IntType:
616                c2pwrite = msvcrt.get_osfhandle(stdout)
617            else:
618                # Assuming file-like object
619                c2pwrite = msvcrt.get_osfhandle(stdout.fileno())
620            c2pwrite = self._make_inheritable(c2pwrite)
621
622            if stderr == None:
623                errwrite = GetStdHandle(STD_ERROR_HANDLE)
624            elif stderr == PIPE:
625                errread, errwrite = CreatePipe(None, 0)
626                # Detach and turn into fd
627                errread = errread.Detach()
628                errread = msvcrt.open_osfhandle(errread, 0)
629            elif stderr == STDOUT:
630                errwrite = c2pwrite
631            elif type(stderr) == types.IntType:
632                errwrite = msvcrt.get_osfhandle(stderr)
633            else:
634                # Assuming file-like object
635                errwrite = msvcrt.get_osfhandle(stderr.fileno())
636            errwrite = self._make_inheritable(errwrite)
637
638            return (p2cread, p2cwrite,
639                    c2pread, c2pwrite,
640                    errread, errwrite)
641
642
643        def _make_inheritable(self, handle):
644            """Return a duplicate of handle, which is inheritable"""
645            return DuplicateHandle(GetCurrentProcess(), handle,
646                                   GetCurrentProcess(), 0, 1,
647                                   DUPLICATE_SAME_ACCESS)
648
649
650        def _find_w9xpopen(self):
651            """Find and return absolut path to w9xpopen.exe"""
652            w9xpopen = os.path.join(os.path.dirname(GetModuleFileName(0)),
653                                    "w9xpopen.exe")
654            if not os.path.exists(w9xpopen):
655                # Eeek - file-not-found - possibly an embedding
656                # situation - see if we can locate it in sys.exec_prefix
657                w9xpopen = os.path.join(os.path.dirname(sys.exec_prefix),
658                                        "w9xpopen.exe")
659                if not os.path.exists(w9xpopen):
660                    raise RuntimeError("Cannot locate w9xpopen.exe, which is "
661                                       "needed for Popen to work with your "
662                                       "shell or platform.")
663            return w9xpopen
664
665
666        def _execute_child(self, args, executable, preexec_fn, close_fds,
667                           cwd, env, universal_newlines,
668                           startupinfo, creationflags, shell,
669                           p2cread, p2cwrite,
670                           c2pread, c2pwrite,
671                           errread, errwrite):
672            """Execute program (MS Windows version)"""
673
674            if not isinstance(args, types.StringTypes):
675                args = list2cmdline(args)
676
677            if shell:
678                comspec = os.environ.get("COMSPEC", "cmd.exe")
679                args = comspec + " /c " + args
680                if (GetVersion() >= 0x80000000L or
681                        os.path.basename(comspec).lower() == "command.com"):
682                    # Win9x, or using command.com on NT. We need to
683                    # use the w9xpopen intermediate program. For more
684                    # information, see KB Q150956
685                    # (http://web.archive.org/web/20011105084002/http://support.microsoft.com/support/kb/articles/Q150/9/56.asp)
686                    w9xpopen = self._find_w9xpopen()
687                    args = '"%s" %s' % (w9xpopen, args)
688                    # Not passing CREATE_NEW_CONSOLE has been known to
689                    # cause random failures on win9x.  Specifically a
690                    # dialog: "Your program accessed mem currently in
691                    # use at xxx" and a hopeful warning about the
692                    # stability of your system.  Cost is Ctrl+C wont
693                    # kill children.
694                    creationflags |= CREATE_NEW_CONSOLE
695
696            # Process startup details
697            if startupinfo == None:
698                startupinfo = STARTUPINFO()
699            if not None in (p2cread, c2pwrite, errwrite):
700                startupinfo.dwFlags |= STARTF_USESTDHANDLES
701                startupinfo.hStdInput = p2cread
702                startupinfo.hStdOutput = c2pwrite
703                startupinfo.hStdError = errwrite
704
705            # Start the process
706            try:
707                hp, ht, pid, tid = CreateProcess(executable, args,
708                                         # no special security
709                                         None, None,
710                                         # must inherit handles to pass std
711                                         # handles
712                                         1,
713                                         creationflags,
714                                         env,
715                                         cwd,
716                                         startupinfo)
717            except pywintypes.error, e:
718                # Translate pywintypes.error to WindowsError, which is
719                # a subclass of OSError.  FIXME: We should really
720                # translate errno using _sys_errlist (or simliar), but
721                # how can this be done from Python?
722                raise WindowsError(*e.args)
723
724            # Retain the process handle, but close the thread handle
725            self._handle = hp
726            self.pid = pid
727            ht.Close()
728
729            # Child is launched. Close the parent's copy of those pipe
730            # handles that only the child should have open.  You need
731            # to make sure that no handles to the write end of the
732            # output pipe are maintained in this process or else the
733            # pipe will not close when the child process exits and the
734            # ReadFile will hang.
735            if p2cread != None:
736                p2cread.Close()
737            if c2pwrite != None:
738                c2pwrite.Close()
739            if errwrite != None:
740                errwrite.Close()
741
742
743        def poll(self):
744            """Check if child process has terminated.  Returns returncode
745            attribute."""
746            if self.returncode == None:
747                if WaitForSingleObject(self._handle, 0) == WAIT_OBJECT_0:
748                    self.returncode = GetExitCodeProcess(self._handle)
749                    _active.remove(self)
750            return self.returncode
751
752
753        def wait(self):
754            """Wait for child process to terminate.  Returns returncode
755            attribute."""
756            if self.returncode == None:
757                obj = WaitForSingleObject(self._handle, INFINITE)
758                self.returncode = GetExitCodeProcess(self._handle)
759                _active.remove(self)
760            return self.returncode
761
762
763        def _readerthread(self, fh, buffer):
764            buffer.append(fh.read())
765
766
767        def communicate(self, input=None):
768            """Interact with process: Send data to stdin.  Read data from
769            stdout and stderr, until end-of-file is reached.  Wait for
770            process to terminate.  The optional input argument should be a
771            string to be sent to the child process, or None, if no data
772            should be sent to the child.
773
774            communicate() returns a tuple (stdout, stderr)."""
775            stdout = None # Return
776            stderr = None # Return
777
778            if self.stdout:
779                stdout = []
780                stdout_thread = threading.Thread(target=self._readerthread,
781                                                 args=(self.stdout, stdout))
782                stdout_thread.setDaemon(True)
783                stdout_thread.start()
784            if self.stderr:
785                stderr = []
786                stderr_thread = threading.Thread(target=self._readerthread,
787                                                 args=(self.stderr, stderr))
788                stderr_thread.setDaemon(True)
789                stderr_thread.start()
790
791            if self.stdin:
792                if input != None:
793                    self.stdin.write(input)
794                self.stdin.close()
795
796            if self.stdout:
797                stdout_thread.join()
798            if self.stderr:
799                stderr_thread.join()
800
801            # All data exchanged.  Translate lists into strings.
802            if stdout != None:
803                stdout = stdout[0]
804            if stderr != None:
805                stderr = stderr[0]
806
807            # Translate newlines, if requested.  We cannot let the file
808            # object do the translation: It is based on stdio, which is
809            # impossible to combine with select (unless forcing no
810            # buffering).
811            if self.universal_newlines and hasattr(open, 'newlines'):
812                if stdout:
813                    stdout = self._translate_newlines(stdout)
814                if stderr:
815                    stderr = self._translate_newlines(stderr)
816
817            self.wait()
818            return (stdout, stderr)
819
820    else:
821        #
822        # POSIX methods
823        #
824        def _get_handles(self, stdin, stdout, stderr):
825            """Construct and return tupel with IO objects:
826            p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite
827            """
828            p2cread, p2cwrite = None, None
829            c2pread, c2pwrite = None, None
830            errread, errwrite = None, None
831
832            if stdin == None:
833                pass
834            elif stdin == PIPE:
835                p2cread, p2cwrite = os.pipe()
836            elif type(stdin) == types.IntType:
837                p2cread = stdin
838            else:
839                # Assuming file-like object
840                p2cread = stdin.fileno()
841
842            if stdout == None:
843                pass
844            elif stdout == PIPE:
845                c2pread, c2pwrite = os.pipe()
846            elif type(stdout) == types.IntType:
847                c2pwrite = stdout
848            else:
849                # Assuming file-like object
850                c2pwrite = stdout.fileno()
851
852            if stderr == None:
853                pass
854            elif stderr == PIPE:
855                errread, errwrite = os.pipe()
856            elif stderr == STDOUT:
857                errwrite = c2pwrite
858            elif type(stderr) == types.IntType:
859                errwrite = stderr
860            else:
861                # Assuming file-like object
862                errwrite = stderr.fileno()
863
864            return (p2cread, p2cwrite,
865                    c2pread, c2pwrite,
866                    errread, errwrite)
867
868
869        def _set_cloexec_flag(self, fd):
870            try:
871                cloexec_flag = fcntl.FD_CLOEXEC
872            except AttributeError:
873                cloexec_flag = 1
874
875            old = fcntl.fcntl(fd, fcntl.F_GETFD)
876            fcntl.fcntl(fd, fcntl.F_SETFD, old | cloexec_flag)
877
878
879        def _close_fds(self, but):
880            for i in range(3, MAXFD):
881                if i == but:
882                    continue
883                try:
884                    os.close(i)
885                except:
886                    pass
887
888
889        def _execute_child(self, args, executable, preexec_fn, close_fds,
890                           cwd, env, universal_newlines,
891                           startupinfo, creationflags, shell,
892                           p2cread, p2cwrite,
893                           c2pread, c2pwrite,
894                           errread, errwrite):
895            """Execute program (POSIX version)"""
896
897            if isinstance(args, types.StringTypes):
898                args = [args]
899
900            if shell:
901                args = ["/bin/sh", "-c"] + args
902
903            if executable == None:
904                executable = args[0]
905
906            # For transferring possible exec failure from child to parent
907            # The first char specifies the exception type: 0 means
908            # OSError, 1 means some other error.
909            errpipe_read, errpipe_write = os.pipe()
910            self._set_cloexec_flag(errpipe_write)
911
912            self.pid = os.fork()
913            if self.pid == 0:
914                # Child
915                try:
916                    # Close parent's pipe ends
917                    if p2cwrite:
918                        os.close(p2cwrite)
919                    if c2pread:
920                        os.close(c2pread)
921                    if errread:
922                        os.close(errread)
923                    os.close(errpipe_read)
924
925                    # Dup fds for child
926                    if p2cread:
927                        os.dup2(p2cread, 0)
928                    if c2pwrite:
929                        os.dup2(c2pwrite, 1)
930                    if errwrite:
931                        os.dup2(errwrite, 2)
932
933                    # Close pipe fds.  Make sure we doesn't close the same
934                    # fd more than once.
935                    if p2cread:
936                        os.close(p2cread)
937                    if c2pwrite and c2pwrite not in (p2cread,):
938                        os.close(c2pwrite)
939                    if errwrite and errwrite not in (p2cread, c2pwrite):
940                        os.close(errwrite)
941
942                    # Close all other fds, if asked for
943                    if close_fds:
944                        self._close_fds(but=errpipe_write)
945
946                    if cwd != None:
947                        os.chdir(cwd)
948
949                    if preexec_fn:
950                        apply(preexec_fn)
951
952                    if env == None:
953                        os.execvp(executable, args)
954                    else:
955                        os.execvpe(executable, args, env)
956
957                except:
958                    exc_type, exc_value, tb = sys.exc_info()
959                    # Save the traceback and attach it to the exception object
960                    exc_lines = traceback.format_exception(exc_type,
961                                                           exc_value,
962                                                           tb)
963                    exc_value.child_traceback = ''.join(exc_lines)
964                    os.write(errpipe_write, pickle.dumps(exc_value))
965
966                # This exitcode won't be reported to applications, so it
967                # really doesn't matter what we return.
968                os._exit(255)
969
970            # Parent
971            os.close(errpipe_write)
972            if p2cread and p2cwrite:
973                os.close(p2cread)
974            if c2pwrite and c2pread:
975                os.close(c2pwrite)
976            if errwrite and errread:
977                os.close(errwrite)
978
979            # Wait for exec to fail or succeed; possibly raising exception
980            data = os.read(errpipe_read, 1048576) # Exceptions limited to 1 MB
981            os.close(errpipe_read)
982            if data != "":
983                child_exception = pickle.loads(data)
984                raise child_exception
985
986
987        def _handle_exitstatus(self, sts):
988            if os.WIFSIGNALED(sts):
989                self.returncode = -os.WTERMSIG(sts)
990            elif os.WIFEXITED(sts):
991                self.returncode = os.WEXITSTATUS(sts)
992            else:
993                # Should never happen
994                raise RuntimeError("Unknown child exit status!")
995
996            _active.remove(self)
997
998
999        def poll(self):
1000            """Check if child process has terminated.  Returns returncode
1001            attribute."""
1002            if self.returncode == None:
1003                try:
1004                    pid, sts = os.waitpid(self.pid, os.WNOHANG)
1005                    if pid == self.pid:
1006                        self._handle_exitstatus(sts)
1007                except os.error:
1008                    pass
1009            return self.returncode
1010
1011
1012        def wait(self):
1013            """Wait for child process to terminate.  Returns returncode
1014            attribute."""
1015            if self.returncode == None:
1016                pid, sts = os.waitpid(self.pid, 0)
1017                self._handle_exitstatus(sts)
1018            return self.returncode
1019
1020
1021        def communicate(self, input=None):
1022            """Interact with process: Send data to stdin.  Read data from
1023            stdout and stderr, until end-of-file is reached.  Wait for
1024            process to terminate.  The optional input argument should be a
1025            string to be sent to the child process, or None, if no data
1026            should be sent to the child.
1027
1028            communicate() returns a tuple (stdout, stderr)."""
1029            read_set = []
1030            write_set = []
1031            stdout = None # Return
1032            stderr = None # Return
1033
1034            if self.stdin:
1035                # Flush stdio buffer.  This might block, if the user has
1036                # been writing to .stdin in an uncontrolled fashion.
1037                self.stdin.flush()
1038                if input:
1039                    write_set.append(self.stdin)
1040                else:
1041                    self.stdin.close()
1042            if self.stdout:
1043                read_set.append(self.stdout)
1044                stdout = []
1045            if self.stderr:
1046                read_set.append(self.stderr)
1047                stderr = []
1048
1049            while read_set or write_set:
1050                rlist, wlist, xlist = select.select(read_set, write_set, [])
1051
1052                if self.stdin in wlist:
1053                    # When select has indicated that the file is writable,
1054                    # we can write up to PIPE_BUF bytes without risk
1055                    # blocking.  POSIX defines PIPE_BUF >= 512
1056                    bytes_written = os.write(self.stdin.fileno(), input[:512])
1057                    input = input[bytes_written:]
1058                    if not input:
1059                        self.stdin.close()
1060                        write_set.remove(self.stdin)
1061
1062                if self.stdout in rlist:
1063                    data = os.read(self.stdout.fileno(), 1024)
1064                    if data == "":
1065                        self.stdout.close()
1066                        read_set.remove(self.stdout)
1067                    stdout.append(data)
1068
1069                if self.stderr in rlist:
1070                    data = os.read(self.stderr.fileno(), 1024)
1071                    if data == "":
1072                        self.stderr.close()
1073                        read_set.remove(self.stderr)
1074                    stderr.append(data)
1075
1076            # All data exchanged.  Translate lists into strings.
1077            if stdout != None:
1078                stdout = ''.join(stdout)
1079            if stderr != None:
1080                stderr = ''.join(stderr)
1081
1082            # Translate newlines, if requested.  We cannot let the file
1083            # object do the translation: It is based on stdio, which is
1084            # impossible to combine with select (unless forcing no
1085            # buffering).
1086            if self.universal_newlines and hasattr(open, 'newlines'):
1087                if stdout:
1088                    stdout = self._translate_newlines(stdout)
1089                if stderr:
1090                    stderr = self._translate_newlines(stderr)
1091
1092            self.wait()
1093            return (stdout, stderr)
1094
1095
1096def _demo_posix():
1097    #
1098    # Example 1: Simple redirection: Get process list
1099    #
1100    plist = Popen(["ps"], stdout=PIPE).communicate()[0]
1101    print "Process list:"
1102    print plist
1103
1104    #
1105    # Example 2: Change uid before executing child
1106    #
1107    if os.getuid() == 0:
1108        p = Popen(["id"], preexec_fn=lambda: os.setuid(100))
1109        p.wait()
1110
1111    #
1112    # Example 3: Connecting several subprocesses
1113    #
1114    print "Looking for 'hda'..."
1115    p1 = Popen(["dmesg"], stdout=PIPE)
1116    p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
1117    print repr(p2.communicate()[0])
1118
1119    #
1120    # Example 4: Catch execution error
1121    #
1122    print
1123    print "Trying a weird file..."
1124    try:
1125        print Popen(["/this/path/does/not/exist"]).communicate()
1126    except OSError, e:
1127        if e.errno == errno.ENOENT:
1128            print "The file didn't exist.  I thought so..."
1129            print "Child traceback:"
1130            print e.child_traceback
1131        else:
1132            print "Error", e.errno
1133    else:
1134        print >>sys.stderr, "Gosh.  No error."
1135
1136
1137def _demo_windows():
1138    #
1139    # Example 1: Connecting several subprocesses
1140    #
1141    print "Looking for 'PROMPT' in set output..."
1142    p1 = Popen("set", stdout=PIPE, shell=True)
1143    p2 = Popen('find "PROMPT"', stdin=p1.stdout, stdout=PIPE)
1144    print repr(p2.communicate()[0])
1145
1146    #
1147    # Example 2: Simple execution of program
1148    #
1149    print "Executing calc..."
1150    p = Popen("calc")
1151    p.wait()
1152
1153
1154if __name__ == "__main__":
1155    if mswindows:
1156        _demo_windows()
1157    else:
1158        _demo_posix()
Note: See TracBrowser for help on using the repository browser.