@@ -5142,15 +5142,15 @@ os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
51425142 Py_ssize_t argc , envc ;
51435143 PyObject * result = NULL ;
51445144 PyObject * seq = NULL ;
5145-
5145+ PyObject * file_actions_obj = NULL ;
51465146
51475147 /* posix_spawn has three arguments: (path, argv, env), where
5148- argv is a list or tuple of strings and env is a dictionary
5149- like posix.environ. */
5148+ argv is a list or tuple of strings and env is a dictionary
5149+ like posix.environ. */
51505150
5151- if (!PySequence_Check (argv )) {
5151+ if (!PyList_Check ( argv ) && ! PyTuple_Check (argv )) {
51525152 PyErr_SetString (PyExc_TypeError ,
5153- "posix_spawn: argv must be a tuple or list " );
5153+ "posix_spawn: argv must be a tuple" );
51545154 goto exit ;
51555155 }
51565156 argc = PySequence_Size (argv );
@@ -5181,8 +5181,8 @@ os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
51815181 }
51825182
51835183 pid_t pid ;
5184- if (file_actions != NULL && file_actions != Py_None ) {
5185- if (posix_spawn_file_actions_init (& _file_actions ) != 0 ){
5184+ if (file_actions != Py_None ) {
5185+ if (posix_spawn_file_actions_init (& _file_actions ) != 0 ) {
51865186 PyErr_SetString (PyExc_OSError ,
51875187 "Error initializing file actions" );
51885188 goto exit ;
@@ -5191,104 +5191,104 @@ os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
51915191 file_actionsp = & _file_actions ;
51925192
51935193 seq = PySequence_Fast (file_actions , "file_actions must be a sequence" );
5194- if (seq == NULL ) {
5194+ if (seq == NULL ) {
51955195 goto exit ;
51965196 }
5197- PyObject * file_actions_obj ;
51985197 PyObject * mode_obj ;
51995198
52005199 for (int i = 0 ; i < PySequence_Fast_GET_SIZE (seq ); ++ i ) {
52015200 file_actions_obj = PySequence_Fast_GET_ITEM (seq , i );
5202-
5203- if (!PySequence_Check (file_actions_obj ) | !PySequence_Size (file_actions_obj )) {
5204- PyErr_SetString (PyExc_TypeError ,"Each file_action element must be a non empty sequence" );
5201+ if (file_actions_obj == NULL ) {
5202+ goto exit ;
5203+ }
5204+ file_actions_obj = PySequence_Fast (file_actions_obj ,
5205+ "Each file_action element must be" \
5206+ " a non-empty sequence" );
5207+ if (file_actions_obj == NULL ) {
52055208 goto exit ;
52065209 }
5207-
52085210
52095211 mode_obj = PySequence_Fast_GET_ITEM (file_actions_obj , 0 );
52105212 int mode = PyLong_AsLong (mode_obj );
5213+ if (mode == -1 && PyErr_Occurred ()) {
5214+ goto exit ;
5215+ }
52115216
52125217 /* Populate the file_actions object */
52135218
52145219 switch (mode ) {
52155220
52165221 case POSIX_SPAWN_OPEN :
5217- if (PySequence_Size (file_actions_obj ) != 5 ) {
5222+ if (PySequence_Size (file_actions_obj ) != 5 ) {
52185223 PyErr_SetString (PyExc_TypeError ,"A open file_action object must have 5 elements" );
52195224 goto exit ;
52205225 }
5226+ int open_fd , open_oflag , open_mode ;
5227+ char * open_path ;
52215228
5222- long open_fd = PyLong_AsLong (PySequence_GetItem (file_actions_obj , 1 ));
5223- if (PyErr_Occurred ()) {
5224- goto exit ;
5225- }
5226- const char * open_path = PyUnicode_AsUTF8 (PySequence_GetItem (file_actions_obj , 2 ));
5227- if (open_path == NULL ) {
5229+ if (!PyArg_ParseTuple (file_actions_obj , "iisii" , & mode , & open_fd , & open_path ,
5230+ & open_oflag , & open_mode )) {
52285231 goto exit ;
52295232 }
5230- long open_oflag = PyLong_AsLong (PySequence_GetItem (file_actions_obj , 3 ));
5231- if (PyErr_Occurred ()) {
5232- goto exit ;
5233- }
5234- long open_mode = PyLong_AsLong (PySequence_GetItem (file_actions_obj , 4 ));
5235- if (PyErr_Occurred ()) {
5236- goto exit ;
5237- }
5238- if (posix_spawn_file_actions_addopen (file_actionsp , open_fd , open_path , open_oflag , open_mode )) {
5233+
5234+ if (posix_spawn_file_actions_addopen (file_actionsp , open_fd , open_path , open_oflag , open_mode )) {
52395235 PyErr_SetString (PyExc_OSError ,"Failed to add open file action" );
52405236 goto exit ;
52415237 }
5242-
5238+
52435239 break ;
52445240
52455241 case POSIX_SPAWN_CLOSE :
5246- if (PySequence_Size (file_actions_obj ) != 2 ){
5242+ if (PySequence_Size (file_actions_obj ) != 2 ) {
52475243 PyErr_SetString (PyExc_TypeError ,"A close file_action object must have 2 elements" );
52485244 goto exit ;
52495245 }
52505246
5251- long close_fd = PyLong_AsLong (PySequence_GetItem (file_actions_obj , 1 ));
5252- if (PyErr_Occurred ()) {
5247+ int close_fd ;
5248+
5249+ if (!PyArg_ParseTuple (file_actions_obj , "ii" , & mode , & close_fd )) {
52535250 goto exit ;
52545251 }
5255- if (posix_spawn_file_actions_addclose (file_actionsp , close_fd )) {
5252+
5253+ if (posix_spawn_file_actions_addclose (file_actionsp , close_fd )) {
52565254 PyErr_SetString (PyExc_OSError ,"Failed to add close file action" );
52575255 goto exit ;
52585256 }
5257+
52595258 break ;
52605259
52615260 case POSIX_SPAWN_DUP2 :
5262- if (PySequence_Size (file_actions_obj ) != 3 ){
5261+ if (PySequence_Size (file_actions_obj ) != 3 ) {
52635262 PyErr_SetString (PyExc_TypeError ,"A dup2 file_action object must have 3 elements" );
52645263 goto exit ;
52655264 }
52665265
5267- long fd1 = PyLong_AsLong (PySequence_GetItem (file_actions_obj , 1 ));
5268- if (PyErr_Occurred ()) {
5269- goto exit ;
5270- }
5271- long fd2 = PyLong_AsLong (PySequence_GetItem (file_actions_obj , 2 ));
5272- if (PyErr_Occurred ()) {
5266+ int fd1 , fd2 ;
5267+
5268+ if (!PyArg_ParseTuple (file_actions_obj , "iii" , & mode , & fd1 , & fd2 )) {
52735269 goto exit ;
52745270 }
5275- if (posix_spawn_file_actions_adddup2 (file_actionsp , fd1 , fd2 )) {
5271+
5272+ if (posix_spawn_file_actions_adddup2 (file_actionsp , fd1 , fd2 )) {
52765273 PyErr_SetString (PyExc_OSError ,"Failed to add dup2 file action" );
52775274 goto exit ;
52785275 }
5276+
52795277 break ;
52805278
52815279 default :
5282- PyErr_SetString (PyExc_TypeError ,"Unknown file_actions identifier" );
5280+ PyErr_SetString (PyExc_ValueError ,"Unknown file_actions identifier" );
52835281 goto exit ;
52845282 }
5283+ Py_DECREF (file_actions_obj );
52855284 }
5285+ file_actions_obj = NULL ;
52865286 }
52875287
52885288 _Py_BEGIN_SUPPRESS_IPH
52895289 int err_code = posix_spawn (& pid , path -> narrow , file_actionsp , NULL , argvlist , envlist );
52905290 _Py_END_SUPPRESS_IPH
5291- if (err_code ) {
5291+ if (err_code ) {
52925292 PyErr_SetString (PyExc_OSError ,"posix_spawn call failed" );
52935293 goto exit ;
52945294 }
@@ -5297,11 +5297,12 @@ os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
52975297exit :
52985298
52995299 Py_XDECREF (seq );
5300+ Py_XDECREF (file_actions_obj );
53005301
5301- if (file_actionsp ) {
5302+ if (file_actionsp ) {
53025303 posix_spawn_file_actions_destroy (file_actionsp );
53035304 }
5304-
5305+
53055306 if (envlist ) {
53065307 free_string_array (envlist , envc );
53075308 }
0 commit comments