2006-03-18 05:07:36 +03:00
|
|
|
# -*-python-*-
|
|
|
|
#
|
2013-01-04 23:01:54 +04:00
|
|
|
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
|
2006-03-18 05:07:36 +03:00
|
|
|
#
|
|
|
|
# By using this file, you agree to the terms and conditions set forth in
|
|
|
|
# the LICENSE.html file which can be found at the top level of the ViewVC
|
|
|
|
# distribution or at http://viewvc.org/license-1.html.
|
|
|
|
#
|
|
|
|
# For more information, visit http://viewvc.org/
|
|
|
|
#
|
|
|
|
# -----------------------------------------------------------------------
|
|
|
|
#
|
2003-02-09 12:57:46 +03:00
|
|
|
# Utilities for controlling processes and pipes on win32
|
2006-03-18 05:07:36 +03:00
|
|
|
#
|
|
|
|
# -----------------------------------------------------------------------
|
2003-02-09 12:57:46 +03:00
|
|
|
|
Wow. Drop a "general code cleanup" kind of bomb on the codebase. All
of this is aimed at not paying the maintenance price of supporting
Python versions prior to 2.4 any longer, plus a little bit of just
getting dead code out of the way.
* lib/compat.py
Remove as unused.
* bin/cvsdbadmin,
* bin/loginfo-handler,
* bin/make-database,
* bin/svndbadmin,
* lib/accept.py,
* lib/blame.py,
* lib/cvsdb.py,
* lib/popen.py,
* lib/query.py,
* lib/sapi.py,
* lib/vcauth/forbidden/__init__.py
* lib/vcauth/forbiddenre/__init__.py,
* lib/vcauth/svnauthz/__init__.py,
* lib/vclib/__init__.py,
* lib/vclib/ccvs/blame.py,
* lib/win32popen.py,
* tests/timelog.py
Replace explicit import and use of the 'string' module with newer constructs.
* bin/standalone.py,
* lib/viewvc.py
No longer use 'compat' module. Replace explicit import and use of
the 'string' module with newer constructs.
* lib/dbi.py
Use calender.timegm() instead of compat.timegm().
* lib/vcauth/__init__.py
Lose unused module imports.
* lib/config.py,
Replace explicit import and use of the 'string' module with newer
constructs where possible. Lose old ConfigParser patch-up code for
Python 1.5.1.
* lib/vclib/ccvs/ccvs.py
Replace explicit import and use of the 'string' module with newer
constructs where possible. Import _path_join() from bincvs, and use
it instead of a bunch of copy-and-pasted string join() statements
throughout.
* lib/vclib/ccvs/__init__.py
(cvs_strptime): Moved here from the 'compat' module.
* lib/vclib/ccvs/bincvs.py
(): No longer use 'compat' module. Replace explicit import and use
of the 'string' module with newer constructs.
(_path_join): New, used now instead of a bunch of copy-and-pasted
string join() statements throughout.
* viewvc-install
Don't use the 'compat' module any more.
Also, so some rearranging of non-critical bits.
* misc/: New directory.
* misc/py2html.py: Moved from 'lib/py2html.py'.
* misc/PyFontify.py: Moved from 'lib/PyFontify.py'.
* misc/elemx/: Moved from 'elemx/'.
* misc/tparse/: Moved from 'tparse/'.
* tools/make-release
Omit 'misc' directory from releases, too.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2437 8cb11bc2-c004-0410-86c3-e597b4017df7
2010-09-03 20:49:52 +04:00
|
|
|
import os, sys, traceback, thread
|
2007-04-02 16:38:33 +04:00
|
|
|
try:
|
|
|
|
import win32api
|
|
|
|
except ImportError, e:
|
|
|
|
raise ImportError, str(e) + """
|
|
|
|
|
|
|
|
Did you install the Python for Windows Extensions?
|
|
|
|
|
|
|
|
http://sourceforge.net/projects/pywin32/
|
|
|
|
"""
|
|
|
|
|
2005-12-22 20:04:44 +03:00
|
|
|
import win32process, win32pipe, win32con
|
2007-04-02 16:38:33 +04:00
|
|
|
import win32event, win32file, winerror
|
2003-02-09 12:57:46 +03:00
|
|
|
import pywintypes, msvcrt
|
|
|
|
|
|
|
|
# Buffer size for spooling
|
|
|
|
SPOOL_BYTES = 4096
|
|
|
|
|
|
|
|
# File object to write error messages
|
2003-06-10 03:20:00 +04:00
|
|
|
SPOOL_ERROR = sys.stderr
|
2003-02-09 12:57:46 +03:00
|
|
|
#SPOOL_ERROR = open("m:/temp/error.txt", "wt")
|
|
|
|
|
|
|
|
def CommandLine(command, args):
|
|
|
|
"""Convert an executable path and a sequence of arguments into a command
|
|
|
|
line that can be passed to CreateProcess"""
|
2003-06-10 03:20:00 +04:00
|
|
|
|
Wow. Drop a "general code cleanup" kind of bomb on the codebase. All
of this is aimed at not paying the maintenance price of supporting
Python versions prior to 2.4 any longer, plus a little bit of just
getting dead code out of the way.
* lib/compat.py
Remove as unused.
* bin/cvsdbadmin,
* bin/loginfo-handler,
* bin/make-database,
* bin/svndbadmin,
* lib/accept.py,
* lib/blame.py,
* lib/cvsdb.py,
* lib/popen.py,
* lib/query.py,
* lib/sapi.py,
* lib/vcauth/forbidden/__init__.py
* lib/vcauth/forbiddenre/__init__.py,
* lib/vcauth/svnauthz/__init__.py,
* lib/vclib/__init__.py,
* lib/vclib/ccvs/blame.py,
* lib/win32popen.py,
* tests/timelog.py
Replace explicit import and use of the 'string' module with newer constructs.
* bin/standalone.py,
* lib/viewvc.py
No longer use 'compat' module. Replace explicit import and use of
the 'string' module with newer constructs.
* lib/dbi.py
Use calender.timegm() instead of compat.timegm().
* lib/vcauth/__init__.py
Lose unused module imports.
* lib/config.py,
Replace explicit import and use of the 'string' module with newer
constructs where possible. Lose old ConfigParser patch-up code for
Python 1.5.1.
* lib/vclib/ccvs/ccvs.py
Replace explicit import and use of the 'string' module with newer
constructs where possible. Import _path_join() from bincvs, and use
it instead of a bunch of copy-and-pasted string join() statements
throughout.
* lib/vclib/ccvs/__init__.py
(cvs_strptime): Moved here from the 'compat' module.
* lib/vclib/ccvs/bincvs.py
(): No longer use 'compat' module. Replace explicit import and use
of the 'string' module with newer constructs.
(_path_join): New, used now instead of a bunch of copy-and-pasted
string join() statements throughout.
* viewvc-install
Don't use the 'compat' module any more.
Also, so some rearranging of non-critical bits.
* misc/: New directory.
* misc/py2html.py: Moved from 'lib/py2html.py'.
* misc/PyFontify.py: Moved from 'lib/PyFontify.py'.
* misc/elemx/: Moved from 'elemx/'.
* misc/tparse/: Moved from 'tparse/'.
* tools/make-release
Omit 'misc' directory from releases, too.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2437 8cb11bc2-c004-0410-86c3-e597b4017df7
2010-09-03 20:49:52 +04:00
|
|
|
cmd = "\"" + command.replace("\"", "\"\"") + "\""
|
2003-02-09 12:57:46 +03:00
|
|
|
for arg in args:
|
Wow. Drop a "general code cleanup" kind of bomb on the codebase. All
of this is aimed at not paying the maintenance price of supporting
Python versions prior to 2.4 any longer, plus a little bit of just
getting dead code out of the way.
* lib/compat.py
Remove as unused.
* bin/cvsdbadmin,
* bin/loginfo-handler,
* bin/make-database,
* bin/svndbadmin,
* lib/accept.py,
* lib/blame.py,
* lib/cvsdb.py,
* lib/popen.py,
* lib/query.py,
* lib/sapi.py,
* lib/vcauth/forbidden/__init__.py
* lib/vcauth/forbiddenre/__init__.py,
* lib/vcauth/svnauthz/__init__.py,
* lib/vclib/__init__.py,
* lib/vclib/ccvs/blame.py,
* lib/win32popen.py,
* tests/timelog.py
Replace explicit import and use of the 'string' module with newer constructs.
* bin/standalone.py,
* lib/viewvc.py
No longer use 'compat' module. Replace explicit import and use of
the 'string' module with newer constructs.
* lib/dbi.py
Use calender.timegm() instead of compat.timegm().
* lib/vcauth/__init__.py
Lose unused module imports.
* lib/config.py,
Replace explicit import and use of the 'string' module with newer
constructs where possible. Lose old ConfigParser patch-up code for
Python 1.5.1.
* lib/vclib/ccvs/ccvs.py
Replace explicit import and use of the 'string' module with newer
constructs where possible. Import _path_join() from bincvs, and use
it instead of a bunch of copy-and-pasted string join() statements
throughout.
* lib/vclib/ccvs/__init__.py
(cvs_strptime): Moved here from the 'compat' module.
* lib/vclib/ccvs/bincvs.py
(): No longer use 'compat' module. Replace explicit import and use
of the 'string' module with newer constructs.
(_path_join): New, used now instead of a bunch of copy-and-pasted
string join() statements throughout.
* viewvc-install
Don't use the 'compat' module any more.
Also, so some rearranging of non-critical bits.
* misc/: New directory.
* misc/py2html.py: Moved from 'lib/py2html.py'.
* misc/PyFontify.py: Moved from 'lib/PyFontify.py'.
* misc/elemx/: Moved from 'elemx/'.
* misc/tparse/: Moved from 'tparse/'.
* tools/make-release
Omit 'misc' directory from releases, too.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2437 8cb11bc2-c004-0410-86c3-e597b4017df7
2010-09-03 20:49:52 +04:00
|
|
|
cmd = cmd + " \"" + arg.replace("\"", "\"\"") + "\""
|
2003-02-09 12:57:46 +03:00
|
|
|
return cmd
|
|
|
|
|
|
|
|
def CreateProcess(cmd, hStdInput, hStdOutput, hStdError):
|
|
|
|
"""Creates a new process which uses the specified handles for its standard
|
|
|
|
input, output, and error. The handles must be inheritable. 0 can be passed
|
|
|
|
as a special handle indicating that the process should inherit the current
|
|
|
|
process's input, output, or error streams, and None can be passed to discard
|
|
|
|
the child process's output or to prevent it from reading any input."""
|
|
|
|
|
|
|
|
# initialize new process's startup info
|
|
|
|
si = win32process.STARTUPINFO()
|
|
|
|
si.dwFlags = win32process.STARTF_USESTDHANDLES
|
|
|
|
|
|
|
|
if hStdInput == 0:
|
|
|
|
si.hStdInput = win32api.GetStdHandle(win32api.STD_INPUT_HANDLE)
|
|
|
|
else:
|
|
|
|
si.hStdInput = hStdInput
|
2003-06-10 03:20:00 +04:00
|
|
|
|
2003-02-09 12:57:46 +03:00
|
|
|
if hStdOutput == 0:
|
|
|
|
si.hStdOutput = win32api.GetStdHandle(win32api.STD_OUTPUT_HANDLE)
|
|
|
|
else:
|
|
|
|
si.hStdOutput = hStdOutput
|
|
|
|
|
|
|
|
if hStdError == 0:
|
2003-06-10 03:20:00 +04:00
|
|
|
si.hStdError = win32api.GetStdHandle(win32api.STD_ERROR_HANDLE)
|
2003-02-09 12:57:46 +03:00
|
|
|
else:
|
|
|
|
si.hStdError = hStdError
|
|
|
|
|
|
|
|
# create the process
|
|
|
|
phandle, pid, thandle, tid = win32process.CreateProcess \
|
|
|
|
( None, # appName
|
|
|
|
cmd, # commandLine
|
|
|
|
None, # processAttributes
|
|
|
|
None, # threadAttributes
|
|
|
|
1, # bInheritHandles
|
|
|
|
win32con.NORMAL_PRIORITY_CLASS, # dwCreationFlags
|
|
|
|
None, # newEnvironment
|
|
|
|
None, # currentDirectory
|
|
|
|
si # startupinfo
|
|
|
|
)
|
2003-06-10 03:20:00 +04:00
|
|
|
|
2003-02-09 12:57:46 +03:00
|
|
|
if hStdInput and hasattr(hStdInput, 'Close'):
|
|
|
|
hStdInput.Close()
|
|
|
|
|
|
|
|
if hStdOutput and hasattr(hStdOutput, 'Close'):
|
|
|
|
hStdOutput.Close()
|
|
|
|
|
|
|
|
if hStdError and hasattr(hStdError, 'Close'):
|
|
|
|
hStdError.Close()
|
2003-06-10 03:20:00 +04:00
|
|
|
|
2003-02-09 12:57:46 +03:00
|
|
|
return phandle, pid, thandle, tid
|
2003-06-10 03:20:00 +04:00
|
|
|
|
2003-06-02 08:40:44 +04:00
|
|
|
def CreatePipe(readInheritable, writeInheritable):
|
2003-02-09 12:57:46 +03:00
|
|
|
"""Create a new pipe specifying whether the read and write ends are
|
|
|
|
inheritable and whether they should be created for blocking or nonblocking
|
|
|
|
I/O."""
|
2003-06-10 03:20:00 +04:00
|
|
|
|
2003-06-02 08:40:44 +04:00
|
|
|
r, w = win32pipe.CreatePipe(None, SPOOL_BYTES)
|
2003-02-09 12:57:46 +03:00
|
|
|
if readInheritable:
|
2003-06-02 08:40:44 +04:00
|
|
|
r = MakeInheritedHandle(r)
|
2003-02-09 12:57:46 +03:00
|
|
|
if writeInheritable:
|
2003-06-02 08:40:44 +04:00
|
|
|
w = MakeInheritedHandle(w)
|
2003-02-09 12:57:46 +03:00
|
|
|
return r, w
|
|
|
|
|
|
|
|
def File2FileObject(pipe, mode):
|
|
|
|
"""Make a C stdio file object out of a win32 file handle"""
|
Wow. Drop a "general code cleanup" kind of bomb on the codebase. All
of this is aimed at not paying the maintenance price of supporting
Python versions prior to 2.4 any longer, plus a little bit of just
getting dead code out of the way.
* lib/compat.py
Remove as unused.
* bin/cvsdbadmin,
* bin/loginfo-handler,
* bin/make-database,
* bin/svndbadmin,
* lib/accept.py,
* lib/blame.py,
* lib/cvsdb.py,
* lib/popen.py,
* lib/query.py,
* lib/sapi.py,
* lib/vcauth/forbidden/__init__.py
* lib/vcauth/forbiddenre/__init__.py,
* lib/vcauth/svnauthz/__init__.py,
* lib/vclib/__init__.py,
* lib/vclib/ccvs/blame.py,
* lib/win32popen.py,
* tests/timelog.py
Replace explicit import and use of the 'string' module with newer constructs.
* bin/standalone.py,
* lib/viewvc.py
No longer use 'compat' module. Replace explicit import and use of
the 'string' module with newer constructs.
* lib/dbi.py
Use calender.timegm() instead of compat.timegm().
* lib/vcauth/__init__.py
Lose unused module imports.
* lib/config.py,
Replace explicit import and use of the 'string' module with newer
constructs where possible. Lose old ConfigParser patch-up code for
Python 1.5.1.
* lib/vclib/ccvs/ccvs.py
Replace explicit import and use of the 'string' module with newer
constructs where possible. Import _path_join() from bincvs, and use
it instead of a bunch of copy-and-pasted string join() statements
throughout.
* lib/vclib/ccvs/__init__.py
(cvs_strptime): Moved here from the 'compat' module.
* lib/vclib/ccvs/bincvs.py
(): No longer use 'compat' module. Replace explicit import and use
of the 'string' module with newer constructs.
(_path_join): New, used now instead of a bunch of copy-and-pasted
string join() statements throughout.
* viewvc-install
Don't use the 'compat' module any more.
Also, so some rearranging of non-critical bits.
* misc/: New directory.
* misc/py2html.py: Moved from 'lib/py2html.py'.
* misc/PyFontify.py: Moved from 'lib/PyFontify.py'.
* misc/elemx/: Moved from 'elemx/'.
* misc/tparse/: Moved from 'tparse/'.
* tools/make-release
Omit 'misc' directory from releases, too.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2437 8cb11bc2-c004-0410-86c3-e597b4017df7
2010-09-03 20:49:52 +04:00
|
|
|
if mode.find('r') >= 0:
|
2003-02-09 12:57:46 +03:00
|
|
|
wmode = os.O_RDONLY
|
Wow. Drop a "general code cleanup" kind of bomb on the codebase. All
of this is aimed at not paying the maintenance price of supporting
Python versions prior to 2.4 any longer, plus a little bit of just
getting dead code out of the way.
* lib/compat.py
Remove as unused.
* bin/cvsdbadmin,
* bin/loginfo-handler,
* bin/make-database,
* bin/svndbadmin,
* lib/accept.py,
* lib/blame.py,
* lib/cvsdb.py,
* lib/popen.py,
* lib/query.py,
* lib/sapi.py,
* lib/vcauth/forbidden/__init__.py
* lib/vcauth/forbiddenre/__init__.py,
* lib/vcauth/svnauthz/__init__.py,
* lib/vclib/__init__.py,
* lib/vclib/ccvs/blame.py,
* lib/win32popen.py,
* tests/timelog.py
Replace explicit import and use of the 'string' module with newer constructs.
* bin/standalone.py,
* lib/viewvc.py
No longer use 'compat' module. Replace explicit import and use of
the 'string' module with newer constructs.
* lib/dbi.py
Use calender.timegm() instead of compat.timegm().
* lib/vcauth/__init__.py
Lose unused module imports.
* lib/config.py,
Replace explicit import and use of the 'string' module with newer
constructs where possible. Lose old ConfigParser patch-up code for
Python 1.5.1.
* lib/vclib/ccvs/ccvs.py
Replace explicit import and use of the 'string' module with newer
constructs where possible. Import _path_join() from bincvs, and use
it instead of a bunch of copy-and-pasted string join() statements
throughout.
* lib/vclib/ccvs/__init__.py
(cvs_strptime): Moved here from the 'compat' module.
* lib/vclib/ccvs/bincvs.py
(): No longer use 'compat' module. Replace explicit import and use
of the 'string' module with newer constructs.
(_path_join): New, used now instead of a bunch of copy-and-pasted
string join() statements throughout.
* viewvc-install
Don't use the 'compat' module any more.
Also, so some rearranging of non-critical bits.
* misc/: New directory.
* misc/py2html.py: Moved from 'lib/py2html.py'.
* misc/PyFontify.py: Moved from 'lib/PyFontify.py'.
* misc/elemx/: Moved from 'elemx/'.
* misc/tparse/: Moved from 'tparse/'.
* tools/make-release
Omit 'misc' directory from releases, too.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2437 8cb11bc2-c004-0410-86c3-e597b4017df7
2010-09-03 20:49:52 +04:00
|
|
|
elif mode.find('w') >= 0:
|
2003-02-09 12:57:46 +03:00
|
|
|
wmode = os.O_WRONLY
|
Wow. Drop a "general code cleanup" kind of bomb on the codebase. All
of this is aimed at not paying the maintenance price of supporting
Python versions prior to 2.4 any longer, plus a little bit of just
getting dead code out of the way.
* lib/compat.py
Remove as unused.
* bin/cvsdbadmin,
* bin/loginfo-handler,
* bin/make-database,
* bin/svndbadmin,
* lib/accept.py,
* lib/blame.py,
* lib/cvsdb.py,
* lib/popen.py,
* lib/query.py,
* lib/sapi.py,
* lib/vcauth/forbidden/__init__.py
* lib/vcauth/forbiddenre/__init__.py,
* lib/vcauth/svnauthz/__init__.py,
* lib/vclib/__init__.py,
* lib/vclib/ccvs/blame.py,
* lib/win32popen.py,
* tests/timelog.py
Replace explicit import and use of the 'string' module with newer constructs.
* bin/standalone.py,
* lib/viewvc.py
No longer use 'compat' module. Replace explicit import and use of
the 'string' module with newer constructs.
* lib/dbi.py
Use calender.timegm() instead of compat.timegm().
* lib/vcauth/__init__.py
Lose unused module imports.
* lib/config.py,
Replace explicit import and use of the 'string' module with newer
constructs where possible. Lose old ConfigParser patch-up code for
Python 1.5.1.
* lib/vclib/ccvs/ccvs.py
Replace explicit import and use of the 'string' module with newer
constructs where possible. Import _path_join() from bincvs, and use
it instead of a bunch of copy-and-pasted string join() statements
throughout.
* lib/vclib/ccvs/__init__.py
(cvs_strptime): Moved here from the 'compat' module.
* lib/vclib/ccvs/bincvs.py
(): No longer use 'compat' module. Replace explicit import and use
of the 'string' module with newer constructs.
(_path_join): New, used now instead of a bunch of copy-and-pasted
string join() statements throughout.
* viewvc-install
Don't use the 'compat' module any more.
Also, so some rearranging of non-critical bits.
* misc/: New directory.
* misc/py2html.py: Moved from 'lib/py2html.py'.
* misc/PyFontify.py: Moved from 'lib/PyFontify.py'.
* misc/elemx/: Moved from 'elemx/'.
* misc/tparse/: Moved from 'tparse/'.
* tools/make-release
Omit 'misc' directory from releases, too.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2437 8cb11bc2-c004-0410-86c3-e597b4017df7
2010-09-03 20:49:52 +04:00
|
|
|
if mode.find('b') >= 0:
|
2003-02-09 12:57:46 +03:00
|
|
|
wmode = wmode | os.O_BINARY
|
Wow. Drop a "general code cleanup" kind of bomb on the codebase. All
of this is aimed at not paying the maintenance price of supporting
Python versions prior to 2.4 any longer, plus a little bit of just
getting dead code out of the way.
* lib/compat.py
Remove as unused.
* bin/cvsdbadmin,
* bin/loginfo-handler,
* bin/make-database,
* bin/svndbadmin,
* lib/accept.py,
* lib/blame.py,
* lib/cvsdb.py,
* lib/popen.py,
* lib/query.py,
* lib/sapi.py,
* lib/vcauth/forbidden/__init__.py
* lib/vcauth/forbiddenre/__init__.py,
* lib/vcauth/svnauthz/__init__.py,
* lib/vclib/__init__.py,
* lib/vclib/ccvs/blame.py,
* lib/win32popen.py,
* tests/timelog.py
Replace explicit import and use of the 'string' module with newer constructs.
* bin/standalone.py,
* lib/viewvc.py
No longer use 'compat' module. Replace explicit import and use of
the 'string' module with newer constructs.
* lib/dbi.py
Use calender.timegm() instead of compat.timegm().
* lib/vcauth/__init__.py
Lose unused module imports.
* lib/config.py,
Replace explicit import and use of the 'string' module with newer
constructs where possible. Lose old ConfigParser patch-up code for
Python 1.5.1.
* lib/vclib/ccvs/ccvs.py
Replace explicit import and use of the 'string' module with newer
constructs where possible. Import _path_join() from bincvs, and use
it instead of a bunch of copy-and-pasted string join() statements
throughout.
* lib/vclib/ccvs/__init__.py
(cvs_strptime): Moved here from the 'compat' module.
* lib/vclib/ccvs/bincvs.py
(): No longer use 'compat' module. Replace explicit import and use
of the 'string' module with newer constructs.
(_path_join): New, used now instead of a bunch of copy-and-pasted
string join() statements throughout.
* viewvc-install
Don't use the 'compat' module any more.
Also, so some rearranging of non-critical bits.
* misc/: New directory.
* misc/py2html.py: Moved from 'lib/py2html.py'.
* misc/PyFontify.py: Moved from 'lib/PyFontify.py'.
* misc/elemx/: Moved from 'elemx/'.
* misc/tparse/: Moved from 'tparse/'.
* tools/make-release
Omit 'misc' directory from releases, too.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2437 8cb11bc2-c004-0410-86c3-e597b4017df7
2010-09-03 20:49:52 +04:00
|
|
|
if mode.find('t') >= 0:
|
2003-02-09 12:57:46 +03:00
|
|
|
wmode = wmode | os.O_TEXT
|
|
|
|
return os.fdopen(msvcrt.open_osfhandle(pipe.Detach(),wmode),mode)
|
|
|
|
|
|
|
|
def FileObject2File(fileObject):
|
|
|
|
"""Get the win32 file handle from a C stdio file object"""
|
|
|
|
return win32file._get_osfhandle(fileObject.fileno())
|
|
|
|
|
|
|
|
def DuplicateHandle(handle):
|
|
|
|
"""Duplicates a win32 handle."""
|
|
|
|
proc = win32api.GetCurrentProcess()
|
|
|
|
return win32api.DuplicateHandle(proc,handle,proc,0,0,win32con.DUPLICATE_SAME_ACCESS)
|
|
|
|
|
|
|
|
def MakePrivateHandle(handle, replace = 1):
|
2003-06-10 03:20:00 +04:00
|
|
|
"""Turn an inherited handle into a non inherited one. This avoids the
|
2003-02-09 12:57:46 +03:00
|
|
|
handle duplication that occurs on CreateProcess calls which can create
|
|
|
|
uncloseable pipes."""
|
2003-06-10 03:20:00 +04:00
|
|
|
|
2003-06-02 08:40:44 +04:00
|
|
|
### Could change implementation to use SetHandleInformation()...
|
2003-06-10 03:20:00 +04:00
|
|
|
|
2003-10-14 19:53:42 +04:00
|
|
|
flags = win32con.DUPLICATE_SAME_ACCESS
|
2003-02-09 12:57:46 +03:00
|
|
|
proc = win32api.GetCurrentProcess()
|
2005-08-22 22:41:59 +04:00
|
|
|
if replace: flags = flags | win32con.DUPLICATE_CLOSE_SOURCE
|
2003-02-09 12:57:46 +03:00
|
|
|
newhandle = win32api.DuplicateHandle(proc,handle,proc,0,0,flags)
|
|
|
|
if replace: handle.Detach() # handle was already deleted by the last call
|
|
|
|
return newhandle
|
|
|
|
|
|
|
|
def MakeInheritedHandle(handle, replace = 1):
|
|
|
|
"""Turn a private handle into an inherited one."""
|
2003-06-10 03:20:00 +04:00
|
|
|
|
2003-06-02 08:40:44 +04:00
|
|
|
### Could change implementation to use SetHandleInformation()...
|
2003-06-10 03:20:00 +04:00
|
|
|
|
2003-10-14 19:53:42 +04:00
|
|
|
flags = win32con.DUPLICATE_SAME_ACCESS
|
2003-02-09 12:57:46 +03:00
|
|
|
proc = win32api.GetCurrentProcess()
|
2005-08-22 22:41:59 +04:00
|
|
|
if replace: flags = flags | win32con.DUPLICATE_CLOSE_SOURCE
|
2003-02-09 12:57:46 +03:00
|
|
|
newhandle = win32api.DuplicateHandle(proc,handle,proc,0,1,flags)
|
|
|
|
if replace: handle.Detach() # handle was deleted by the last call
|
|
|
|
return newhandle
|
|
|
|
|
|
|
|
def MakeSpyPipe(readInheritable, writeInheritable, outFiles = None, doneEvent = None):
|
|
|
|
"""Return read and write handles to a pipe that asynchronously writes all of
|
|
|
|
its input to the files in the outFiles sequence. doneEvent can be None, or a
|
|
|
|
a win32 event handle that will be set when the write end of pipe is closed.
|
|
|
|
"""
|
|
|
|
|
|
|
|
if outFiles is None:
|
2003-06-02 08:40:44 +04:00
|
|
|
return CreatePipe(readInheritable, writeInheritable)
|
2003-02-09 12:57:46 +03:00
|
|
|
|
2003-06-02 08:40:44 +04:00
|
|
|
r, writeHandle = CreatePipe(0, writeInheritable)
|
2003-02-09 12:57:46 +03:00
|
|
|
if readInheritable is None:
|
|
|
|
readHandle, w = None, None
|
|
|
|
else:
|
2003-06-02 08:40:44 +04:00
|
|
|
readHandle, w = CreatePipe(readInheritable, 0)
|
2003-06-10 03:20:00 +04:00
|
|
|
|
2003-06-02 08:40:44 +04:00
|
|
|
thread.start_new_thread(SpoolWorker, (r, w, outFiles, doneEvent))
|
2003-02-09 12:57:46 +03:00
|
|
|
|
|
|
|
return readHandle, writeHandle
|
|
|
|
|
|
|
|
def SpoolWorker(srcHandle, destHandle, outFiles, doneEvent):
|
2003-06-02 08:40:44 +04:00
|
|
|
"""Thread entry point for implementation of MakeSpyPipe"""
|
2003-02-09 12:57:46 +03:00
|
|
|
try:
|
|
|
|
buffer = win32file.AllocateReadBuffer(SPOOL_BYTES)
|
2003-06-10 03:20:00 +04:00
|
|
|
|
2003-02-09 12:57:46 +03:00
|
|
|
while 1:
|
|
|
|
try:
|
2003-06-02 08:40:44 +04:00
|
|
|
#print >> SPOOL_ERROR, "Calling ReadFile..."; SPOOL_ERROR.flush()
|
2003-02-09 12:57:46 +03:00
|
|
|
hr, data = win32file.ReadFile(srcHandle, buffer)
|
2003-06-02 08:40:44 +04:00
|
|
|
#print >> SPOOL_ERROR, "ReadFile returned '%s', '%s'" % (str(hr), str(data)); SPOOL_ERROR.flush()
|
2003-02-26 04:39:51 +03:00
|
|
|
if hr != 0:
|
|
|
|
raise "win32file.ReadFile returned %i, '%s'" % (hr, data)
|
|
|
|
elif len(data) == 0:
|
2003-02-09 12:57:46 +03:00
|
|
|
break
|
|
|
|
except pywintypes.error, e:
|
2003-06-02 08:40:44 +04:00
|
|
|
#print >> SPOOL_ERROR, "ReadFile threw '%s'" % str(e); SPOOL_ERROR.flush()
|
2003-06-10 03:20:00 +04:00
|
|
|
if e.args[0] == winerror.ERROR_BROKEN_PIPE:
|
2003-02-09 12:57:46 +03:00
|
|
|
break
|
|
|
|
else:
|
|
|
|
raise e
|
2003-06-02 08:40:44 +04:00
|
|
|
|
|
|
|
#print >> SPOOL_ERROR, "Writing to %i file objects..." % len(outFiles); SPOOL_ERROR.flush()
|
2003-02-09 12:57:46 +03:00
|
|
|
for f in outFiles:
|
|
|
|
f.write(data)
|
2003-06-02 08:40:44 +04:00
|
|
|
#print >> SPOOL_ERROR, "Done writing to file objects."; SPOOL_ERROR.flush()
|
|
|
|
|
|
|
|
#print >> SPOOL_ERROR, "Writing to destination %s" % str(destHandle); SPOOL_ERROR.flush()
|
2003-02-09 12:57:46 +03:00
|
|
|
if destHandle:
|
2003-06-02 08:40:44 +04:00
|
|
|
#print >> SPOOL_ERROR, "Calling WriteFile..."; SPOOL_ERROR.flush()
|
2003-02-09 12:57:46 +03:00
|
|
|
hr, bytes = win32file.WriteFile(destHandle, data)
|
2003-06-02 08:40:44 +04:00
|
|
|
#print >> SPOOL_ERROR, "WriteFile() passed %i bytes and returned %i, %i" % (len(data), hr, bytes); SPOOL_ERROR.flush()
|
2003-02-09 12:57:46 +03:00
|
|
|
if hr != 0 or bytes != len(data):
|
|
|
|
raise "win32file.WriteFile() passed %i bytes and returned %i, %i" % (len(data), hr, bytes)
|
2003-06-10 03:20:00 +04:00
|
|
|
|
2003-02-09 12:57:46 +03:00
|
|
|
srcHandle.Close()
|
2003-06-10 03:20:00 +04:00
|
|
|
|
2003-02-09 12:57:46 +03:00
|
|
|
if doneEvent:
|
|
|
|
win32event.SetEvent(doneEvent)
|
2003-06-10 03:20:00 +04:00
|
|
|
|
2003-02-09 12:57:46 +03:00
|
|
|
if destHandle:
|
2003-06-10 03:20:00 +04:00
|
|
|
destHandle.Close()
|
|
|
|
|
2003-02-09 12:57:46 +03:00
|
|
|
except:
|
|
|
|
info = sys.exc_info()
|
2005-08-22 22:41:59 +04:00
|
|
|
SPOOL_ERROR.writelines(apply(traceback.format_exception, info), '')
|
|
|
|
SPOOL_ERROR.flush()
|
2003-06-10 03:20:00 +04:00
|
|
|
del info
|
|
|
|
|
|
|
|
def NullFile(inheritable):
|
|
|
|
"""Create a null file handle."""
|
|
|
|
if inheritable:
|
|
|
|
sa = pywintypes.SECURITY_ATTRIBUTES()
|
|
|
|
sa.bInheritHandle = 1
|
|
|
|
else:
|
|
|
|
sa = None
|
|
|
|
|
|
|
|
return win32file.CreateFile("nul",
|
|
|
|
win32file.GENERIC_READ | win32file.GENERIC_WRITE,
|
|
|
|
win32file.FILE_SHARE_READ | win32file.FILE_SHARE_WRITE,
|
|
|
|
sa, win32file.OPEN_EXISTING, 0, None)
|