@@ -176,14 +176,6 @@ corresponding Unix manual entries for more information on calls.");
176
176
#else
177
177
/* Unix functions that the configure script doesn't check for */
178
178
#define HAVE_EXECV 1
179
- /* bpo-32705: Current Android does not have posix_spawn
180
- * Most likely posix_spawn will be available in next Android version (Android
181
- * P, API 28). Need revisit then. See
182
- * https://android-review.googlesource.com/c/platform/bionic/+/504842
183
- **/
184
- #ifndef __ANDROID__
185
- #define HAVE_POSIX_SPAWN 1
186
- #endif
187
179
#define HAVE_FORK 1
188
180
#if defined(__USLC__ ) && defined(__SCO_VERSION__ ) /* SCO UDK Compiler */
189
181
#define HAVE_FORK1 1
@@ -5139,17 +5131,22 @@ os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
5139
5131
/*[clinic end generated code: output=d023521f541c709c input=0ec9f1cfdc890be5]*/
5140
5132
{
5141
5133
EXECV_CHAR * * argvlist = NULL ;
5142
- EXECV_CHAR * * envlist ;
5134
+ EXECV_CHAR * * envlist = NULL ;
5135
+ posix_spawn_file_actions_t _file_actions ;
5136
+ posix_spawn_file_actions_t * file_actionsp = NULL ;
5143
5137
Py_ssize_t argc , envc ;
5138
+ PyObject * result = NULL ;
5139
+ PyObject * seq = NULL ;
5140
+
5144
5141
5145
5142
/* posix_spawn has three arguments: (path, argv, env), where
5146
5143
argv is a list or tuple of strings and env is a dictionary
5147
5144
like posix.environ. */
5148
5145
5149
- if (!PySequence_Check (argv )){
5146
+ if (!PySequence_Check (argv )) {
5150
5147
PyErr_SetString (PyExc_TypeError ,
5151
5148
"posix_spawn: argv must be a tuple or list" );
5152
- goto fail ;
5149
+ goto exit ;
5153
5150
}
5154
5151
argc = PySequence_Size (argv );
5155
5152
if (argc < 1 ) {
@@ -5160,50 +5157,47 @@ os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
5160
5157
if (!PyMapping_Check (env )) {
5161
5158
PyErr_SetString (PyExc_TypeError ,
5162
5159
"posix_spawn: environment must be a mapping object" );
5163
- goto fail ;
5160
+ goto exit ;
5164
5161
}
5165
5162
5166
5163
argvlist = parse_arglist (argv , & argc );
5167
5164
if (argvlist == NULL ) {
5168
- goto fail ;
5165
+ goto exit ;
5169
5166
}
5170
5167
if (!argvlist [0 ][0 ]) {
5171
5168
PyErr_SetString (PyExc_ValueError ,
5172
5169
"posix_spawn: argv first element cannot be empty" );
5173
- goto fail ;
5170
+ goto exit ;
5174
5171
}
5175
5172
5176
5173
envlist = parse_envlist (env , & envc );
5177
- if (envlist == NULL )
5178
- goto fail ;
5174
+ if (envlist == NULL ) {
5175
+ goto exit ;
5176
+ }
5179
5177
5180
5178
pid_t pid ;
5181
- posix_spawn_file_actions_t * file_actionsp = NULL ;
5182
- if (file_actions != NULL && file_actions != Py_None ){
5183
- posix_spawn_file_actions_t _file_actions ;
5179
+ if (file_actions != NULL && file_actions != Py_None ) {
5184
5180
if (posix_spawn_file_actions_init (& _file_actions ) != 0 ){
5185
- PyErr_SetString (PyExc_TypeError ,
5181
+ PyErr_SetString (PyExc_OSError ,
5186
5182
"Error initializing file actions" );
5187
- goto fail ;
5183
+ goto exit ;
5188
5184
}
5189
5185
5190
-
5191
5186
file_actionsp = & _file_actions ;
5192
5187
5193
-
5194
- PyObject * seq = PySequence_Fast (file_actions , "file_actions must be a sequence" );
5195
- if (seq == NULL ){
5196
- goto fail ;
5188
+ seq = PySequence_Fast (file_actions , "file_actions must be a sequence" );
5189
+ if (seq == NULL ) {
5190
+ goto exit ;
5197
5191
}
5198
5192
PyObject * file_actions_obj ;
5199
5193
PyObject * mode_obj ;
5200
5194
5201
5195
for (int i = 0 ; i < PySequence_Fast_GET_SIZE (seq ); ++ i ) {
5202
5196
file_actions_obj = PySequence_Fast_GET_ITEM (seq , i );
5203
5197
5204
- if (!PySequence_Check (file_actions_obj ) | !PySequence_Size (file_actions_obj )){
5198
+ if (!PySequence_Check (file_actions_obj ) | !PySequence_Size (file_actions_obj )) {
5205
5199
PyErr_SetString (PyExc_TypeError ,"Each file_action element must be a non empty sequence" );
5206
- goto fail ;
5200
+ goto exit ;
5207
5201
}
5208
5202
5209
5203
@@ -5215,83 +5209,103 @@ os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
5215
5209
switch (mode ) {
5216
5210
5217
5211
case POSIX_SPAWN_OPEN :
5218
- if (PySequence_Size (file_actions_obj ) != 5 ){
5212
+ if (PySequence_Size (file_actions_obj ) != 5 ) {
5219
5213
PyErr_SetString (PyExc_TypeError ,"A open file_action object must have 5 elements" );
5220
- goto fail ;
5214
+ goto exit ;
5221
5215
}
5222
5216
5223
5217
long open_fd = PyLong_AsLong (PySequence_GetItem (file_actions_obj , 1 ));
5224
5218
if (PyErr_Occurred ()) {
5225
- goto fail ;
5219
+ goto exit ;
5226
5220
}
5227
5221
const char * open_path = PyUnicode_AsUTF8 (PySequence_GetItem (file_actions_obj , 2 ));
5228
- if (open_path == NULL ){
5229
- goto fail ;
5222
+ if (open_path == NULL ) {
5223
+ goto exit ;
5230
5224
}
5231
5225
long open_oflag = PyLong_AsLong (PySequence_GetItem (file_actions_obj , 3 ));
5232
5226
if (PyErr_Occurred ()) {
5233
- goto fail ;
5227
+ goto exit ;
5234
5228
}
5235
5229
long open_mode = PyLong_AsLong (PySequence_GetItem (file_actions_obj , 4 ));
5236
5230
if (PyErr_Occurred ()) {
5237
- goto fail ;
5231
+ goto exit ;
5232
+ }
5233
+ if (posix_spawn_file_actions_addopen (file_actionsp , open_fd , open_path , open_oflag , open_mode )) {
5234
+ PyErr_SetString (PyExc_OSError ,"Failed to add open file action" );
5235
+ goto exit ;
5238
5236
}
5239
- posix_spawn_file_actions_addopen ( file_actionsp , open_fd , open_path , open_oflag , open_mode );
5237
+
5240
5238
break ;
5241
5239
5242
5240
case POSIX_SPAWN_CLOSE :
5243
5241
if (PySequence_Size (file_actions_obj ) != 2 ){
5244
5242
PyErr_SetString (PyExc_TypeError ,"A close file_action object must have 2 elements" );
5245
- goto fail ;
5243
+ goto exit ;
5246
5244
}
5247
5245
5248
5246
long close_fd = PyLong_AsLong (PySequence_GetItem (file_actions_obj , 1 ));
5249
5247
if (PyErr_Occurred ()) {
5250
- goto fail ;
5248
+ goto exit ;
5249
+ }
5250
+ if (posix_spawn_file_actions_addclose (file_actionsp , close_fd )) {
5251
+ PyErr_SetString (PyExc_OSError ,"Failed to add close file action" );
5252
+ goto exit ;
5251
5253
}
5252
- posix_spawn_file_actions_addclose (file_actionsp , close_fd );
5253
5254
break ;
5254
5255
5255
5256
case POSIX_SPAWN_DUP2 :
5256
5257
if (PySequence_Size (file_actions_obj ) != 3 ){
5257
5258
PyErr_SetString (PyExc_TypeError ,"A dup2 file_action object must have 3 elements" );
5258
- goto fail ;
5259
+ goto exit ;
5259
5260
}
5260
5261
5261
5262
long fd1 = PyLong_AsLong (PySequence_GetItem (file_actions_obj , 1 ));
5262
5263
if (PyErr_Occurred ()) {
5263
- goto fail ;
5264
+ goto exit ;
5264
5265
}
5265
5266
long fd2 = PyLong_AsLong (PySequence_GetItem (file_actions_obj , 2 ));
5266
5267
if (PyErr_Occurred ()) {
5267
- goto fail ;
5268
+ goto exit ;
5269
+ }
5270
+ if (posix_spawn_file_actions_adddup2 (file_actionsp , fd1 , fd2 )) {
5271
+ PyErr_SetString (PyExc_OSError ,"Failed to add dup2 file action" );
5272
+ goto exit ;
5268
5273
}
5269
- posix_spawn_file_actions_adddup2 (file_actionsp , fd1 , fd2 );
5270
5274
break ;
5271
5275
5272
5276
default :
5273
5277
PyErr_SetString (PyExc_TypeError ,"Unknown file_actions identifier" );
5274
- goto fail ;
5278
+ goto exit ;
5275
5279
}
5276
5280
}
5277
- Py_DECREF (seq );
5278
- }
5281
+ }
5279
5282
5280
5283
_Py_BEGIN_SUPPRESS_IPH
5281
- posix_spawn (& pid , path -> narrow , file_actionsp , NULL , argvlist , envlist );
5282
- return PyLong_FromPid (pid );
5284
+ int err_code = posix_spawn (& pid , path -> narrow , file_actionsp , NULL , argvlist , envlist );
5283
5285
_Py_END_SUPPRESS_IPH
5286
+ if (err_code ) {
5287
+ PyErr_SetString (PyExc_OSError ,"posix_spawn call failed" );
5288
+ goto exit ;
5289
+ }
5290
+ result = PyLong_FromPid (pid );
5284
5291
5285
- path_error ( path );
5292
+ exit :
5286
5293
5287
- free_string_array ( envlist , envc );
5294
+ Py_XDECREF ( seq );
5288
5295
5289
- fail :
5296
+ if (file_actionsp ) {
5297
+ posix_spawn_file_actions_destroy (file_actionsp );
5298
+ }
5299
+
5300
+ if (envlist ) {
5301
+ free_string_array (envlist , envc );
5302
+ }
5290
5303
5291
5304
if (argvlist ) {
5292
5305
free_string_array (argvlist , argc );
5293
5306
}
5294
- return NULL ;
5307
+
5308
+ return result ;
5295
5309
5296
5310
5297
5311
}
0 commit comments