Skip to content

Commit f2d7ac7

Browse files
pxinwrvstinner
authored andcommitted
bpo-31904: Add posix module support for VxWorks (GH-12118)
1 parent d12e757 commit f2d7ac7

File tree

8 files changed

+84
-15
lines changed

8 files changed

+84
-15
lines changed

Doc/library/os.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ Notes on the availability of these functions:
3232
objects, and result in an object of the same type, if a path or file name is
3333
returned.
3434

35+
* On VxWorks, os.fork, os.execv and os.spawn*p* are not supported.
3536

3637
.. note::
3738

@@ -3578,6 +3579,9 @@ written in Python, such as a mail server's external command delivery program.
35783579
process. On Windows, the process id will actually be the process handle, so can
35793580
be used with the :func:`waitpid` function.
35803581

3582+
Note on VxWorks, this function doesn't return ``-signal`` when the new process is
3583+
killed. Instead it raises OSError exception.
3584+
35813585
The "l" and "v" variants of the :func:`spawn\* <spawnl>` functions differ in how
35823586
command-line arguments are passed. The "l" variants are perhaps the easiest
35833587
to work with if the number of parameters is fixed when the code is written; the

Lib/test/test_os.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1407,6 +1407,8 @@ def test_getrandom_value(self):
14071407

14081408
@unittest.skipIf(OS_URANDOM_DONT_USE_FD ,
14091409
"os.random() does not use a file descriptor")
1410+
@unittest.skipIf(sys.platform == "vxworks",
1411+
"VxWorks can't set RLIMIT_NOFILE to 1")
14101412
class URandomFDTests(unittest.TestCase):
14111413
@unittest.skipUnless(resource, "test requires the resource module")
14121414
def test_urandom_failure(self):
@@ -1517,7 +1519,8 @@ def mock_execve(name, *args):
15171519
os.execve = orig_execve
15181520
os.defpath = orig_defpath
15191521

1520-
1522+
@unittest.skipUnless(hasattr(os, 'execv'),
1523+
"need os.execv()")
15211524
class ExecTests(unittest.TestCase):
15221525
@unittest.skipIf(USING_LINUXTHREADS,
15231526
"avoid triggering a linuxthreads bug: see issue #4970")
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add posix module support for VxWorks.

Modules/clinic/posixmodule.c.h

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Modules/posixmodule.c

Lines changed: 65 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -191,11 +191,13 @@ corresponding Unix manual entries for more information on calls.");
191191
#define fsync _commit
192192
#else
193193
/* Unix functions that the configure script doesn't check for */
194+
#ifndef __VXWORKS__
194195
#define HAVE_EXECV 1
195196
#define HAVE_FORK 1
196197
#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
197198
#define HAVE_FORK1 1
198199
#endif
200+
#endif
199201
#define HAVE_GETEGID 1
200202
#define HAVE_GETEUID 1
201203
#define HAVE_GETGID 1
@@ -227,6 +229,18 @@ extern char *ctermid_r(char *);
227229

228230
#endif /* !_MSC_VER */
229231

232+
#if defined(__VXWORKS__)
233+
#include <vxCpuLib.h>
234+
#include <rtpLib.h>
235+
#include <wait.h>
236+
#include <taskLib.h>
237+
#ifndef _P_WAIT
238+
#define _P_WAIT 0
239+
#define _P_NOWAIT 1
240+
#define _P_NOWAITO 1
241+
#endif
242+
#endif /* __VXWORKS__ */
243+
230244
#ifdef HAVE_POSIX_SPAWN
231245
#include <spawn.h>
232246
#endif
@@ -1353,7 +1367,7 @@ win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
13531367
*/
13541368
#include <crt_externs.h>
13551369
static char **environ;
1356-
#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
1370+
#elif !defined(_MSC_VER) && (!defined(__WATCOMC__) || defined(__QNX__) || defined(__VXWORKS__))
13571371
extern char **environ;
13581372
#endif /* !_MSC_VER */
13591373

@@ -4870,7 +4884,7 @@ os__exit_impl(PyObject *module, int status)
48704884
#define EXECV_CHAR char
48714885
#endif
48724886

4873-
#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4887+
#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV) || defined(HAVE_RTPSPAWN)
48744888
static void
48754889
free_string_array(EXECV_CHAR **array, Py_ssize_t count)
48764890
{
@@ -4908,7 +4922,7 @@ fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
49084922
}
49094923
#endif
49104924

4911-
#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
4925+
#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE) || defined(HAVE_RTPSPAWN)
49124926
static EXECV_CHAR**
49134927
parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
49144928
{
@@ -5632,8 +5646,41 @@ os_posix_spawnp_impl(PyObject *module, path_t *path, PyObject *argv,
56325646
}
56335647
#endif /* HAVE_POSIX_SPAWNP */
56345648

5635-
5636-
#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)
5649+
#ifdef HAVE_RTPSPAWN
5650+
static intptr_t
5651+
_rtp_spawn(int mode, const char *rtpFileName, const char *argv[],
5652+
const char *envp[])
5653+
{
5654+
RTP_ID rtpid;
5655+
int status;
5656+
pid_t res;
5657+
int async_err = 0;
5658+
5659+
/* Set priority=100 and uStackSize=16 MiB (0x1000000) for new processes.
5660+
uStackSize=0 cannot be used, the default stack size is too small for
5661+
Python. */
5662+
if (envp) {
5663+
rtpid = rtpSpawn(rtpFileName, argv, envp,
5664+
100, 0x1000000, 0, VX_FP_TASK);
5665+
}
5666+
else {
5667+
rtpid = rtpSpawn(rtpFileName, argv, (const char **)environ,
5668+
100, 0x1000000, 0, VX_FP_TASK);
5669+
}
5670+
if ((rtpid != RTP_ID_ERROR) && (mode == _P_WAIT)) {
5671+
do {
5672+
res = waitpid((pid_t)rtpid, &status, 0);
5673+
} while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
5674+
5675+
if (res < 0)
5676+
return RTP_ID_ERROR;
5677+
return ((intptr_t)status);
5678+
}
5679+
return ((intptr_t)rtpid);
5680+
}
5681+
#endif
5682+
5683+
#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) || defined(HAVE_RTPSPAWN)
56375684
/*[clinic input]
56385685
os.spawnv
56395686
@@ -5703,13 +5750,17 @@ os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
57035750
}
57045751
argvlist[argc] = NULL;
57055752

5753+
#if !defined(HAVE_RTPSPAWN)
57065754
if (mode == _OLD_P_OVERLAY)
57075755
mode = _P_OVERLAY;
5756+
#endif
57085757

57095758
Py_BEGIN_ALLOW_THREADS
57105759
_Py_BEGIN_SUPPRESS_IPH
57115760
#ifdef HAVE_WSPAWNV
57125761
spawnval = _wspawnv(mode, path->wide, argvlist);
5762+
#elif defined(HAVE_RTPSPAWN)
5763+
spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist, NULL);
57135764
#else
57145765
spawnval = _spawnv(mode, path->narrow, argvlist);
57155766
#endif
@@ -5808,13 +5859,18 @@ os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
58085859
if (envlist == NULL)
58095860
goto fail_1;
58105861

5862+
#if !defined(HAVE_RTPSPAWN)
58115863
if (mode == _OLD_P_OVERLAY)
58125864
mode = _P_OVERLAY;
5865+
#endif
58135866

58145867
Py_BEGIN_ALLOW_THREADS
58155868
_Py_BEGIN_SUPPRESS_IPH
58165869
#ifdef HAVE_WSPAWNV
58175870
spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
5871+
#elif defined(HAVE_RTPSPAWN)
5872+
spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist,
5873+
(const char **)envlist);
58185874
#else
58195875
spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
58205876
#endif
@@ -13844,11 +13900,13 @@ all_ins(PyObject *m)
1384413900
if (PyModule_AddIntConstant(m, "POSIX_SPAWN_DUP2", POSIX_SPAWN_DUP2)) return -1;
1384513901
#endif
1384613902

13847-
#ifdef HAVE_SPAWNV
13903+
#if defined(HAVE_SPAWNV) || defined (HAVE_RTPSPAWN)
1384813904
if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
1384913905
if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
13850-
if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
1385113906
if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
13907+
#endif
13908+
#ifdef HAVE_SPAWNV
13909+
if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
1385213910
if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
1385313911
#endif
1385413912

configure

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11484,7 +11484,7 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
1148411484
sigtimedwait sigwait sigwaitinfo snprintf strftime strlcpy strsignal symlinkat sync \
1148511485
sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \
1148611486
truncate uname unlinkat unsetenv utimensat utimes waitid waitpid wait3 wait4 \
11487-
wcscoll wcsftime wcsxfrm wmemcmp writev _getpty
11487+
wcscoll wcsftime wcsxfrm wmemcmp writev _getpty rtpSpawn
1148811488
do :
1148911489
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
1149011490
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"

configure.ac

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3541,7 +3541,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
35413541
sigtimedwait sigwait sigwaitinfo snprintf strftime strlcpy strsignal symlinkat sync \
35423542
sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \
35433543
truncate uname unlinkat unsetenv utimensat utimes waitid waitpid wait3 wait4 \
3544-
wcscoll wcsftime wcsxfrm wmemcmp writev _getpty)
3544+
wcscoll wcsftime wcsxfrm wmemcmp writev _getpty rtpSpawn)
35453545

35463546
# Force lchmod off for Linux. Linux disallows changing the mode of symbolic
35473547
# links. Some libc implementations have a stub lchmod implementation that always

pyconfig.h.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -835,6 +835,9 @@
835835
/* Define to 1 if you have the `round' function. */
836836
#undef HAVE_ROUND
837837

838+
/* Define to 1 if you have the `rtpSpawn' function. */
839+
#undef HAVE_RTPSPAWN
840+
838841
/* Define to 1 if you have the `sched_get_priority_max' function. */
839842
#undef HAVE_SCHED_GET_PRIORITY_MAX
840843

0 commit comments

Comments
 (0)