Commit f2d7ac7e authored by pxinwr's avatar pxinwr Committed by Victor Stinner

bpo-31904: Add posix module support for VxWorks (GH-12118)

parent d12e7573
...@@ -32,6 +32,7 @@ Notes on the availability of these functions: ...@@ -32,6 +32,7 @@ Notes on the availability of these functions:
objects, and result in an object of the same type, if a path or file name is objects, and result in an object of the same type, if a path or file name is
returned. returned.
* On VxWorks, os.fork, os.execv and os.spawn*p* are not supported.
.. note:: .. note::
...@@ -3578,6 +3579,9 @@ written in Python, such as a mail server's external command delivery program. ...@@ -3578,6 +3579,9 @@ written in Python, such as a mail server's external command delivery program.
process. On Windows, the process id will actually be the process handle, so can process. On Windows, the process id will actually be the process handle, so can
be used with the :func:`waitpid` function. be used with the :func:`waitpid` function.
Note on VxWorks, this function doesn't return ``-signal`` when the new process is
killed. Instead it raises OSError exception.
The "l" and "v" variants of the :func:`spawn\* <spawnl>` functions differ in how The "l" and "v" variants of the :func:`spawn\* <spawnl>` functions differ in how
command-line arguments are passed. The "l" variants are perhaps the easiest command-line arguments are passed. The "l" variants are perhaps the easiest
to work with if the number of parameters is fixed when the code is written; the to work with if the number of parameters is fixed when the code is written; the
......
...@@ -1407,6 +1407,8 @@ OS_URANDOM_DONT_USE_FD = ( ...@@ -1407,6 +1407,8 @@ OS_URANDOM_DONT_USE_FD = (
@unittest.skipIf(OS_URANDOM_DONT_USE_FD , @unittest.skipIf(OS_URANDOM_DONT_USE_FD ,
"os.random() does not use a file descriptor") "os.random() does not use a file descriptor")
@unittest.skipIf(sys.platform == "vxworks",
"VxWorks can't set RLIMIT_NOFILE to 1")
class URandomFDTests(unittest.TestCase): class URandomFDTests(unittest.TestCase):
@unittest.skipUnless(resource, "test requires the resource module") @unittest.skipUnless(resource, "test requires the resource module")
def test_urandom_failure(self): def test_urandom_failure(self):
...@@ -1517,7 +1519,8 @@ def _execvpe_mockup(defpath=None): ...@@ -1517,7 +1519,8 @@ def _execvpe_mockup(defpath=None):
os.execve = orig_execve os.execve = orig_execve
os.defpath = orig_defpath os.defpath = orig_defpath
@unittest.skipUnless(hasattr(os, 'execv'),
"need os.execv()")
class ExecTests(unittest.TestCase): class ExecTests(unittest.TestCase):
@unittest.skipIf(USING_LINUXTHREADS, @unittest.skipIf(USING_LINUXTHREADS,
"avoid triggering a linuxthreads bug: see issue #4970") "avoid triggering a linuxthreads bug: see issue #4970")
......
...@@ -2491,7 +2491,7 @@ exit: ...@@ -2491,7 +2491,7 @@ exit:
#endif /* defined(HAVE_POSIX_SPAWNP) */ #endif /* defined(HAVE_POSIX_SPAWNP) */
#if (defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)) #if (defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) || defined(HAVE_RTPSPAWN))
PyDoc_STRVAR(os_spawnv__doc__, PyDoc_STRVAR(os_spawnv__doc__,
"spawnv($module, mode, path, argv, /)\n" "spawnv($module, mode, path, argv, /)\n"
...@@ -2545,9 +2545,9 @@ exit: ...@@ -2545,9 +2545,9 @@ exit:
return return_value; return return_value;
} }
#endif /* (defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)) */ #endif /* (defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) || defined(HAVE_RTPSPAWN)) */
#if (defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)) #if (defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) || defined(HAVE_RTPSPAWN))
PyDoc_STRVAR(os_spawnve__doc__, PyDoc_STRVAR(os_spawnve__doc__,
"spawnve($module, mode, path, argv, env, /)\n" "spawnve($module, mode, path, argv, env, /)\n"
...@@ -2606,7 +2606,7 @@ exit: ...@@ -2606,7 +2606,7 @@ exit:
return return_value; return return_value;
} }
#endif /* (defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)) */ #endif /* (defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) || defined(HAVE_RTPSPAWN)) */
#if defined(HAVE_FORK) #if defined(HAVE_FORK)
...@@ -8576,4 +8576,4 @@ exit: ...@@ -8576,4 +8576,4 @@ exit:
#ifndef OS__REMOVE_DLL_DIRECTORY_METHODDEF #ifndef OS__REMOVE_DLL_DIRECTORY_METHODDEF
#define OS__REMOVE_DLL_DIRECTORY_METHODDEF #define OS__REMOVE_DLL_DIRECTORY_METHODDEF
#endif /* !defined(OS__REMOVE_DLL_DIRECTORY_METHODDEF) */ #endif /* !defined(OS__REMOVE_DLL_DIRECTORY_METHODDEF) */
/*[clinic end generated code: output=ab36ec0376a422ae input=a9049054013a1b77]*/ /*[clinic end generated code: output=5ee9420fb2e7aa2c input=a9049054013a1b77]*/
...@@ -191,11 +191,13 @@ corresponding Unix manual entries for more information on calls."); ...@@ -191,11 +191,13 @@ corresponding Unix manual entries for more information on calls.");
#define fsync _commit #define fsync _commit
#else #else
/* Unix functions that the configure script doesn't check for */ /* Unix functions that the configure script doesn't check for */
#ifndef __VXWORKS__
#define HAVE_EXECV 1 #define HAVE_EXECV 1
#define HAVE_FORK 1 #define HAVE_FORK 1
#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */ #if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
#define HAVE_FORK1 1 #define HAVE_FORK1 1
#endif #endif
#endif
#define HAVE_GETEGID 1 #define HAVE_GETEGID 1
#define HAVE_GETEUID 1 #define HAVE_GETEUID 1
#define HAVE_GETGID 1 #define HAVE_GETGID 1
...@@ -227,6 +229,18 @@ extern char *ctermid_r(char *); ...@@ -227,6 +229,18 @@ extern char *ctermid_r(char *);
#endif /* !_MSC_VER */ #endif /* !_MSC_VER */
#if defined(__VXWORKS__)
#include <vxCpuLib.h>
#include <rtpLib.h>
#include <wait.h>
#include <taskLib.h>
#ifndef _P_WAIT
#define _P_WAIT 0
#define _P_NOWAIT 1
#define _P_NOWAITO 1
#endif
#endif /* __VXWORKS__ */
#ifdef HAVE_POSIX_SPAWN #ifdef HAVE_POSIX_SPAWN
#include <spawn.h> #include <spawn.h>
#endif #endif
...@@ -1353,7 +1367,7 @@ win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag) ...@@ -1353,7 +1367,7 @@ win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
*/ */
#include <crt_externs.h> #include <crt_externs.h>
static char **environ; static char **environ;
#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) ) #elif !defined(_MSC_VER) && (!defined(__WATCOMC__) || defined(__QNX__) || defined(__VXWORKS__))
extern char **environ; extern char **environ;
#endif /* !_MSC_VER */ #endif /* !_MSC_VER */
...@@ -4870,7 +4884,7 @@ os__exit_impl(PyObject *module, int status) ...@@ -4870,7 +4884,7 @@ os__exit_impl(PyObject *module, int status)
#define EXECV_CHAR char #define EXECV_CHAR char
#endif #endif
#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV) #if defined(HAVE_EXECV) || defined(HAVE_SPAWNV) || defined(HAVE_RTPSPAWN)
static void static void
free_string_array(EXECV_CHAR **array, Py_ssize_t count) free_string_array(EXECV_CHAR **array, Py_ssize_t count)
{ {
...@@ -4908,7 +4922,7 @@ fsconvert_strdup(PyObject *o, EXECV_CHAR **out) ...@@ -4908,7 +4922,7 @@ fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
} }
#endif #endif
#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE) #if defined(HAVE_EXECV) || defined (HAVE_FEXECVE) || defined(HAVE_RTPSPAWN)
static EXECV_CHAR** static EXECV_CHAR**
parse_envlist(PyObject* env, Py_ssize_t *envc_ptr) parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
{ {
...@@ -5632,8 +5646,41 @@ os_posix_spawnp_impl(PyObject *module, path_t *path, PyObject *argv, ...@@ -5632,8 +5646,41 @@ os_posix_spawnp_impl(PyObject *module, path_t *path, PyObject *argv,
} }
#endif /* HAVE_POSIX_SPAWNP */ #endif /* HAVE_POSIX_SPAWNP */
#ifdef HAVE_RTPSPAWN
#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) static intptr_t
_rtp_spawn(int mode, const char *rtpFileName, const char *argv[],
const char *envp[])
{
RTP_ID rtpid;
int status;
pid_t res;
int async_err = 0;
/* Set priority=100 and uStackSize=16 MiB (0x1000000) for new processes.
uStackSize=0 cannot be used, the default stack size is too small for
Python. */
if (envp) {
rtpid = rtpSpawn(rtpFileName, argv, envp,
100, 0x1000000, 0, VX_FP_TASK);
}
else {
rtpid = rtpSpawn(rtpFileName, argv, (const char **)environ,
100, 0x1000000, 0, VX_FP_TASK);
}
if ((rtpid != RTP_ID_ERROR) && (mode == _P_WAIT)) {
do {
res = waitpid((pid_t)rtpid, &status, 0);
} while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
if (res < 0)
return RTP_ID_ERROR;
return ((intptr_t)status);
}
return ((intptr_t)rtpid);
}
#endif
#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) || defined(HAVE_RTPSPAWN)
/*[clinic input] /*[clinic input]
os.spawnv os.spawnv
...@@ -5703,13 +5750,17 @@ os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv) ...@@ -5703,13 +5750,17 @@ os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
} }
argvlist[argc] = NULL; argvlist[argc] = NULL;
#if !defined(HAVE_RTPSPAWN)
if (mode == _OLD_P_OVERLAY) if (mode == _OLD_P_OVERLAY)
mode = _P_OVERLAY; mode = _P_OVERLAY;
#endif
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
_Py_BEGIN_SUPPRESS_IPH _Py_BEGIN_SUPPRESS_IPH
#ifdef HAVE_WSPAWNV #ifdef HAVE_WSPAWNV
spawnval = _wspawnv(mode, path->wide, argvlist); spawnval = _wspawnv(mode, path->wide, argvlist);
#elif defined(HAVE_RTPSPAWN)
spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist, NULL);
#else #else
spawnval = _spawnv(mode, path->narrow, argvlist); spawnval = _spawnv(mode, path->narrow, argvlist);
#endif #endif
...@@ -5808,13 +5859,18 @@ os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv, ...@@ -5808,13 +5859,18 @@ os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
if (envlist == NULL) if (envlist == NULL)
goto fail_1; goto fail_1;
#if !defined(HAVE_RTPSPAWN)
if (mode == _OLD_P_OVERLAY) if (mode == _OLD_P_OVERLAY)
mode = _P_OVERLAY; mode = _P_OVERLAY;
#endif
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
_Py_BEGIN_SUPPRESS_IPH _Py_BEGIN_SUPPRESS_IPH
#ifdef HAVE_WSPAWNV #ifdef HAVE_WSPAWNV
spawnval = _wspawnve(mode, path->wide, argvlist, envlist); spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
#elif defined(HAVE_RTPSPAWN)
spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist,
(const char **)envlist);
#else #else
spawnval = _spawnve(mode, path->narrow, argvlist, envlist); spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
#endif #endif
...@@ -13844,11 +13900,13 @@ all_ins(PyObject *m) ...@@ -13844,11 +13900,13 @@ all_ins(PyObject *m)
if (PyModule_AddIntConstant(m, "POSIX_SPAWN_DUP2", POSIX_SPAWN_DUP2)) return -1; if (PyModule_AddIntConstant(m, "POSIX_SPAWN_DUP2", POSIX_SPAWN_DUP2)) return -1;
#endif #endif
#ifdef HAVE_SPAWNV #if defined(HAVE_SPAWNV) || defined (HAVE_RTPSPAWN)
if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1; if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1; if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1; if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
#endif
#ifdef HAVE_SPAWNV
if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1; if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
#endif #endif
......
...@@ -11484,7 +11484,7 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ ...@@ -11484,7 +11484,7 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
sigtimedwait sigwait sigwaitinfo snprintf strftime strlcpy strsignal symlinkat sync \ sigtimedwait sigwait sigwaitinfo snprintf strftime strlcpy strsignal symlinkat sync \
sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \
truncate uname unlinkat unsetenv utimensat utimes waitid waitpid wait3 wait4 \ truncate uname unlinkat unsetenv utimensat utimes waitid waitpid wait3 wait4 \
wcscoll wcsftime wcsxfrm wmemcmp writev _getpty wcscoll wcsftime wcsxfrm wmemcmp writev _getpty rtpSpawn
do : do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
......
...@@ -3541,7 +3541,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ ...@@ -3541,7 +3541,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
sigtimedwait sigwait sigwaitinfo snprintf strftime strlcpy strsignal symlinkat sync \ sigtimedwait sigwait sigwaitinfo snprintf strftime strlcpy strsignal symlinkat sync \
sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \
truncate uname unlinkat unsetenv utimensat utimes waitid waitpid wait3 wait4 \ truncate uname unlinkat unsetenv utimensat utimes waitid waitpid wait3 wait4 \
wcscoll wcsftime wcsxfrm wmemcmp writev _getpty) wcscoll wcsftime wcsxfrm wmemcmp writev _getpty rtpSpawn)
# Force lchmod off for Linux. Linux disallows changing the mode of symbolic # Force lchmod off for Linux. Linux disallows changing the mode of symbolic
# links. Some libc implementations have a stub lchmod implementation that always # links. Some libc implementations have a stub lchmod implementation that always
......
...@@ -835,6 +835,9 @@ ...@@ -835,6 +835,9 @@
/* Define to 1 if you have the `round' function. */ /* Define to 1 if you have the `round' function. */
#undef HAVE_ROUND #undef HAVE_ROUND
/* Define to 1 if you have the `rtpSpawn' function. */
#undef HAVE_RTPSPAWN
/* Define to 1 if you have the `sched_get_priority_max' function. */ /* Define to 1 if you have the `sched_get_priority_max' function. */
#undef HAVE_SCHED_GET_PRIORITY_MAX #undef HAVE_SCHED_GET_PRIORITY_MAX
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment