Index: Doc/library/subprocess.rst =================================================================== --- Doc/library/subprocess.rst (revision 77912) +++ Doc/library/subprocess.rst (working copy) @@ -362,6 +362,86 @@ ``N`` (Unix only). +Windows Specific +---------------------------------------------------- + +On Windows, a number of lower level functions are exposed by the subproces +module. + +.. function:: GetStdHandle(handle) + + Retrieve a handle to the specified standard device (:data:`STD_INPUT_HANDLE`, + :data:`STD_OUTPUT_HANDLE`, :data:`STD_ERROR_HANDLE`). The integer + associated with the handle object is returned. + +.. function:: GetCurrentProcess() + + Retrieve a handle object for the current process. + +.. function:: DuplicateHandle(source_proc_handle, source_handle, target_proc_handle, target_handle, access, inherit[, options]) + + Return a duplicate handle object. + + The duplicate handle refers to the same object as the original handle. + Therefore, any changes to the object are reflected through both handles. + +.. function:: CreatePipe(pipe_attrs, size) + + Create an anonymous pipe, and return handles to the read and write ends + of the pipe as a tuple. The *size* of the buffer for the pipe is to be + specified in bytes. If this parameter is zero, the system uses the + default buffer size. + + *pipe_attrs* is ignored internally and can be None. + +.. function:: CreateProcess(app_name, cmd_line, proc_attrs, thread_attrs, inherit, flags, env_mapping, curdir, startup_info) + + Create a new process and its primary thread. Returns a tuple of the process + handle, the primary thread handle, process ID, and primary thread ID. + + *proc_attrs* and *thread_attrs* are ignored internally and can be None. + +.. function:: TerminateProcess(handle, exit_code) + + Terminate the process specifid by *handle* along with all of its threads. + + *exit_code* will be populated with the process' exit code. + +.. function:: GetExitCodeProcess(handle) + + Return the termination status of the specified process. + +.. function:: WaitForSingleObject(handle, timeout) + + Wait until the specified object is in the signaled state or the *timeout* + interval elapses. The *timeout* value is specified in milliseconds. + +.. function:: GetVersion() + + Return the version number of the current operating system. + +.. function:: GetModuleFileName(module) + + Return the fully-qualified path for the file that contains the specified + *module*. The module must have been loaded by the current process. + + The *module* parameter should be a handle to the loaded module whose path + is being requested. If this parameter is 0, :func:`GetModuleFileName` + retrieves the path of the executable file of the current process. + +.. data:: STD_INPUT_HANDLE + + The standard input device. + +.. data:: STD_OUTPUT_HANDLE + + The standard input device. + +.. data:: STD_ERROR_HANDLE + + The standard input device. + + .. _subprocess-replacements: Replacing Older Functions with the subprocess Module Index: Lib/subprocess.py =================================================================== --- Lib/subprocess.py (revision 77912) +++ Lib/subprocess.py (working copy) @@ -415,29 +415,15 @@ if mswindows: import threading import msvcrt - if 0: # <-- change this to use pywin32 instead of the _subprocess driver - import pywintypes - from win32api import GetStdHandle, STD_INPUT_HANDLE, \ - STD_OUTPUT_HANDLE, STD_ERROR_HANDLE - from win32api import GetCurrentProcess, DuplicateHandle, \ - GetModuleFileName, GetVersion - from win32con import DUPLICATE_SAME_ACCESS, SW_HIDE - from win32pipe import CreatePipe - from win32process import CreateProcess, STARTUPINFO, \ - GetExitCodeProcess, STARTF_USESTDHANDLES, \ - STARTF_USESHOWWINDOW, CREATE_NEW_CONSOLE - from win32process import TerminateProcess - from win32event import WaitForSingleObject, INFINITE, WAIT_OBJECT_0 - else: - from _subprocess import * - class STARTUPINFO: - dwFlags = 0 - hStdInput = None - hStdOutput = None - hStdError = None - wShowWindow = 0 - class pywintypes: - error = IOError + from _subprocess import * + class STARTUPINFO: + dwFlags = 0 + hStdInput = None + hStdOutput = None + hStdError = None + wShowWindow = 0 + class pywintypes: + error = IOError else: import select _has_poll = hasattr(select, 'poll') Index: PC/_subprocess.c =================================================================== --- PC/_subprocess.c (revision 77912) +++ PC/_subprocess.c (working copy) @@ -154,6 +154,13 @@ /* -------------------------------------------------------------------- */ /* windows API functions */ +PyDoc_STRVAR(GetStdHandle_doc, +"GetStdHandle(handle) -> integer\n\ +\n\ +Return a handle to the specified standard device\n\ +(STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, STD_ERROR_HANDLE).\n\ +The integer associatedwith the handle object is returned."); + static PyObject * sp_GetStdHandle(PyObject* self, PyObject* args) { @@ -179,6 +186,11 @@ return HANDLE_TO_PYNUM(handle); } +PyDoc_STRVAR(GetCurrentProcess_doc, +"GetCurrentProcess() -> handle\n\ +\n\ +Return a handle object for the current process."); + static PyObject * sp_GetCurrentProcess(PyObject* self, PyObject* args) { @@ -188,6 +200,17 @@ return sp_handle_new(GetCurrentProcess()); } +PyDoc_STRVAR(DuplicateHandle_doc, +"DuplicateHandle(source_proc_handle, source_handle,\n\ + target_proc_handle, target_handle, access,\n\ + inherit[, options]) -> handle\n\ +\n\ +Return a duplicate a handle object.\n\ +\n\ +The duplicate handle refers to the same object as the original\n\ +handle. Therefore, any changes to the object are reflected\n\ +through both handles."); + static PyObject * sp_DuplicateHandle(PyObject* self, PyObject* args) { @@ -230,6 +253,14 @@ return sp_handle_new(target_handle); } +PyDoc_STRVAR(CreatePipe_doc, +"CreatePipe(pipe_attrs, size) -> (read_handle, write_handle)\n\ +\n\ +Create an anonymous pipe, and return handles to the read and\n\ +write ends of the pipe.\n\ +\n\ +pipe_attrs is ignored internally and can be None."); + static PyObject * sp_CreatePipe(PyObject* self, PyObject* args) { @@ -365,6 +396,18 @@ return NULL; } +PyDoc_STRVAR(CreateProcess_doc, +"CreateProcess(app_name, cmd_line, proc_attrs, thread_attrs,\n\ + inherit, flags, env_mapping, curdir,\n\ + startup_info) -> (proc_handle, thread_handle,\n\ + pid, tid)\n\ +\n\ +Create a new process and its primary thread. The return\n\ +value is tuple of the process handle, thread handle,\n\ +process ID, and thread ID.\n\ +\n\ +proc_attrs and thread_attrs are ignored internally and can be None."); + static PyObject * sp_CreateProcess(PyObject* self, PyObject* args) { @@ -441,6 +484,11 @@ pi.dwThreadId); } +PyDoc_STRVAR(TerminateProcess_doc, +"TerminateProcess(handle, exit_code) -> None\n\ +\n\ +Terminate the specified process and all of its threads."); + static PyObject * sp_TerminateProcess(PyObject* self, PyObject* args) { @@ -461,6 +509,11 @@ return Py_None; } +PyDoc_STRVAR(GetExitCodeProcess_doc, +"GetExitCodeProcess(handle) -> Exit code\n\ +\n\ +Return the termination status of the specified process."); + static PyObject * sp_GetExitCodeProcess(PyObject* self, PyObject* args) { @@ -479,6 +532,13 @@ return PyInt_FromLong(exit_code); } +PyDoc_STRVAR(WaitForSingleObject_doc, +"WaitForSingleObject(handle, timeout) -> result\n\ +\n\ +Wait until the specified object is in the signaled state or\n\ +the time-out interval elapses. The timeout value is specified\n\ +in milliseconds."); + static PyObject * sp_WaitForSingleObject(PyObject* self, PyObject* args) { @@ -501,6 +561,11 @@ return PyInt_FromLong((int) result); } +PyDoc_STRVAR(GetVersion_doc, +"GetVersion() -> version\n\ +\n\ +Return the version number of the current operating system."); + static PyObject * sp_GetVersion(PyObject* self, PyObject* args) { @@ -510,6 +575,18 @@ return PyInt_FromLong((int) GetVersion()); } +PyDoc_STRVAR(GetModuleFileName_doc, +"GetModuleFileName(module) -> path\n\ +\n\ +Return the fully-qualified path for the file that contains\n\ +the specified module. The module must have been loaded by the\n\ +current process.\n\ +\n\ +The module parameter should be a handle to the loaded module\n\ +whose path is being requested. If this parameter is 0, \n\ +GetModuleFileName retrieves the path of the executable file\n\ +of the current process."); + static PyObject * sp_GetModuleFileName(PyObject* self, PyObject* args) { @@ -531,16 +608,22 @@ } static PyMethodDef sp_functions[] = { - {"GetStdHandle", sp_GetStdHandle, METH_VARARGS}, - {"GetCurrentProcess", sp_GetCurrentProcess, METH_VARARGS}, - {"DuplicateHandle", sp_DuplicateHandle, METH_VARARGS}, - {"CreatePipe", sp_CreatePipe, METH_VARARGS}, - {"CreateProcess", sp_CreateProcess, METH_VARARGS}, - {"TerminateProcess", sp_TerminateProcess, METH_VARARGS}, - {"GetExitCodeProcess", sp_GetExitCodeProcess, METH_VARARGS}, - {"WaitForSingleObject", sp_WaitForSingleObject, METH_VARARGS}, - {"GetVersion", sp_GetVersion, METH_VARARGS}, - {"GetModuleFileName", sp_GetModuleFileName, METH_VARARGS}, + {"GetStdHandle", sp_GetStdHandle, METH_VARARGS, GetStdHandle_doc}, + {"GetCurrentProcess", sp_GetCurrentProcess, METH_VARARGS, + GetCurrentProcess_doc}, + {"DuplicateHandle", sp_DuplicateHandle, METH_VARARGS, + DuplicateHandle_doc}, + {"CreatePipe", sp_CreatePipe, METH_VARARGS, CreatePipe_doc}, + {"CreateProcess", sp_CreateProcess, METH_VARARGS, CreateProcess_doc}, + {"TerminateProcess", sp_TerminateProcess, METH_VARARGS, + TerminateProcess_doc}, + {"GetExitCodeProcess", sp_GetExitCodeProcess, METH_VARARGS, + GetExitCodeProcess_doc}, + {"WaitForSingleObject", sp_WaitForSingleObject, METH_VARARGS, + WaitForSingleObject_doc}, + {"GetVersion", sp_GetVersion, METH_VARARGS, GetVersion_doc}, + {"GetModuleFileName", sp_GetModuleFileName, METH_VARARGS, + GetModuleFileName_doc}, {NULL, NULL} };