Skip to content

Commit

Permalink
python312: os.posix_spawn enhancements from solaris-userland
Browse files Browse the repository at this point in the history
  • Loading branch information
citrus-it committed Feb 15, 2024
1 parent 70f4f91 commit 949d727
Show file tree
Hide file tree
Showing 4 changed files with 209 additions and 2 deletions.
4 changes: 2 additions & 2 deletions build/python312/patches/mod-posix-sched_priority.patch
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ However, -1 alongside EINVAL represents an error.
diff -wpruN --no-dereference '--exclude=*.orig' a~/Modules/posixmodule.c a/Modules/posixmodule.c
--- a~/Modules/posixmodule.c 1970-01-01 00:00:00
+++ a/Modules/posixmodule.c 1970-01-01 00:00:00
@@ -7757,7 +7757,11 @@ os_sched_get_priority_max_impl(PyObject
@@ -7782,7 +7782,11 @@ os_sched_get_priority_max_impl(PyObject
int max;

max = sched_get_priority_max(policy);
Expand All @@ -19,7 +19,7 @@ diff -wpruN --no-dereference '--exclude=*.orig' a~/Modules/posixmodule.c a/Modul
return posix_error();
return PyLong_FromLong(max);
}
@@ -7776,7 +7780,11 @@ os_sched_get_priority_min_impl(PyObject
@@ -7801,7 +7805,11 @@ os_sched_get_priority_min_impl(PyObject
/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
{
int min = sched_get_priority_min(policy);
Expand Down
141 changes: 141 additions & 0 deletions build/python312/patches/posix_spawn-close_fds-support.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
From https://github.com/oracle/solaris-userland

Implement support for posix_spawn being called with close_fds argument.

This was offered and merged upstream; it will be available in Python 3.13:
https://github.com/python/cpython/issues/113117
https://github.com/python/cpython/pull/113118

diff -wpruN --no-dereference '--exclude=*.orig' a~/Lib/subprocess.py a/Lib/subprocess.py
--- a~/Lib/subprocess.py 1970-01-01 00:00:00
+++ a/Lib/subprocess.py 1970-01-01 00:00:00
@@ -744,6 +744,7 @@ def _use_posix_spawn():
# guarantee the given libc/syscall API will be used.
_USE_POSIX_SPAWN = _use_posix_spawn()
_USE_VFORK = True
+_HAVE_POSIX_SPAWN_CLOSEFROM = hasattr(os, 'POSIX_SPAWN_CLOSEFROM')


class Popen:
@@ -1747,7 +1748,7 @@ class Popen:
errread, errwrite)


- def _posix_spawn(self, args, executable, env, restore_signals,
+ def _posix_spawn(self, args, executable, env, restore_signals, close_fds,
p2cread, p2cwrite,
c2pread, c2pwrite,
errread, errwrite):
@@ -1776,6 +1777,10 @@ class Popen:
):
if fd != -1:
file_actions.append((os.POSIX_SPAWN_DUP2, fd, fd2))
+
+ if close_fds:
+ file_actions.append((os.POSIX_SPAWN_CLOSEFROM, 3))
+
if file_actions:
kwargs['file_actions'] = file_actions

@@ -1823,7 +1828,7 @@ class Popen:
if (_USE_POSIX_SPAWN
and os.path.dirname(executable)
and preexec_fn is None
- and not close_fds
+ and (not close_fds or _HAVE_POSIX_SPAWN_CLOSEFROM)
and not pass_fds
and cwd is None
and (p2cread == -1 or p2cread > 2)
@@ -1835,7 +1840,7 @@ class Popen:
and gids is None
and uid is None
and umask < 0):
- self._posix_spawn(args, executable, env, restore_signals,
+ self._posix_spawn(args, executable, env, restore_signals, close_fds,
p2cread, p2cwrite,
c2pread, c2pwrite,
errread, errwrite)
diff -wpruN --no-dereference '--exclude=*.orig' a~/Lib/test/test_subprocess.py a/Lib/test/test_subprocess.py
--- a~/Lib/test/test_subprocess.py 1970-01-01 00:00:00
+++ a/Lib/test/test_subprocess.py 1970-01-01 00:00:00
@@ -1610,6 +1610,7 @@ class ProcessTestCase(BaseTestCase):
@unittest.skipIf(not sysconfig.get_config_var("HAVE_VFORK"),
"vfork() not enabled by configure.")
@mock.patch("subprocess._fork_exec")
+ @mock.patch("subprocess._USE_POSIX_SPAWN", new=False)
def test__use_vfork(self, mock_fork_exec):
self.assertTrue(subprocess._USE_VFORK) # The default value regardless.
mock_fork_exec.side_effect = RuntimeError("just testing args")
diff -wpruN --no-dereference '--exclude=*.orig' a~/Modules/posixmodule.c a/Modules/posixmodule.c
--- a~/Modules/posixmodule.c 1970-01-01 00:00:00
+++ a/Modules/posixmodule.c 1970-01-01 00:00:00
@@ -6745,6 +6745,9 @@ enum posix_spawn_file_actions_identifier
POSIX_SPAWN_OPEN,
POSIX_SPAWN_CLOSE,
POSIX_SPAWN_DUP2
+#ifdef HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSEFROM_NP
+ ,POSIX_SPAWN_CLOSEFROM
+#endif
};

#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
@@ -6985,6 +6988,24 @@ parse_file_actions(PyObject *file_action
}
break;
}
+#ifdef HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSEFROM_NP
+ case POSIX_SPAWN_CLOSEFROM: {
+ int fd;
+ if (!PyArg_ParseTuple(file_action, "Oi"
+ ";A closefrom file_action tuple must have 2 elements",
+ &tag_obj, &fd))
+ {
+ goto fail;
+ }
+ errno = posix_spawn_file_actions_addclosefrom_np(file_actionsp,
+ fd);
+ if (errno) {
+ posix_error();
+ goto fail;
+ }
+ break;
+ }
+#endif
default: {
PyErr_SetString(PyExc_TypeError,
"Unknown file_actions identifier");
@@ -16412,6 +16433,9 @@ all_ins(PyObject *m)
if (PyModule_AddIntConstant(m, "POSIX_SPAWN_OPEN", POSIX_SPAWN_OPEN)) return -1;
if (PyModule_AddIntConstant(m, "POSIX_SPAWN_CLOSE", POSIX_SPAWN_CLOSE)) return -1;
if (PyModule_AddIntConstant(m, "POSIX_SPAWN_DUP2", POSIX_SPAWN_DUP2)) return -1;
+#ifdef HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSEFROM_NP
+ if (PyModule_AddIntMacro(m, POSIX_SPAWN_CLOSEFROM)) return -1;
+#endif
#endif

#if defined(HAVE_SPAWNV) || defined (HAVE_RTPSPAWN)
diff -wpruN --no-dereference '--exclude=*.orig' a~/configure.ac a/configure.ac
--- a~/configure.ac 1970-01-01 00:00:00
+++ a/configure.ac 1970-01-01 00:00:00
@@ -4896,6 +4896,7 @@ AC_CHECK_FUNCS([ \
lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \
mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \
pipe2 plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
+ posix_spawn_file_actions_addclosefrom_np \
pread preadv preadv2 pthread_condattr_setclock pthread_init pthread_kill \
pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \
rtpSpawn sched_get_priority_max sched_rr_get_interval sched_setaffinity \
diff -wpruN --no-dereference '--exclude=*.orig' a~/pyconfig.h.in a/pyconfig.h.in
--- a~/pyconfig.h.in 1970-01-01 00:00:00
+++ a/pyconfig.h.in 1970-01-01 00:00:00
@@ -908,6 +908,10 @@
/* Define to 1 if you have the `posix_spawnp' function. */
#undef HAVE_POSIX_SPAWNP

+/* Define to 1 if you have the `posix_spawn_file_actions_addclosefrom_np'
+ function. */
+#undef HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSEFROM_NP
+
/* Define to 1 if you have the `pread' function. */
#undef HAVE_PREAD

64 changes: 64 additions & 0 deletions build/python312/patches/posix_spawn-environment-fix.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
From https://github.com/oracle/solaris-userland

Allow for os.posix_spawn call with env set to None, which makes it inherit
the environment from the current process (similar to execv).

With this change, subprocess using posix_spawn can behave similarly
to the standard fork exec path.

This was offered and merged upstream; it will be available in Python 3.13:
https://github.com/python/cpython/issues/113119
https://github.com/python/cpython/pull/113120

diff -wpruN --no-dereference '--exclude=*.orig' a~/Lib/subprocess.py a/Lib/subprocess.py
--- a~/Lib/subprocess.py 1970-01-01 00:00:00
+++ a/Lib/subprocess.py 1970-01-01 00:00:00
@@ -1753,9 +1753,6 @@ class Popen:
c2pread, c2pwrite,
errread, errwrite):
"""Execute program using os.posix_spawn()."""
- if env is None:
- env = os.environ
-
kwargs = {}
if restore_signals:
# See _Py_RestoreSignals() in Python/pylifecycle.c
diff -wpruN --no-dereference '--exclude=*.orig' a~/Modules/posixmodule.c a/Modules/posixmodule.c
--- a~/Modules/posixmodule.c 1970-01-01 00:00:00
+++ a/Modules/posixmodule.c 1970-01-01 00:00:00
@@ -7061,9 +7061,9 @@ py_posix_spawn(int use_posix_spawnp, PyO
return NULL;
}

- if (!PyMapping_Check(env)) {
+ if (!PyMapping_Check(env) && env != Py_None) {
PyErr_Format(PyExc_TypeError,
- "%s: environment must be a mapping object", func_name);
+ "%s: environment must be a mapping object or None", func_name);
goto exit;
}

@@ -7077,10 +7077,14 @@ py_posix_spawn(int use_posix_spawnp, PyO
goto exit;
}

+ if (env == Py_None) {
+ envlist = environ;
+ } else {
envlist = parse_envlist(env, &envc);
if (envlist == NULL) {
goto exit;
}
+ }

if (file_actions != NULL && file_actions != Py_None) {
/* There is a bug in old versions of glibc that makes some of the
@@ -7142,7 +7146,7 @@ exit:
if (attrp) {
(void)posix_spawnattr_destroy(attrp);
}
- if (envlist) {
+ if (envlist && envlist != environ) {
free_string_array(envlist, envc);
}
if (argvlist) {
2 changes: 2 additions & 0 deletions build/python312/patches/series
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ pyc-timestamp.patch
asyncio-watcher.patch
py_db.patch
restore-dtrace.patch
posix_spawn-close_fds-support.patch
posix_spawn-environment-fix.patch
#
# Additional modules
module-ucred.patch
Expand Down

0 comments on commit 949d727

Please sign in to comment.