@@ -177,15 +177,17 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
177177 int p2cread , p2cwrite , c2pread , c2pwrite , errread , errwrite ;
178178 int errpipe_read , errpipe_write , close_fds , restore_signals ;
179179 int call_setsid ;
180+ PyObject * cwd_obj , * cwd_obj2 ;
180181 const char * cwd ;
181182 pid_t pid ;
182183 int need_to_reenable_gc = 0 ;
183184 char * const * exec_array , * const * argv = NULL , * const * envp = NULL ;
184185 Py_ssize_t arg_num ;
185186
186187 if (!PyArg_ParseTuple (
187- args , "OOOzOiiiiiiiiiiO:fork_exec" ,
188- & process_args , & executable_list , & py_close_fds , & cwd , & env_list ,
188+ args , "OOOOOiiiiiiiiiiO:fork_exec" ,
189+ & process_args , & executable_list , & py_close_fds ,
190+ & cwd_obj , & env_list ,
189191 & p2cread , & p2cwrite , & c2pread , & c2pwrite ,
190192 & errread , & errwrite , & errpipe_read , & errpipe_write ,
191193 & restore_signals , & call_setsid , & preexec_fn ))
@@ -263,13 +265,25 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
263265 preexec_fn_args_tuple = PyTuple_New (0 );
264266 if (!preexec_fn_args_tuple )
265267 goto cleanup ;
266- _PyImport_AcquireLock ();
268+ _PyImport_AcquireLock ();
269+ }
270+
271+ if (cwd_obj != Py_None ) {
272+ if (PyUnicode_FSConverter (cwd_obj , & cwd_obj2 ) == 0 )
273+ goto cleanup ;
274+ if (PyBytes_Check (cwd_obj2 ))
275+ cwd = PyBytes_AS_STRING (cwd_obj2 );
276+ else
277+ cwd = PyByteArray_AS_STRING (cwd_obj2 );
278+ } else {
279+ cwd = NULL ;
280+ cwd_obj2 = NULL ;
267281 }
268282
269283 pid = fork ();
270284 if (pid == 0 ) {
271285 /* Child process */
272- /*
286+ /*
273287 * Code from here to _exit() must only use async-signal-safe functions,
274288 * listed at `man 7 signal` or
275289 * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html.
@@ -291,6 +305,8 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
291305 _exit (255 );
292306 return NULL ; /* Dead code to avoid a potential compiler warning. */
293307 }
308+ Py_XDECREF (cwd_obj2 );
309+
294310 if (pid == -1 ) {
295311 /* Capture the errno exception before errno can be clobbered. */
296312 PyErr_SetFromErrno (PyExc_OSError );
0 commit comments