152 lines
		
	
	
	
		
			3.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			152 lines
		
	
	
	
		
			3.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
 | |
|  * See the copyright notice in the ACK home directory, in the file "Copyright".
 | |
|  *
 | |
|  */
 | |
| 
 | |
| #include <stdlib.h>
 | |
| #include <string.h>
 | |
| #include "ack.h"
 | |
| #include "list.h"
 | |
| #include "trans.h"
 | |
| #include "grows.h"
 | |
| #include "data.h"
 | |
| #include <signal.h>
 | |
| 
 | |
| #ifndef NORCSID
 | |
| static char rcs_id[] = "$Id$" ;
 | |
| #endif
 | |
| 
 | |
| #define ARG_MORE  40            /* The size of args chunks to allocate */
 | |
| 
 | |
| extern growstring scanvars();
 | |
| 
 | |
| static char      **arglist ;    /* The first argument */
 | |
| static unsigned  argcount ;     /* The current number of arguments */
 | |
| static unsigned  argmax;        /* The maximum number of arguments so far */
 | |
| 
 | |
| int runphase(phase) register trf *phase ; {
 | |
| 	register list_elem *elem ;
 | |
|       char *prog ; int result ;
 | |
|       growstring bline ;
 | |
| 
 | |
|       bline=scanvars(phase->t_prog) ;
 | |
|       prog=gr_final(&bline) ;
 | |
| 	if ( v_flag || debug ) {
 | |
| 		if ( v_flag==1 && !debug ) {
 | |
| 			vprint("%s",phase->t_name) ;
 | |
| 			if ( !phase->t_combine ) {
 | |
| 				vprint(" %s%s\n",p_basename,
 | |
| 					strrchr(in.p_path,SUFCHAR) ) ;
 | |
| 			} else {
 | |
| 				scanlist(l_first(phase->t_inputs), elem) {
 | |
| 					vprint(" %s",p_cont(*elem)->p_path);
 | |
| 				}
 | |
| 				vprint("\n") ;
 | |
| 			}
 | |
| 		} else {
 | |
| 			/* list all args */
 | |
|                       vprint("%s",prog) ;
 | |
| 			scanlist(l_first(phase->t_flags), elem) {
 | |
| 				vprint(" %s",l_content(*elem)) ;
 | |
| 			}
 | |
| 			scanlist(l_first(phase->t_args), elem) {
 | |
| 				vprint(" %s",l_content(*elem)) ;
 | |
| 			}
 | |
| 			vprint("\n") ;
 | |
| 		}
 | |
| 	}
 | |
| 	argcount=0 ;
 | |
| 	x_arg(phase->t_name) ;
 | |
| 	scanlist(l_first(phase->t_flags), elem) {
 | |
| 		x_arg(l_content(*elem)) ;
 | |
| 	}
 | |
| 	scanlist(l_first(phase->t_args), elem) {
 | |
| 		x_arg(l_content(*elem)) ;
 | |
| 	}
 | |
| 	x_arg( (char *)0 ) ;
 | |
|       result=run_exec(phase,prog) ;
 | |
|       throws(prog) ;
 | |
|       return result ;
 | |
| }
 | |
| 
 | |
| int run_exec(phase,prog) trf *phase ; char *prog ; {
 | |
| 	int status, child, waitchild ;
 | |
| 
 | |
| 	do_flush();
 | |
| 	while ( (child=fork())== -1 ) ;
 | |
| 	if ( child ) {
 | |
| 		/* The parent */
 | |
| 		do {
 | |
| 			waitchild= wait(&status) ;
 | |
| 			if ( waitchild== -1 ) {
 | |
| 				fatal("missing child") ;
 | |
| 			}
 | |
| 		} while ( waitchild!=child) ;
 | |
| 		if ( status ) {
 | |
| 			if ( status&0200 && (status&0177)!=SIGQUIT &&
 | |
| 				t_flag<=1 ) unlink("core") ;
 | |
| 			switch ( status&0177 ) {
 | |
| 			case 0 :
 | |
| 				break ;
 | |
| 			case SIGHUP:
 | |
| 			case SIGINT:
 | |
| 			case SIGQUIT:
 | |
| 			case SIGTERM:
 | |
| 				quit(-5) ;
 | |
| 			default:
 | |
| 				error("%s died with signal %d",
 | |
|                                       prog,status&0177) ;
 | |
| 			}
 | |
| 			/* The assumption is that processes voluntarely
 | |
| 			   dying with a non-zero status already produced
 | |
| 			   some sort of error message to the outside world.
 | |
| 			*/
 | |
| 			n_error++ ;
 | |
| 			return 0 ;
 | |
| 		}
 | |
| 		return 1 ; /* From the parent */
 | |
| 	}
 | |
| 	/* 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*/
 | |
| }
 | |
| 
 | |
| x_arg(string) char *string ; {
 | |
| 	/* Add one execute argument to the argument vector */
 | |
| 	if ( argcount==argmax ) {
 | |
| 		if ( argmax==0 ) {
 | |
| 			argmax= 2*ARG_MORE ;
 | |
| 			arglist= (char **)getcore(argmax*sizeof (char *)) ;
 | |
| 		} else {
 | |
| 			argmax += ARG_MORE ;
 | |
| 			arglist= (char **)changecore((char *)arglist,
 | |
| 					argmax*sizeof (char *)) ;
 | |
| 		}
 | |
| 	}
 | |
| 	*(arglist+argcount++) = string ;
 | |
| }
 |