aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/src/Modules/_posixsubprocess.c
diff options
context:
space:
mode:
authorshadchin <shadchin@yandex-team.ru>2022-02-10 16:44:39 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:44:39 +0300
commite9656aae26e0358d5378e5b63dcac5c8dbe0e4d0 (patch)
tree64175d5cadab313b3e7039ebaa06c5bc3295e274 /contrib/tools/python3/src/Modules/_posixsubprocess.c
parent2598ef1d0aee359b4b6d5fdd1758916d5907d04f (diff)
downloadydb-e9656aae26e0358d5378e5b63dcac5c8dbe0e4d0.tar.gz
Restoring authorship annotation for <shadchin@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/tools/python3/src/Modules/_posixsubprocess.c')
-rw-r--r--contrib/tools/python3/src/Modules/_posixsubprocess.c466
1 files changed, 233 insertions, 233 deletions
diff --git a/contrib/tools/python3/src/Modules/_posixsubprocess.c b/contrib/tools/python3/src/Modules/_posixsubprocess.c
index 2e01d1e9c3..d64e0a1cfa 100644
--- a/contrib/tools/python3/src/Modules/_posixsubprocess.c
+++ b/contrib/tools/python3/src/Modules/_posixsubprocess.c
@@ -8,7 +8,7 @@
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
-#if defined(HAVE_SYS_STAT_H)
+#if defined(HAVE_SYS_STAT_H)
#include <sys/stat.h>
#endif
#ifdef HAVE_SYS_SYSCALL_H
@@ -20,12 +20,12 @@
#ifdef HAVE_DIRENT_H
#include <dirent.h>
#endif
-#ifdef HAVE_GRP_H
-#include <grp.h>
-#endif /* HAVE_GRP_H */
+#ifdef HAVE_GRP_H
+#include <grp.h>
+#endif /* HAVE_GRP_H */
+
+#include "posixmodule.h"
-#include "posixmodule.h"
-
#ifdef _Py_MEMORY_SANITIZER
# include <sanitizer/msan_interface.h>
#endif
@@ -46,38 +46,38 @@
# endif
#endif
-#if defined(__FreeBSD__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__DragonFly__)
+#if defined(__FreeBSD__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__DragonFly__)
# define FD_DIR "/dev/fd"
#else
# define FD_DIR "/proc/self/fd"
#endif
-#ifdef NGROUPS_MAX
-#define MAX_GROUPS NGROUPS_MAX
-#else
-#define MAX_GROUPS 64
-#endif
-
+#ifdef NGROUPS_MAX
+#define MAX_GROUPS NGROUPS_MAX
+#else
+#define MAX_GROUPS 64
+#endif
+
#define POSIX_CALL(call) do { if ((call) == -1) goto error; } while (0)
-typedef struct {
- PyObject* disable;
- PyObject* enable;
- PyObject* isenabled;
-} _posixsubprocessstate;
-
-static struct PyModuleDef _posixsubprocessmodule;
-
-static inline _posixsubprocessstate*
-get_posixsubprocess_state(PyObject *module)
-{
- void *state = PyModule_GetState(module);
- assert(state != NULL);
- return (_posixsubprocessstate *)state;
-}
-
-#define _posixsubprocessstate_global get_posixsubprocess_state(PyState_FindModule(&_posixsubprocessmodule))
-
+typedef struct {
+ PyObject* disable;
+ PyObject* enable;
+ PyObject* isenabled;
+} _posixsubprocessstate;
+
+static struct PyModuleDef _posixsubprocessmodule;
+
+static inline _posixsubprocessstate*
+get_posixsubprocess_state(PyObject *module)
+{
+ void *state = PyModule_GetState(module);
+ assert(state != NULL);
+ return (_posixsubprocessstate *)state;
+}
+
+#define _posixsubprocessstate_global get_posixsubprocess_state(PyState_FindModule(&_posixsubprocessmodule))
+
/* If gc was disabled, call gc.enable(). Return 0 on success. */
static int
_enable_gc(int need_to_reenable_gc, PyObject *gc_module)
@@ -87,8 +87,8 @@ _enable_gc(int need_to_reenable_gc, PyObject *gc_module)
if (need_to_reenable_gc) {
PyErr_Fetch(&exctype, &val, &tb);
- result = PyObject_CallMethodNoArgs(
- gc_module, _posixsubprocessstate_global->enable);
+ result = PyObject_CallMethodNoArgs(
+ gc_module, _posixsubprocessstate_global->enable);
if (exctype != NULL) {
PyErr_Restore(exctype, val, tb);
}
@@ -116,9 +116,9 @@ _pos_int_from_ascii(const char *name)
}
-#if defined(__FreeBSD__) || defined(__DragonFly__)
+#if defined(__FreeBSD__) || defined(__DragonFly__)
/* When /dev/fd isn't mounted it is often a static directory populated
- * with 0 1 2 or entries for 0 .. 63 on FreeBSD, NetBSD, OpenBSD and DragonFlyBSD.
+ * with 0 1 2 or entries for 0 .. 63 on FreeBSD, NetBSD, OpenBSD and DragonFlyBSD.
* NetBSD and OpenBSD have a /proc fs available (though not necessarily
* mounted) and do not have fdescfs for /dev/fd. MacOS X has a devfs
* that properly supports /dev/fd.
@@ -264,15 +264,15 @@ _close_fds_by_brute_force(long start_fd, PyObject *py_fds_to_keep)
start_fd = keep_fd + 1;
}
if (start_fd <= end_fd) {
-#if defined(__FreeBSD__)
- /* Any errors encountered while closing file descriptors are ignored */
- closefrom(start_fd);
-#else
+#if defined(__FreeBSD__)
+ /* Any errors encountered while closing file descriptors are ignored */
+ closefrom(start_fd);
+#else
for (fd_num = start_fd; fd_num < end_fd; ++fd_num) {
- /* Ignore errors */
- (void)close(fd_num);
+ /* Ignore errors */
+ (void)close(fd_num);
}
-#endif
+#endif
}
}
@@ -377,7 +377,7 @@ _close_open_fds_maybe_unsafe(long start_fd, PyObject* py_fds_to_keep)
++start_fd;
#endif
-#if defined(__FreeBSD__) || defined(__DragonFly__)
+#if defined(__FreeBSD__) || defined(__DragonFly__)
if (!_is_fdescfs_mounted_on_dev_fd())
proc_fd_dir = NULL;
else
@@ -439,9 +439,9 @@ child_exec(char *const exec_array[],
int errpipe_read, int errpipe_write,
int close_fds, int restore_signals,
int call_setsid,
- int call_setgid, gid_t gid,
- int call_setgroups, size_t groups_size, const gid_t *groups,
- int call_setuid, uid_t uid, int child_umask,
+ int call_setgid, gid_t gid,
+ int call_setgroups, size_t groups_size, const gid_t *groups,
+ int call_setuid, uid_t uid, int child_umask,
PyObject *py_fds_to_keep,
PyObject *preexec_fn,
PyObject *preexec_fn_args_tuple)
@@ -511,9 +511,9 @@ child_exec(char *const exec_array[],
if (cwd)
POSIX_CALL(chdir(cwd));
- if (child_umask >= 0)
- umask(child_umask); /* umask() always succeeds. */
-
+ if (child_umask >= 0)
+ umask(child_umask); /* umask() always succeeds. */
+
if (restore_signals)
_Py_RestoreSignals();
@@ -522,22 +522,22 @@ child_exec(char *const exec_array[],
POSIX_CALL(setsid());
#endif
-#ifdef HAVE_SETGROUPS
- if (call_setgroups)
- POSIX_CALL(setgroups(groups_size, groups));
-#endif /* HAVE_SETGROUPS */
-
-#ifdef HAVE_SETREGID
- if (call_setgid)
- POSIX_CALL(setregid(gid, gid));
-#endif /* HAVE_SETREGID */
-
-#ifdef HAVE_SETREUID
- if (call_setuid)
- POSIX_CALL(setreuid(uid, uid));
-#endif /* HAVE_SETREUID */
-
-
+#ifdef HAVE_SETGROUPS
+ if (call_setgroups)
+ POSIX_CALL(setgroups(groups_size, groups));
+#endif /* HAVE_SETGROUPS */
+
+#ifdef HAVE_SETREGID
+ if (call_setgid)
+ POSIX_CALL(setregid(gid, gid));
+#endif /* HAVE_SETREGID */
+
+#ifdef HAVE_SETREUID
+ if (call_setuid)
+ POSIX_CALL(setreuid(uid, uid));
+#endif /* HAVE_SETREUID */
+
+
reached_preexec = 1;
if (preexec_fn != Py_None && preexec_fn_args_tuple) {
/* This is where the user has asked us to deadlock their program. */
@@ -617,43 +617,43 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
PyObject *env_list, *preexec_fn;
PyObject *process_args, *converted_args = NULL, *fast_args = NULL;
PyObject *preexec_fn_args_tuple = NULL;
- PyObject *groups_list;
- PyObject *uid_object, *gid_object;
+ PyObject *groups_list;
+ PyObject *uid_object, *gid_object;
int p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite;
int errpipe_read, errpipe_write, close_fds, restore_signals;
int call_setsid;
- int call_setgid = 0, call_setgroups = 0, call_setuid = 0;
- uid_t uid;
- gid_t gid, *groups = NULL;
- int child_umask;
- PyObject *cwd_obj, *cwd_obj2 = NULL;
+ int call_setgid = 0, call_setgroups = 0, call_setuid = 0;
+ uid_t uid;
+ gid_t gid, *groups = NULL;
+ int child_umask;
+ PyObject *cwd_obj, *cwd_obj2 = NULL;
const char *cwd;
pid_t pid;
int need_to_reenable_gc = 0;
char *const *exec_array, *const *argv = NULL, *const *envp = NULL;
- Py_ssize_t arg_num, num_groups = 0;
+ Py_ssize_t arg_num, num_groups = 0;
int need_after_fork = 0;
int saved_errno = 0;
if (!PyArg_ParseTuple(
- args, "OOpO!OOiiiiiiiiiiOOOiO:fork_exec",
+ args, "OOpO!OOiiiiiiiiiiOOOiO:fork_exec",
&process_args, &executable_list,
&close_fds, &PyTuple_Type, &py_fds_to_keep,
&cwd_obj, &env_list,
&p2cread, &p2cwrite, &c2pread, &c2pwrite,
&errread, &errwrite, &errpipe_read, &errpipe_write,
- &restore_signals, &call_setsid,
- &gid_object, &groups_list, &uid_object, &child_umask,
- &preexec_fn))
+ &restore_signals, &call_setsid,
+ &gid_object, &groups_list, &uid_object, &child_umask,
+ &preexec_fn))
return NULL;
- if ((preexec_fn != Py_None) &&
- (PyInterpreterState_Get() != PyInterpreterState_Main())) {
- PyErr_SetString(PyExc_RuntimeError,
- "preexec_fn not supported within subinterpreters");
- return NULL;
- }
-
+ if ((preexec_fn != Py_None) &&
+ (PyInterpreterState_Get() != PyInterpreterState_Main())) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "preexec_fn not supported within subinterpreters");
+ return NULL;
+ }
+
if (close_fds && errpipe_write < 3) { /* precondition */
PyErr_SetString(PyExc_ValueError, "errpipe_write must be >= 3");
return NULL;
@@ -663,14 +663,14 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
return NULL;
}
- PyInterpreterState *interp = PyInterpreterState_Get();
- const PyConfig *config = _PyInterpreterState_GetConfig(interp);
- if (config->_isolated_interpreter) {
- PyErr_SetString(PyExc_RuntimeError,
- "subprocess not supported for isolated subinterpreters");
- return NULL;
- }
-
+ PyInterpreterState *interp = PyInterpreterState_Get();
+ const PyConfig *config = _PyInterpreterState_GetConfig(interp);
+ if (config->_isolated_interpreter) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "subprocess not supported for isolated subinterpreters");
+ return NULL;
+ }
+
/* We need to call gc.disable() when we'll be calling preexec_fn */
if (preexec_fn != Py_None) {
PyObject *result;
@@ -678,8 +678,8 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
gc_module = PyImport_ImportModule("gc");
if (gc_module == NULL)
return NULL;
- result = PyObject_CallMethodNoArgs(
- gc_module, _posixsubprocessstate_global->isenabled);
+ result = PyObject_CallMethodNoArgs(
+ gc_module, _posixsubprocessstate_global->isenabled);
if (result == NULL) {
Py_DECREF(gc_module);
return NULL;
@@ -690,8 +690,8 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
Py_DECREF(gc_module);
return NULL;
}
- result = PyObject_CallMethodNoArgs(
- gc_module, _posixsubprocessstate_global->disable);
+ result = PyObject_CallMethodNoArgs(
+ gc_module, _posixsubprocessstate_global->disable);
if (result == NULL) {
Py_DECREF(gc_module);
return NULL;
@@ -750,86 +750,86 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
cwd = NULL;
}
- if (groups_list != Py_None) {
-#ifdef HAVE_SETGROUPS
- Py_ssize_t i;
- gid_t gid;
-
- if (!PyList_Check(groups_list)) {
- PyErr_SetString(PyExc_TypeError,
- "setgroups argument must be a list");
- goto cleanup;
- }
- num_groups = PySequence_Size(groups_list);
-
- if (num_groups < 0)
- goto cleanup;
-
- if (num_groups > MAX_GROUPS) {
- PyErr_SetString(PyExc_ValueError, "too many groups");
- goto cleanup;
- }
-
- if ((groups = PyMem_RawMalloc(num_groups * sizeof(gid_t))) == NULL) {
- PyErr_SetString(PyExc_MemoryError,
- "failed to allocate memory for group list");
- goto cleanup;
- }
-
- for (i = 0; i < num_groups; i++) {
- PyObject *elem;
- elem = PySequence_GetItem(groups_list, i);
- if (!elem)
- goto cleanup;
- if (!PyLong_Check(elem)) {
- PyErr_SetString(PyExc_TypeError,
- "groups must be integers");
- Py_DECREF(elem);
- goto cleanup;
- } else {
- if (!_Py_Gid_Converter(elem, &gid)) {
- Py_DECREF(elem);
- PyErr_SetString(PyExc_ValueError, "invalid group id");
- goto cleanup;
- }
- groups[i] = gid;
- }
- Py_DECREF(elem);
- }
- call_setgroups = 1;
-
-#else /* HAVE_SETGROUPS */
- PyErr_BadInternalCall();
- goto cleanup;
-#endif /* HAVE_SETGROUPS */
- }
-
- if (gid_object != Py_None) {
-#ifdef HAVE_SETREGID
- if (!_Py_Gid_Converter(gid_object, &gid))
- goto cleanup;
-
- call_setgid = 1;
-
-#else /* HAVE_SETREGID */
- PyErr_BadInternalCall();
- goto cleanup;
-#endif /* HAVE_SETREUID */
- }
-
- if (uid_object != Py_None) {
-#ifdef HAVE_SETREUID
- if (!_Py_Uid_Converter(uid_object, &uid))
- goto cleanup;
-
- call_setuid = 1;
-
-#else /* HAVE_SETREUID */
- PyErr_BadInternalCall();
- goto cleanup;
-#endif /* HAVE_SETREUID */
- }
-
+ if (groups_list != Py_None) {
+#ifdef HAVE_SETGROUPS
+ Py_ssize_t i;
+ gid_t gid;
+
+ if (!PyList_Check(groups_list)) {
+ PyErr_SetString(PyExc_TypeError,
+ "setgroups argument must be a list");
+ goto cleanup;
+ }
+ num_groups = PySequence_Size(groups_list);
+
+ if (num_groups < 0)
+ goto cleanup;
+
+ if (num_groups > MAX_GROUPS) {
+ PyErr_SetString(PyExc_ValueError, "too many groups");
+ goto cleanup;
+ }
+
+ if ((groups = PyMem_RawMalloc(num_groups * sizeof(gid_t))) == NULL) {
+ PyErr_SetString(PyExc_MemoryError,
+ "failed to allocate memory for group list");
+ goto cleanup;
+ }
+
+ for (i = 0; i < num_groups; i++) {
+ PyObject *elem;
+ elem = PySequence_GetItem(groups_list, i);
+ if (!elem)
+ goto cleanup;
+ if (!PyLong_Check(elem)) {
+ PyErr_SetString(PyExc_TypeError,
+ "groups must be integers");
+ Py_DECREF(elem);
+ goto cleanup;
+ } else {
+ if (!_Py_Gid_Converter(elem, &gid)) {
+ Py_DECREF(elem);
+ PyErr_SetString(PyExc_ValueError, "invalid group id");
+ goto cleanup;
+ }
+ groups[i] = gid;
+ }
+ Py_DECREF(elem);
+ }
+ call_setgroups = 1;
+
+#else /* HAVE_SETGROUPS */
+ PyErr_BadInternalCall();
+ goto cleanup;
+#endif /* HAVE_SETGROUPS */
+ }
+
+ if (gid_object != Py_None) {
+#ifdef HAVE_SETREGID
+ if (!_Py_Gid_Converter(gid_object, &gid))
+ goto cleanup;
+
+ call_setgid = 1;
+
+#else /* HAVE_SETREGID */
+ PyErr_BadInternalCall();
+ goto cleanup;
+#endif /* HAVE_SETREUID */
+ }
+
+ if (uid_object != Py_None) {
+#ifdef HAVE_SETREUID
+ if (!_Py_Uid_Converter(uid_object, &uid))
+ goto cleanup;
+
+ call_setuid = 1;
+
+#else /* HAVE_SETREUID */
+ PyErr_BadInternalCall();
+ goto cleanup;
+#endif /* HAVE_SETREUID */
+ }
+
/* This must be the last thing done before fork() because we do not
* want to call PyOS_BeforeFork() if there is any chance of another
* error leading to the cleanup: code without calling fork(). */
@@ -862,8 +862,8 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
p2cread, p2cwrite, c2pread, c2pwrite,
errread, errwrite, errpipe_read, errpipe_write,
close_fds, restore_signals, call_setsid,
- call_setgid, gid, call_setgroups, num_groups, groups,
- call_setuid, uid, child_umask,
+ call_setgid, gid, call_setgroups, num_groups, groups,
+ call_setuid, uid, child_umask,
py_fds_to_keep, preexec_fn, preexec_fn_args_tuple);
_exit(255);
return NULL; /* Dead code to avoid a potential compiler warning. */
@@ -888,7 +888,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
if (_enable_gc(need_to_reenable_gc, gc_module)) {
pid = -1;
}
- PyMem_RawFree(groups);
+ PyMem_RawFree(groups);
Py_XDECREF(preexec_fn_args_tuple);
Py_XDECREF(gc_module);
@@ -903,15 +903,15 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
return PyLong_FromPid(pid);
cleanup:
- Py_XDECREF(cwd_obj2);
+ Py_XDECREF(cwd_obj2);
if (envp)
_Py_FreeCharPArray(envp);
if (argv)
_Py_FreeCharPArray(argv);
if (exec_array)
_Py_FreeCharPArray(exec_array);
-
- PyMem_RawFree(groups);
+
+ PyMem_RawFree(groups);
Py_XDECREF(converted_args);
Py_XDECREF(fast_args);
Py_XDECREF(preexec_fn_args_tuple);
@@ -922,22 +922,22 @@ cleanup:
PyDoc_STRVAR(subprocess_fork_exec_doc,
-"fork_exec(args, executable_list, close_fds, pass_fds, cwd, env,\n\
+"fork_exec(args, executable_list, close_fds, pass_fds, cwd, env,\n\
p2cread, p2cwrite, c2pread, c2pwrite,\n\
errread, errwrite, errpipe_read, errpipe_write,\n\
- restore_signals, call_setsid,\n\
- gid, groups_list, uid,\n\
- preexec_fn)\n\
+ restore_signals, call_setsid,\n\
+ gid, groups_list, uid,\n\
+ preexec_fn)\n\
\n\
Forks a child process, closes parent file descriptors as appropriate in the\n\
child and dups the few that are needed before calling exec() in the child\n\
process.\n\
\n\
-If close_fds is true, close file descriptors 3 and higher, except those listed\n\
-in the sorted tuple pass_fds.\n\
-\n\
-The preexec_fn, if supplied, will be called immediately before closing file\n\
-descriptors and exec.\n\
+If close_fds is true, close file descriptors 3 and higher, except those listed\n\
+in the sorted tuple pass_fds.\n\
+\n\
+The preexec_fn, if supplied, will be called immediately before closing file\n\
+descriptors and exec.\n\
WARNING: preexec_fn is NOT SAFE if your application uses threads.\n\
It may trigger infrequent, difficult to debug deadlocks.\n\
\n\
@@ -961,56 +961,56 @@ static PyMethodDef module_methods[] = {
};
-static int _posixsubprocess_traverse(PyObject *m, visitproc visit, void *arg) {
- Py_VISIT(get_posixsubprocess_state(m)->disable);
- Py_VISIT(get_posixsubprocess_state(m)->enable);
- Py_VISIT(get_posixsubprocess_state(m)->isenabled);
- return 0;
-}
-
-static int _posixsubprocess_clear(PyObject *m) {
- Py_CLEAR(get_posixsubprocess_state(m)->disable);
- Py_CLEAR(get_posixsubprocess_state(m)->enable);
- Py_CLEAR(get_posixsubprocess_state(m)->isenabled);
- return 0;
-}
-
-static void _posixsubprocess_free(void *m) {
- _posixsubprocess_clear((PyObject *)m);
-}
-
+static int _posixsubprocess_traverse(PyObject *m, visitproc visit, void *arg) {
+ Py_VISIT(get_posixsubprocess_state(m)->disable);
+ Py_VISIT(get_posixsubprocess_state(m)->enable);
+ Py_VISIT(get_posixsubprocess_state(m)->isenabled);
+ return 0;
+}
+
+static int _posixsubprocess_clear(PyObject *m) {
+ Py_CLEAR(get_posixsubprocess_state(m)->disable);
+ Py_CLEAR(get_posixsubprocess_state(m)->enable);
+ Py_CLEAR(get_posixsubprocess_state(m)->isenabled);
+ return 0;
+}
+
+static void _posixsubprocess_free(void *m) {
+ _posixsubprocess_clear((PyObject *)m);
+}
+
static struct PyModuleDef _posixsubprocessmodule = {
PyModuleDef_HEAD_INIT,
"_posixsubprocess",
module_doc,
- sizeof(_posixsubprocessstate),
+ sizeof(_posixsubprocessstate),
module_methods,
- NULL,
- _posixsubprocess_traverse,
- _posixsubprocess_clear,
- _posixsubprocess_free,
+ NULL,
+ _posixsubprocess_traverse,
+ _posixsubprocess_clear,
+ _posixsubprocess_free,
};
PyMODINIT_FUNC
PyInit__posixsubprocess(void)
{
- PyObject* m;
-
- m = PyState_FindModule(&_posixsubprocessmodule);
- if (m != NULL) {
- Py_INCREF(m);
- return m;
- }
-
- m = PyModule_Create(&_posixsubprocessmodule);
- if (m == NULL) {
- return NULL;
- }
-
- get_posixsubprocess_state(m)->disable = PyUnicode_InternFromString("disable");
- get_posixsubprocess_state(m)->enable = PyUnicode_InternFromString("enable");
- get_posixsubprocess_state(m)->isenabled = PyUnicode_InternFromString("isenabled");
-
- PyState_AddModule(m, &_posixsubprocessmodule);
- return m;
+ PyObject* m;
+
+ m = PyState_FindModule(&_posixsubprocessmodule);
+ if (m != NULL) {
+ Py_INCREF(m);
+ return m;
+ }
+
+ m = PyModule_Create(&_posixsubprocessmodule);
+ if (m == NULL) {
+ return NULL;
+ }
+
+ get_posixsubprocess_state(m)->disable = PyUnicode_InternFromString("disable");
+ get_posixsubprocess_state(m)->enable = PyUnicode_InternFromString("enable");
+ get_posixsubprocess_state(m)->isenabled = PyUnicode_InternFromString("isenabled");
+
+ PyState_AddModule(m, &_posixsubprocessmodule);
+ return m;
}