Use system() rather than fork()/wait() to run commands, to keep Windows happy.

This commit is contained in:
David Given 2022-07-16 22:33:29 +02:00
parent f6d83620c0
commit d48e7399ee

View file

@ -4,7 +4,6 @@
* *
*/ */
#include <sys/wait.h>
#include <fcntl.h> #include <fcntl.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
@ -72,23 +71,90 @@ int runphase(trf *phase) {
return result ; return result ;
} }
static char* build_command_line(const char* prog)
{
/* Calculate the maximum length of the command line. */
int len = strlen(prog);
for (int i=1; i<(argcount-1); i++)
len += strlen(arglist[i])*2 + 1;
/* Now actually build the command line. */
char* cmdline = malloc(len + 1);
strcpy(cmdline, prog);
char* p = cmdline + strlen(prog);
for (int i=1; i<(argcount-1); i++)
{
const char* word = arglist[i];
*p++ = ' ';
for (;;)
{
char c = *word++;
if (!c)
break;
if ((c == ' ') || (c == '\"') || (c == '\''))
*p++ = '\\';
*p++ = c;
}
}
*p = 0;
return cmdline;
}
static int run_exec(trf *phase, const char *prog) { static int run_exec(trf *phase, const char *prog) {
int status, child, waitchild ; int status, child, waitchild ;
int oldstdin = -1;
int oldstdout = -1;
fflush(stdout) ; fflush(stdout) ;
fflush(stderr) ; fflush(stderr) ;
child= fork() ;
if ( child== - 1) { if ( phase->t_stdin ) {
fatal("Cannot fork %s", prog) ; if (!in.p_path)
fatal("no input file for %s",phase->t_name) ;
oldstdin = dup(0);
close(0) ;
if (open(in.p_path,0)!=0) {
error("cannot open %s",in.p_path) ;
exit(1) ;
} }
if ( child ) {
/* The parent */
do {
waitchild= wait(&status) ;
if ( waitchild== -1 ) {
fatal("missing child") ;
} }
} while ( waitchild!=child) ;
if ( phase->t_stdout ) {
if ( !out.p_path ) {
fatal("no output file for %s",phase->t_name) ;
}
oldstdout = dup(1);
close(1) ;
if ( creat(out.p_path,0666)!=1 ) {
close(1); dup(2);
error("cannot create %s",out.p_path) ;
exit(1) ;
}
}
char* cmdline = build_command_line(prog);
status = system(cmdline);
free(cmdline);
if ( oldstdin != -1 ) {
close(0);
dup2(oldstdin, 0);
close(oldstdin);
}
if ( oldstdout != -1 ) {
close(1);
dup2(oldstdout, 1);
close(oldstdout);
}
if ( status ) { if ( status ) {
switch ( status&0177 ) { switch ( status&0177 ) {
case 0 : case 0 :
@ -107,37 +173,9 @@ static int run_exec(trf *phase, const char *prog) {
some sort of error message to the outside world. some sort of error message to the outside world.
*/ */
n_error++ ; n_error++ ;
return 0 ; return 0;
} }
return 1 ; /* From the parent */ return 1 ;
}
/* The child */
if ( phase->t_stdin ) {
if ( !in.p_path ) {
fatal("no input file for %s",phase->t_name) ;
}
close(0) ;
if ( open(in.p_path,0)!=0 ) {
error("cannot open %s",in.p_path) ;
exit(1) ;
}
}
if ( phase->t_stdout ) {
if ( !out.p_path ) {
fatal("no output file for %s",phase->t_name) ;
}
close(1) ;
if ( creat(out.p_path,0666)!=1 ) {
close(1); dup(2);
error("cannot create %s",out.p_path) ;
exit(1) ;
}
}
execv(prog,arglist) ;
if ( phase->t_stdout ) { close(1) ; dup(2) ; }
error("Cannot execute %s",prog) ;
exit(1) ;
/*NOTREACHED*/
} }
static void x_arg(char *string) { static void x_arg(char *string) {