@@ -155,7 +155,7 @@ static void update_all_child_statuses () {
155
155
//NOTE: curr->next is retrieved preemptively because
156
156
//update_child_status may call free() on curr, and make
157
157
//curr->next inaccessible.
158
- ChildProcessList * next = curr -> next ;
158
+ volatile ChildProcessList * next = curr -> next ;
159
159
update_child_status (curr -> proc -> pid );
160
160
curr = next ;
161
161
}
@@ -458,28 +458,24 @@ stz_int launch_process(stz_byte* file, stz_byte** argvs, stz_int input,
458
458
stz_int output , stz_int error ,
459
459
stz_byte * working_dir , stz_byte * * env_vars , Process * process ) {
460
460
461
- //Compute pipe sources. Examples of entries:
462
- // pipe_sources[PROCESS_IN] = 0, indicates that
463
- // the input pipe to the process is served by POSIX file descriptor 0 (stdin).
464
- // pipe_sources[PROCESS_IN] = -1, indicates that
465
- // no input pipe to the process should be created.
466
- // pipe_sources[STANDARD_ERR] = 1, indicates that
467
- // the process standard error stream should be served by POSIX file descriptor 1 (stdout),
468
- // which means child writes to its error stream should automatically go to stdout.
469
- int pipe_sources [NUM_STREAM_SPECS ];
461
+ //Compute which pipes to create for the process.
462
+ //has_pipes[PROCESS_IN] = 1, indicates that a process input pipe
463
+ //needs to be created.
464
+ int has_pipes [NUM_STREAM_SPECS ];
470
465
for (int i = 0 ; i < NUM_STREAM_SPECS ; i ++ )
471
- pipe_sources [i ] = -1 ;
472
- pipe_sources [input ] = 0 ;
473
- pipe_sources [output ] = 1 ;
474
- pipe_sources [error ] = 2 ;
466
+ has_pipes [i ] = 0 ;
467
+ has_pipes [input ] = 1 ;
468
+ has_pipes [output ] = 1 ;
469
+ has_pipes [error ] = 1 ;
470
+ has_pipes [STANDARD_IN ] = 0 ;
471
+ has_pipes [STANDARD_OUT ] = 0 ;
472
+ has_pipes [STANDARD_ERR ] = 0 ;
475
473
476
474
//Generate pipes for PROCESS_IN, PROCESS_OUT, PROCESS_ERR.
477
475
int pipes [NUM_STREAM_SPECS ][2 ];
478
- int process_io [] = {PROCESS_IN , PROCESS_OUT , PROCESS_ERR };
479
- for (int i = 0 ; i < 3 ; i ++ )
480
- if (pipe_sources [process_io [i ]] >= 0 )
481
- if (pipe (pipes [process_io [i ]]))
482
- return -1 ;
476
+ for (int i = 0 ; i < NUM_STREAM_SPECS ; i ++ )
477
+ if (has_pipes [i ])
478
+ if (pipe (pipes [i ])) return -1 ;
483
479
484
480
// Fork child process
485
481
stz_long pid = (stz_long )vfork ();
@@ -493,19 +489,19 @@ stz_int launch_process(stz_byte* file, stz_byte** argvs, stz_int input,
493
489
494
490
//Set up the pipes in the parent process.
495
491
FILE * fin = NULL ;
496
- if (pipe_sources [PROCESS_IN ] >= 0 ) {
492
+ if (has_pipes [PROCESS_IN ]) {
497
493
close (pipes [PROCESS_IN ][0 ]);
498
494
fin = fdopen (pipes [PROCESS_IN ][1 ], "w" );
499
495
if (fin == NULL ) goto return_error ;
500
496
}
501
497
FILE * fout = NULL ;
502
- if (pipe_sources [PROCESS_OUT ] >= 0 ) {
498
+ if (has_pipes [PROCESS_OUT ]) {
503
499
close (pipes [PROCESS_OUT ][1 ]);
504
500
fout = fdopen (pipes [PROCESS_OUT ][0 ], "r" );
505
501
if (fout == NULL ) goto return_error ;
506
502
}
507
503
FILE * ferr = NULL ;
508
- if (pipe_sources [PROCESS_ERR ] >= 0 ) {
504
+ if (has_pipes [PROCESS_ERR ]) {
509
505
close (pipes [PROCESS_ERR ][1 ]);
510
506
ferr = fdopen (pipes [PROCESS_ERR ][0 ], "r" );
511
507
if (ferr == NULL ) goto return_error ;
@@ -521,59 +517,47 @@ stz_int launch_process(stz_byte* file, stz_byte** argvs, stz_int input,
521
517
//repeated by the autoreap handler.
522
518
register_child_process (pid , fin , fout , ferr , & (process -> status ));
523
519
520
+ //Child process successfully launched and registered.
521
+ goto return_success ;
522
+
524
523
//Perform cleanup and return -1 to indicate error.
525
524
return_error : {
526
525
restore_signal_mask (& old_signal_mask );
527
526
return -1 ;
528
527
}
529
528
530
529
//Perform cleanup and return 0 to indicate success.
531
- return_success :{
530
+ return_success : {
532
531
restore_signal_mask (& old_signal_mask );
533
532
return 0 ;
534
533
}
535
534
}
536
535
537
536
// Child: setup pipes, exec
538
537
else {
539
- //Redirect stdout if necessary
540
- {
541
- int i = STANDARD_OUT ;
542
- if (pipe_sources [i ] >= 0 && pipe_sources [i ] != STDOUT_FILENO )
543
- if (dup2 (STDOUT_FILENO , pipe_sources [i ]) < 0 ) exit (-1 );
544
- }
545
- //Redirect stderr if necessary
546
- {
547
- int i = STANDARD_ERR ;
548
- if (pipe_sources [i ] >= 0 && pipe_sources [i ] != STDERR_FILENO )
549
- if (dup2 (STDERR_FILENO , pipe_sources [i ]) < 0 ) exit (-1 );
550
- }
551
- //Setup input pipe if used
552
- {
553
- int i = PROCESS_IN ;
554
- if (pipe_sources [i ] >= 0 ) {
555
- if (close (pipes [i ][1 ]) < 0 ) exit (-1 );
556
- if (dup2 (pipes [i ][0 ], pipe_sources [i ]) < 0 ) exit (-1 );
557
- if (close (pipes [i ][0 ]) < 0 ) exit (-1 );
558
- }
538
+ //Connect process input pipe if necessary.
539
+ if (has_pipes [PROCESS_IN ]){
540
+ if (close (pipes [PROCESS_IN ][1 ]) < 0 ) exit (-1 );
541
+ if (dup2 (pipes [PROCESS_IN ][0 ], STDIN_FILENO ) < 0 ) exit (-1 );
542
+ if (close (pipes [PROCESS_IN ][0 ]) < 0 ) exit (-1 );
559
543
}
560
- //Setup output pipe if used
561
- {
562
- int i = PROCESS_OUT ;
563
- if (pipe_sources [ i ] >= 0 ) {
564
- if (close (pipes [i ][ 0 ] ) < 0 ) exit (-1 );
565
- if (dup2 ( pipes [ i ][ 1 ], pipe_sources [ i ]) < 0 ) exit ( -1 );
566
- if (close (pipes [i ][1 ]) < 0 ) exit (-1 );
567
- }
544
+ //Connect process output pipe if necessary.
545
+ if ( has_pipes [ PROCESS_OUT ]) {
546
+ if ( close ( pipes [ PROCESS_OUT ][ 0 ]) < 0 ) exit ( -1 ) ;
547
+ if (output == PROCESS_OUT )
548
+ if (dup2 (pipes [PROCESS_OUT ][ 1 ], STDOUT_FILENO ) < 0 ) exit (-1 );
549
+ if (error == PROCESS_OUT )
550
+ if (dup2 (pipes [PROCESS_OUT ][1 ], STDERR_FILENO ) < 0 ) exit (-1 );
551
+ if ( close ( pipes [ PROCESS_OUT ][ 1 ]) < 0 ) exit ( -1 );
568
552
}
569
- //Setup error pipe if used
570
- {
571
- int i = PROCESS_ERR ;
572
- if (pipe_sources [ i ] >= 0 ) {
573
- if (close (pipes [i ][ 0 ] ) < 0 ) exit (-1 );
574
- if (dup2 ( pipes [ i ][ 1 ], pipe_sources [ i ]) < 0 ) exit ( -1 );
575
- if (close (pipes [i ][1 ]) < 0 ) exit (-1 );
576
- }
553
+ //Connect process error pipe if necessary.
554
+ if ( has_pipes [ PROCESS_ERR ]) {
555
+ if ( close ( pipes [ PROCESS_ERR ][ 0 ]) < 0 ) exit ( -1 ) ;
556
+ if (output == PROCESS_ERR )
557
+ if (dup2 (pipes [PROCESS_ERR ][ 1 ], STDOUT_FILENO ) < 0 ) exit (-1 );
558
+ if (error == PROCESS_ERR )
559
+ if (dup2 (pipes [PROCESS_ERR ][1 ], STDERR_FILENO ) < 0 ) exit (-1 );
560
+ if ( close ( pipes [ PROCESS_ERR ][ 1 ]) < 0 ) exit ( -1 );
577
561
}
578
562
579
563
//Setup working directory
0 commit comments