source: publico/il.spdo/trunk/PasteScript-1.7.4.2-py2.6.egg/paste/script/util/subprocess24.py @ 5327

Última Alteração nesse arquivo desde 5327 foi 5327, incluída por fabianosantos, 8 anos atrás

Import inicial.

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

The contents and data of this website are published under license:
Creative Commons 4.0 Brasil - Atribuir Fonte - Compartilhar Igual.