#6394: Add os.getppid() support for Windows.

This commit is contained in:
Amaury Forgeot d'Arc 2010-09-07 21:31:17 +00:00
parent 8bc09039ed
commit 4b6fdf3852
6 changed files with 80 additions and 4 deletions

View File

@ -281,10 +281,14 @@ process and user.
.. index:: single: process; id of parent
Return the parent's process id.
Return the parent's process id. When the parent process has exited, on Unix
the id returned is the one of the init process (1), on Windows it is still
the same id, which may be already reused by another process.
Availability: Unix.
Availability: Unix, Windows
.. versionchanged:: 3.2
Added support for Windows.
.. function:: getresuid()

View File

@ -312,6 +312,11 @@ New, Improved, and Deprecated Modules
(Patch by Adam Jackson; :issue:`7647`.)
* :func:`os.getppid` is now supported on Windows. Note that it will continue to
return the same pid even after the parent process has exited.
(Patch by Jon Anglin; :issue:`6394`.)
* The :func:`shutil.copytree` function has two new options:
* *ignore_dangling_symlinks*: when ``symlinks=False`` so that the function

View File

@ -1183,6 +1183,17 @@ class FSEncodingTests(unittest.TestCase):
check('iso-8859-15', b'\xef\xa4', '\xef\u20ac')
class PidTests(unittest.TestCase):
@unittest.skipUnless(hasattr(os, 'getppid'), "test needs os.getppid")
def test_getppid(self):
p = subprocess.Popen([sys.executable, '-c',
'import os; print(os.getppid())'],
stdout=subprocess.PIPE)
stdout, _ = p.communicate()
# We are the parent of our subprocess
self.assertEqual(int(stdout), os.getpid())
def test_main():
support.run_unittest(
FileTests,
@ -1200,6 +1211,7 @@ def test_main():
Win32KillTests,
Win32SymlinkTests,
FSEncodingTests,
PidTests,
)
if __name__ == "__main__":

View File

@ -28,6 +28,7 @@ John Anderson
Erik Andersén
Oliver Andrich
Ross Andrus
Jon Anglin
Éric Araujo
Jason Asbahr
David Ascher

View File

@ -13,6 +13,10 @@ Core and Builtins
Library
-------
- Issue #6394: os.getppid() is now supported on Windows. Note that it will
still return the id of the parent process after it has exited. This process
id may even have been reused by another unrelated process.
- Issue #9792: In case of connection failure, socket.create_connection()
would swallow the exception and raise a new one, making it impossible
to fetch the original errno, or to filter timeout errors. Now the

View File

@ -121,6 +121,7 @@ corresponding Unix manual entries for more information on calls.");
#else
#ifdef _MSC_VER /* Microsoft compiler */
#define HAVE_GETCWD 1
#define HAVE_GETPPID 1
#define HAVE_SPAWNV 1
#define HAVE_EXECV 1
#define HAVE_PIPE 1
@ -4363,16 +4364,65 @@ posix_setpgrp(PyObject *self, PyObject *noargs)
#endif /* HAVE_SETPGRP */
#ifdef HAVE_GETPPID
#ifdef MS_WINDOWS
#include <tlhelp32.h>
static PyObject*
win32_getppid()
{
HANDLE snapshot;
pid_t mypid;
PyObject* result = NULL;
BOOL have_record;
PROCESSENTRY32 pe;
mypid = getpid(); /* This function never fails */
snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (snapshot == INVALID_HANDLE_VALUE)
return PyErr_SetFromWindowsErr(GetLastError());
pe.dwSize = sizeof(pe);
have_record = Process32First(snapshot, &pe);
while (have_record) {
if (mypid == (pid_t)pe.th32ProcessID) {
/* We could cache the ulong value in a static variable. */
result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
break;
}
have_record = Process32Next(snapshot, &pe);
}
/* If our loop exits and our pid was not found (result will be NULL)
* then GetLastError will return ERROR_NO_MORE_FILES. This is an
* error anyway, so let's raise it. */
if (!result)
result = PyErr_SetFromWindowsErr(GetLastError());
CloseHandle(snapshot);
return result;
}
#endif /*MS_WINDOWS*/
PyDoc_STRVAR(posix_getppid__doc__,
"getppid() -> ppid\n\n\
Return the parent's process id.");
Return the parent's process id. If the parent process has already exited,\n\
Windows machines will still return its id; others systems will return the id\n\
of the 'init' process (1).");
static PyObject *
posix_getppid(PyObject *self, PyObject *noargs)
{
#ifdef MS_WINDOWS
return win32_getppid();
#else
return PyLong_FromPid(getppid());
}
#endif
}
#endif /* HAVE_GETPPID */
#ifdef HAVE_GETLOGIN