@@ -79,11 +79,11 @@ wait_for_terminal_ready(int fd) {
7979
8080static PyObject *
8181spawn (PyObject * self UNUSED , PyObject * args ) {
82- PyObject * argv_p , * env_p , * handled_signals_p ;
82+ PyObject * argv_p , * env_p , * handled_signals_p , * pass_fds ;
8383 int master , slave , stdin_read_fd , stdin_write_fd , ready_read_fd , ready_write_fd , forward_stdio ;
8484 const char * kitten_exe ;
8585 char * cwd , * exe ;
86- if (!PyArg_ParseTuple (args , "ssO!O!iiiiiiO!sp " , & exe , & cwd , & PyTuple_Type , & argv_p , & PyTuple_Type , & env_p , & master , & slave , & stdin_read_fd , & stdin_write_fd , & ready_read_fd , & ready_write_fd , & PyTuple_Type , & handled_signals_p , & kitten_exe , & forward_stdio )) return NULL ;
86+ if (!PyArg_ParseTuple (args , "ssO!O!iiiiiiO!spO! " , & exe , & cwd , & PyTuple_Type , & argv_p , & PyTuple_Type , & env_p , & master , & slave , & stdin_read_fd , & stdin_write_fd , & ready_read_fd , & ready_write_fd , & PyTuple_Type , & handled_signals_p , & kitten_exe , & forward_stdio , & PyTuple_Type , & pass_fds )) return NULL ;
8787 char name [2048 ] = {0 };
8888 if (ttyname_r (slave , name , sizeof (name ) - 1 ) != 0 ) { PyErr_SetFromErrno (PyExc_OSError ); return NULL ; }
8989 char * * argv = serialize_string_tuple (argv_p );
@@ -130,6 +130,15 @@ spawn(PyObject *self UNUSED, PyObject *args) {
130130 safe_close (tfd , __FILE__ , __LINE__ );
131131
132132 int min_closed_fd = 3 ;
133+ for (Py_ssize_t i = 0 ; i < PyTuple_GET_SIZE (pass_fds ); i ++ ) {
134+ PyObject * pfd = PyTuple_GET_ITEM (pass_fds , i );
135+ if (!PyLong_Check (pfd )) exit_on_err ("pass_fds must contain only integers" );
136+ int fd = PyLong_AsLong (pfd );
137+ if (fd > -1 ) {
138+ if (fd == min_closed_fd ) min_closed_fd ++ ;
139+ else if (safe_dup2 (fd , min_closed_fd ++ ) == -1 ) exit_on_err ("dup2() failed for forwarded fd 1" );
140+ }
141+ }
133142 if (forward_stdio ) {
134143 if (safe_dup2 (STDOUT_FILENO , min_closed_fd ++ ) == -1 ) exit_on_err ("dup2() failed for forwarded fd 1" );
135144 if (safe_dup2 (STDERR_FILENO , min_closed_fd ++ ) == -1 ) exit_on_err ("dup2() failed for forwarded fd 2" );
0 commit comments