⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 execunix.c

📁 Boost provides free peer-reviewed portable C++ source libraries. We emphasize libraries that work
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright 1993, 1995 Christopher Seiwald. * Copyright 2007 Noel Belcourt. * * This file is part of Jam - see jam.c for Copyright information. */# include "jam.h"# include "lists.h"# include "execcmd.h"# include "output.h"# include <errno.h># include <signal.h># include <stdio.h># include <time.h># include <unistd.h> /* needed for vfork(), _exit() prototypes */# include <sys/resource.h># include <sys/times.h># include <sys/wait.h>#if defined(sun) || defined(__sun) || defined(linux)#include <wait.h>#endif# ifdef USE_EXECUNIX# include <sys/times.h># ifdef NO_VFORK# define vfork() fork()# endif/* * execunix.c - execute a shell script on UNIX/WinNT/OS2/AmigaOS * * If $(JAMSHELL) is defined, uses that to formulate execvp()/spawnvp(). * The default is: * *	/bin/sh -c %		[ on UNIX/AmigaOS ] *	cmd.exe /c %		[ on OS2/WinNT ] * * Each word must be an individual element in a jam variable value. * * In $(JAMSHELL), % expands to the command string and ! expands to  * the slot number (starting at 1) for multiprocess (-j) invocations. * If $(JAMSHELL) doesn't include a %, it is tacked on as the last * argument. * * Don't just set JAMSHELL to /bin/sh or cmd.exe - it won't work! * * External routines: *	execcmd() - launch an async command execution * 	execwait() - wait and drive at most one execution completion * * Internal routines: *	onintr() - bump intr to note command interruption * * 04/08/94 (seiwald) - Coherent/386 support added. * 05/04/94 (seiwald) - async multiprocess interface * 01/22/95 (seiwald) - $(JAMSHELL) support * 06/02/97 (gsar)    - full async multiprocess support for Win32 */static clock_t tps = 0;static struct timeval tv;static int select_timeout = 0;static int intr = 0;static int cmdsrunning = 0;static struct tms old_time;#define OUT 0#define ERR 1static struct{    int	    pid;              /* on win32, a real process handle */    int     fd[2];            /* file descriptors for stdout and stderr */    FILE   *stream[2];        /* child's stdout (0) and stderr (1) file stream */    clock_t start_time;       /* start time of child process */    int     exit_reason;      /* termination status */    int     action_length;    /* length of action string */    int     target_length;    /* length of target string */    char   *action;           /* buffer to hold action and target invoked */    char   *target;           /* buffer to hold action and target invoked */    char   *command;          /* buffer to hold command being invoked */    char   *buffer[2];        /* buffer to hold stdout and stderr, if any */    void    (*func)( void *closure, int status, timing_info*, char *, char * );    void   *closure;    time_t  start_dt;         /* start of command timestamp */} cmdtab[ MAXJOBS ] = {{0}};/* * onintr() - bump intr to note command interruption */voidonintr( int disp ){	intr++;	printf( "...interrupted\n" );}/* * execcmd() - launch an async command execution */voidexeccmd( 	char *string,	void (*func)( void *closure, int status, timing_info*, char *, char * ),	void *closure,	LIST *shell,        char *action,        char *target ){        static int initialized = 0;        int out[2], err[2];	int slot, len;	char *argv[ MAXARGC + 1 ];	/* +1 for NULL */	/* Find a slot in the running commands table for this one. */	for( slot = 0; slot < MAXJOBS; slot++ )	    if( !cmdtab[ slot ].pid )		break;	if( slot == MAXJOBS )	{	    printf( "no slots for child!\n" );	    exit( EXITBAD );	}	/* Forumulate argv */	/* If shell was defined, be prepared for % and ! subs. */	/* Otherwise, use stock /bin/sh (on unix) or cmd.exe (on NT). */	if( shell )	{	    int i;	    char jobno[4];	    int gotpercent = 0;	    sprintf( jobno, "%d", slot + 1 );	    for( i = 0; shell && i < MAXARGC; i++, shell = list_next( shell ) )	    {		switch( shell->string[0] )		{		case '%':	argv[i] = string; gotpercent++; break;		case '!':	argv[i] = jobno; break;		default:	argv[i] = shell->string;		}		if( DEBUG_EXECCMD )		    printf( "argv[%d] = '%s'\n", i, argv[i] );	    }	    if( !gotpercent )		argv[i++] = string;	    argv[i] = 0;	}	else	{	    argv[0] = "/bin/sh";	    argv[1] = "-c";	    argv[2] = string;	    argv[3] = 0;	}	/* increment jobs running */	++cmdsrunning;        /* save off actual command string */        cmdtab[ slot ].command = BJAM_MALLOC_ATOMIC(strlen(string)+1);        strcpy(cmdtab[slot].command, string);        /* initialize only once */        if ( ! initialized ) {          times(&old_time);          initialized = 1;        }        /* create pipe from child to parent */        if (pipe(out) < 0)            exit(EXITBAD);        fcntl(out[0], F_SETFL, O_NONBLOCK);        fcntl(out[1], F_SETFL, O_NONBLOCK);        if (pipe(err) < 0)            exit(EXITBAD);        fcntl(err[0], F_SETFL, O_NONBLOCK);        fcntl(err[1], F_SETFL, O_NONBLOCK);	/* Start the command */        cmdtab[ slot ].start_dt = time(0);        if (0 < globs.timeout) {            /*              * handle hung processes by manually tracking elapsed              * time and signal process when time limit expires             */            struct tms buf;            cmdtab[ slot ].start_time = times(&buf);            /* make a global, only do this once */            if (tps == 0) tps = sysconf(_SC_CLK_TCK);                        }	if ((cmdtab[slot].pid = vfork()) == 0)    	{            close(out[0]);            close(err[0]);            dup2(out[1], STDOUT_FILENO);            if (globs.pipe_action == 0)            {                dup2(out[1], STDERR_FILENO);                close(err[1]);            }            else                dup2(err[1], STDERR_FILENO);            /* Make this process a process group leader             * so that when we kill it, all child             * processes of this process are terminated             * as well.             *             * we use killpg(pid, SIGKILL) to kill the             * process group leader and all its children.             */             if (0 < globs.timeout)             {                struct rlimit r_limit;                r_limit.rlim_cur = globs.timeout;                r_limit.rlim_max = globs.timeout;                setrlimit(RLIMIT_CPU, &r_limit);            }            setpgid(cmdtab[slot].pid, cmdtab[slot].pid);	    execvp( argv[0], argv );	    _exit(127);	}        else if( cmdtab[slot].pid == -1 )	{	    perror( "vfork" );	    exit( EXITBAD );	}        /* close write end of pipes */        close(out[1]);         close(err[1]);         /* child writes stdout to out[1], parent reads from out[0] */	cmdtab[slot].fd[OUT] = out[0];	cmdtab[slot].stream[OUT] = fdopen(cmdtab[slot].fd[OUT], "rb");        if (cmdtab[slot].stream[OUT] == NULL) {            perror( "fdopen" );            exit( EXITBAD );        }        /* child writes stderr to err[1], parent reads from err[0] */        if (globs.pipe_action == 0)        {          close(err[0]);        }        else        {	    cmdtab[slot].fd[ERR] = err[0];	    cmdtab[slot].stream[ERR] = fdopen(cmdtab[slot].fd[ERR], "rb");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -