]> granicus.if.org Git - python/commitdiff
Implement os.waitpid() for Windows, in a way that's compatible with Linux
authorTim Peters <tim.peters@gmail.com>
Fri, 1 Feb 2002 11:27:43 +0000 (11:27 +0000)
committerTim Peters <tim.peters@gmail.com>
Fri, 1 Feb 2002 11:27:43 +0000 (11:27 +0000)
where their capabilities intersect.  Would be nice if people using non-
MSVC compilers (Borland etc) took a whack at doing something similar for
them (this code relies on the MS _cwait function).

Doc/lib/libos.tex
Misc/NEWS
Modules/posixmodule.c

index 51f00273eff037d3178873193801fdbcab735652..57394855afe1e37061ec310afc09878c6b6dcc29 100644 (file)
@@ -96,7 +96,7 @@ environment.  \function{putenv()} will be called automatically when
 the mapping is modified.
 
 If \function{putenv()} is not provided, this mapping may be passed to
-the appropriate process-creation functions to cause child processes to 
+the appropriate process-creation functions to cause child processes to
 use a modified environment.
 \end{datadesc}
 
@@ -184,7 +184,7 @@ When \function{putenv()} is
 supported, assignments to items in \code{os.environ} are automatically
 translated into corresponding calls to \function{putenv()}; however,
 calls to \function{putenv()} don't update \code{os.environ}, so it is
-actually preferable to assign to items of \code{os.environ}.  
+actually preferable to assign to items of \code{os.environ}.
 \end{funcdesc}
 
 \begin{funcdesc}{setegid}{egid}
@@ -413,7 +413,7 @@ Availability: \UNIX.
 \end{funcdesc}
 
 \begin{funcdesc}{ftruncate}{fd, length}
-Truncate the file corresponding to file descriptor \var{fd}, 
+Truncate the file corresponding to file descriptor \var{fd},
 so that it is at most \var{length} bytes in size.
 Availability: \UNIX.
 \end{funcdesc}
@@ -909,7 +909,7 @@ will seem to be ignored.
 
 \begin{funcdesc}{abort}{}
 Generate a \constant{SIGABRT} signal to the current process.  On
-\UNIX, the default behavior is to produce a core dump; on Windows, the 
+\UNIX, the default behavior is to produce a core dump; on Windows, the
 process immediately returns an exit code of \code{3}.  Be aware that
 programs which use \function{signal.signal()} to register a handler
 for \constant{SIGABRT} will behave differently.
@@ -1166,12 +1166,14 @@ Availability: \UNIX.
 \end{funcdesc}
 
 \begin{funcdesc}{waitpid}{pid, options}
+The details of this function differ on \UNIX and Windows.
+
+On \UNIX:
 Wait for completion of a child process given by process id \var{pid},
 and return a tuple containing its process id and exit status
 indication (encoded as for \function{wait()}).  The semantics of the
 call are affected by the value of the integer \var{options}, which
 should be \code{0} for normal operation.
-Availability: \UNIX.
 
 If \var{pid} is greater than \code{0}, \function{waitpid()} requests
 status information for that specific process.  If \var{pid} is
@@ -1180,6 +1182,19 @@ group of the current process.  If \var{pid} is \code{-1}, the request
 pertains to any child of the current process.  If \var{pid} is less
 than \code{-1}, status is requested for any process in the process
 group \code{-\var{pid}} (the absolute value of \var{pid}).
+
+On Windows:
+Wait for completion of a process given by process id \var{pid},
+and return a tuple containing \var{pid},
+and its exit status shifted left by 8 bits (shifting makes cross-platform
+use of the function easier).
+A \var{pid} less than or equal to \code{0} has no special meaning on
+Windows, and raises an exception.
+The value of integer \var{options} has no effect.
+\var{pid} can refer to any process whose id is known, not necessarily a
+child process.
+The \function{spawn()} functions called with \constant{P_NOWAIT}
+return suitable process ids.
 \end{funcdesc}
 
 \begin{datadesc}{WNOHANG}
@@ -1211,7 +1226,7 @@ Availability: \UNIX.
 
 \begin{funcdesc}{WEXITSTATUS}{status}
 If \code{WIFEXITED(\var{status})} is true, return the integer
-parameter to the \manpage{exit}{2} system call.  Otherwise, the return 
+parameter to the \manpage{exit}{2} system call.  Otherwise, the return
 value is meaningless.
 Availability: \UNIX.
 \end{funcdesc}
index ee9df99f31243a3b48b69e9ac59f2b756e59be1a..c1510679704a4db5ea8254208edf042ba6ab72f2 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -59,6 +59,13 @@ Tests
 
 Windows
 
+- os.waitpid() is now implemented for Windows, and can be used to block
+  until a specified process exits.  This is similar to, but not exactly
+  the same as, os.waitpid() on POSIX systems.  If you're waiting for
+  a specific process whose pid was obtained from one of the spawn()
+  functions, the same Python os.waitpid() code works across platforms.
+  See the docs for details.
+
 - New tempfile.TemporaryFile implementation for Windows:  this doesn't
   need a TemproraryFileWrapper wrapper anymore, and should be immune
   to a nasty problem:  before 2.3, if you got a temp file on Windows, it
index 77b0d66c09b963f1486c7078ae479d47d3e4f7b2..40cf5a70e0b7b305cc2dcd2265bb8f66419a0e22 100644 (file)
@@ -78,6 +78,7 @@ corresponding Unix manual entries for more information on calls.";
 #define HAVE_PIPE       1
 #define HAVE_POPEN      1
 #define HAVE_SYSTEM    1
+#define HAVE_CWAIT     1
 #else /* 16-bit Windows */
 #endif /* !MS_WIN32 */
 #else                  /* all other compilers */
@@ -3333,8 +3334,33 @@ posix_waitpid(PyObject *self, PyObject *args)
        else
                return Py_BuildValue("ii", pid, status_i);
 }
-#endif /* HAVE_WAITPID */
 
+#elif defined(HAVE_CWAIT)
+
+/* MS C has a variant of waitpid() that's usable for most purposes. */
+static char posix_waitpid__doc__[] =
+"waitpid(pid, options) -> (pid, status << 8)\n"
+"Wait for completion of a given process.  options is ignored on Windows.";
+
+static PyObject *
+posix_waitpid(PyObject *self, PyObject *args)
+{
+       int pid, options;
+       int status;
+
+       if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
+               return NULL;
+       Py_BEGIN_ALLOW_THREADS
+       pid = _cwait(&status, pid, options);
+       Py_END_ALLOW_THREADS
+       if (pid == -1)
+               return posix_error();
+       else
+               /* shift the status left a byte so this is more like the
+                  POSIX waitpid */
+               return Py_BuildValue("ii", pid, status << 8);
+}
+#endif /* HAVE_WAITPID || HAVE_CWAIT */
 
 #ifdef HAVE_WAIT
 static char posix_wait__doc__[] =
@@ -5678,7 +5704,7 @@ static PyMethodDef posix_methods[] = {
 #ifdef HAVE_WAIT
        {"wait",        posix_wait, METH_VARARGS, posix_wait__doc__},
 #endif /* HAVE_WAIT */
-#ifdef HAVE_WAITPID
+#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
        {"waitpid",     posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
 #endif /* HAVE_WAITPID */
 #ifdef HAVE_SETSID