@@ -851,19 +851,19 @@ static VALUE
851
851
detach_process_watcher (arg )
852
852
void * arg ;
853
853
{
854
- int pid = (int )arg , status ;
854
+ int pid = (int )( VALUE ) arg , status ;
855
855
856
856
while (rb_waitpid (pid , & status , WNOHANG ) == 0 ) {
857
857
rb_thread_sleep (1 );
858
858
}
859
- return Qnil ;
859
+ return rb_last_status ;
860
860
}
861
861
862
862
VALUE
863
863
rb_detach_process (pid )
864
864
int pid ;
865
865
{
866
- return rb_thread_create (detach_process_watcher , (void * )pid );
866
+ return rb_thread_create (detach_process_watcher , (void * )( VALUE ) pid );
867
867
}
868
868
869
869
@@ -882,6 +882,11 @@ rb_detach_process(pid)
882
882
* terminate. <code>detach</code> only checks the status
883
883
* periodically (currently once each second).
884
884
*
885
+ * The waiting thread returns the exit status of the detached process
886
+ * when it terminates, so you can use <code>Thread#join</code> to
887
+ * know the result. If specified _pid_ is not a valid child process
888
+ * ID, the thread returns +nil+ immediately.
889
+ *
885
890
* In this first example, we don't reap the first child process, so
886
891
* it appears as a zombie in the process status display.
887
892
*
@@ -1069,8 +1074,8 @@ rb_proc_exec(str)
1069
1074
a = argv = ALLOCA_N (char * , (s - str )/2 + 2 );
1070
1075
ss = ALLOCA_N (char , s - str + 1 );
1071
1076
strcpy (ss , str );
1072
- if (* a ++ = strtok (ss , " \t" )) {
1073
- while (t = strtok (NULL , " \t" )) {
1077
+ if (( * a ++ = strtok (ss , " \t" )) != 0 ) {
1078
+ while (( t = strtok (NULL , " \t" )) != 0 ) {
1074
1079
* a ++ = t ;
1075
1080
}
1076
1081
* a = NULL ;
@@ -1189,6 +1194,53 @@ proc_spawn(sv)
1189
1194
#endif
1190
1195
#endif
1191
1196
1197
+ struct rb_exec_arg {
1198
+ int argc ;
1199
+ VALUE * argv ;
1200
+ VALUE prog ;
1201
+ };
1202
+
1203
+ static void
1204
+ proc_prepare_args (e , argc , argv , prog )
1205
+ struct rb_exec_arg * e ;
1206
+ int argc ;
1207
+ VALUE * argv ;
1208
+ VALUE prog ;
1209
+ {
1210
+ int i ;
1211
+
1212
+ MEMZERO (e , struct rb_exec_arg , 1 );
1213
+ if (prog ) {
1214
+ SafeStringValue (prog );
1215
+ StringValueCStr (prog );
1216
+ }
1217
+ for (i = 0 ; i < argc ; i ++ ) {
1218
+ SafeStringValue (argv [i ]);
1219
+ StringValueCStr (argv [i ]);
1220
+ }
1221
+ security (RSTRING (prog ? prog : argv [0 ])-> ptr );
1222
+ e -> prog = prog ;
1223
+ e -> argc = argc ;
1224
+ e -> argv = argv ;
1225
+ }
1226
+
1227
+ static VALUE
1228
+ proc_exec_args (earg )
1229
+ VALUE earg ;
1230
+ {
1231
+ struct rb_exec_arg * e = (struct rb_exec_arg * )earg ;
1232
+ int argc = e -> argc ;
1233
+ VALUE * argv = e -> argv ;
1234
+ VALUE prog = e -> prog ;
1235
+
1236
+ if (argc == 1 && prog == 0 ) {
1237
+ return (VALUE )rb_proc_exec (RSTRING (argv [0 ])-> ptr );
1238
+ }
1239
+ else {
1240
+ return (VALUE )proc_exec_n (argc , argv , prog );
1241
+ }
1242
+ }
1243
+
1192
1244
/*
1193
1245
* call-seq:
1194
1246
* exec(command [, arg, ...])
@@ -1221,8 +1273,10 @@ rb_f_exec(argc, argv)
1221
1273
{
1222
1274
VALUE prog = 0 ;
1223
1275
VALUE tmp ;
1276
+ struct rb_exec_arg earg ;
1224
1277
1225
1278
if (argc == 0 ) {
1279
+ rb_last_status = Qnil ;
1226
1280
rb_raise (rb_eArgError , "wrong number of arguments" );
1227
1281
}
1228
1282
@@ -1235,15 +1289,8 @@ rb_f_exec(argc, argv)
1235
1289
argv [0 ] = RARRAY (tmp )-> ptr [1 ];
1236
1290
SafeStringValue (prog );
1237
1291
}
1238
- if (argc == 1 && prog == 0 ) {
1239
- VALUE cmd = argv [0 ];
1240
-
1241
- SafeStringValue (cmd );
1242
- rb_proc_exec (RSTRING (cmd )-> ptr );
1243
- }
1244
- else {
1245
- proc_exec_n (argc , argv , prog );
1246
- }
1292
+ proc_prepare_args (& earg , argc , argv , prog );
1293
+ proc_exec_args ((VALUE )& earg );
1247
1294
rb_sys_fail (RSTRING (argv [0 ])-> ptr );
1248
1295
return Qnil ; /* dummy */
1249
1296
}
@@ -1500,7 +1547,7 @@ rb_f_system(argc, argv)
1500
1547
#else
1501
1548
volatile VALUE prog = 0 ;
1502
1549
int pid ;
1503
- int i ;
1550
+ struct rb_exec_arg earg ;
1504
1551
RETSIGTYPE (* chfunc )(int );
1505
1552
1506
1553
fflush (stdout );
@@ -1517,25 +1564,15 @@ rb_f_system(argc, argv)
1517
1564
prog = RARRAY (argv [0 ])-> ptr [0 ];
1518
1565
argv [0 ] = RARRAY (argv [0 ])-> ptr [1 ];
1519
1566
}
1567
+ proc_prepare_args (& earg , argc , argv , prog );
1520
1568
1521
- if (prog ) {
1522
- SafeStringValue (prog );
1523
- }
1524
- for (i = 0 ; i < argc ; i ++ ) {
1525
- SafeStringValue (argv [i ]);
1526
- }
1527
- security (RSTRING (prog ? prog : argv [0 ])-> ptr );
1528
1569
chfunc = signal (SIGCHLD , SIG_DFL );
1529
1570
retry :
1530
1571
pid = fork ();
1531
1572
if (pid == 0 ) {
1532
1573
/* child process */
1533
- if (argc == 1 && prog == 0 ) {
1534
- rb_proc_exec (RSTRING (argv [0 ])-> ptr );
1535
- }
1536
- else {
1537
- proc_exec_n (argc , argv , prog );
1538
- }
1574
+ rb_thread_atfork ();
1575
+ rb_protect (proc_exec_args , (VALUE )& earg , NULL );
1539
1576
_exit (127 );
1540
1577
}
1541
1578
if (pid < 0 ) {
0 commit comments