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

📄 execnt.c

📁 Boost provides free peer-reviewed portable C++ source libraries. We emphasize libraries that work
💻 C
📖 第 1 页 / 共 3 页
字号:
            string_copy(&cmd,*(argp++));            while( *argp != 0 )            {                string_push_back(&cmd,' ');                string_append(&cmd,*(argp++));            }        }                /* create the output buffers */        string_new( &cmdtab[ slot ].buffer_out );        string_new( &cmdtab[ slot ].buffer_err );        /* run the command, by creating a sub-process for it */        if (            ! CreateProcess(                NULL, /* application name */                cmd.value, /* command line */                NULL, /* process attributes */                NULL, /* thread attributes */                TRUE, /* inherit handles */                CREATE_NEW_PROCESS_GROUP, /* create flags */                NULL, /* env vars, null inherits env */                NULL, /* current dir, null is our current dir */                &si, /* startup info */                &cmdtab[ slot ].pi /* the child process info, if created */                )            )        {            perror( "CreateProcess" );            exit( EXITBAD );        }                /* clean up temporary stuff */        string_free(&cmd);    }    /* Wait until we're under the limit of concurrent commands. */    /* Don't trust globs.jobs alone.                            */    while( cmdsrunning >= MAXJOBS || cmdsrunning >= globs.jobs )        if( !execwait() )            break;        if (argv != argv_static)    {        free_argv(argv);    }}/* execwait()    - wait and drive at most one execution completion    * waits for one command to complete, while processing the io      for all ongoing commands.*/int execwait(){    int i = -1;    /* Handle naive make1() which doesn't know if cmds are running. */    if( !cmdsrunning )        return 0;        /* wait for a command to complete, while snarfing up any output */    do    {        /* read in the output of all running commands */        read_output();        /* close out pending debug style dialogs */        close_alerts();        /* check for a complete command, briefly */        if ( i < 0 ) i = try_wait(500);        /* check if a command ran out of time */        if ( i < 0 ) i = try_kill_one();    }    while ( i < 0 );        /* we have a command... process it */    --cmdsrunning;    {        timing_info time;        int rstat;                /* the time data for the command */        record_times(cmdtab[i].pi.hProcess, &time);        /* Clear the temp file */        if ( cmdtab[i].tempfile_bat )        {            unlink( cmdtab[ i ].tempfile_bat );            BJAM_FREE(cmdtab[i].tempfile_bat);            cmdtab[i].tempfile_bat = NULL;        }        /* the dispossition of the command */        if( intr )            rstat = EXEC_CMD_INTR;        else if( cmdtab[i].exitcode != 0 )            rstat = EXEC_CMD_FAIL;        else            rstat = EXEC_CMD_OK;                /* output the action block */        out_action(            cmdtab[i].action.size > 0 ? cmdtab[i].action.value : 0,            cmdtab[i].target.size > 0 ? cmdtab[i].target.value : 0,            cmdtab[i].command.size > 0 ? cmdtab[i].command.value : 0,            cmdtab[i].buffer_out.size > 0 ? cmdtab[i].buffer_out.value : 0,            cmdtab[i].buffer_err.size > 0 ? cmdtab[i].buffer_err.value : 0,            cmdtab[i].exit_reason);        /* call the callback, may call back to jam rule land.        assume -p0 in effect so only pass buffer containing        merged output */        (*cmdtab[ i ].func)(            cmdtab[ i ].closure,            rstat,            &time,            cmdtab[i].command.value,            cmdtab[i].buffer_out.value );                /* clean up the command data, process, etc. */        string_free(&cmdtab[i].action); string_new(&cmdtab[i].action);        string_free(&cmdtab[i].target); string_new(&cmdtab[i].target);        string_free(&cmdtab[i].command); string_new(&cmdtab[i].command);        if (cmdtab[i].pi.hProcess) { CloseHandle(cmdtab[i].pi.hProcess); cmdtab[i].pi.hProcess = 0; }        if (cmdtab[i].pi.hThread) { CloseHandle(cmdtab[i].pi.hThread); cmdtab[i].pi.hThread = 0; }        if (cmdtab[i].pipe_out[0]) { CloseHandle(cmdtab[i].pipe_out[0]); cmdtab[i].pipe_out[0] = 0; }        if (cmdtab[i].pipe_out[1]) { CloseHandle(cmdtab[i].pipe_out[1]); cmdtab[i].pipe_out[1] = 0; }        if (cmdtab[i].pipe_err[0]) { CloseHandle(cmdtab[i].pipe_err[0]); cmdtab[i].pipe_err[0] = 0; }        if (cmdtab[i].pipe_err[1]) { CloseHandle(cmdtab[i].pipe_err[1]); cmdtab[i].pipe_err[1] = 0; }        string_free(&cmdtab[i].buffer_out); string_new(&cmdtab[i].buffer_out);        string_free(&cmdtab[i].buffer_err); string_new(&cmdtab[i].buffer_err);        cmdtab[i].exitcode = 0;        cmdtab[i].exit_reason = EXIT_OK;    }    return 1;}/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */static void free_argv( char** args ){    BJAM_FREE( args[0] );    BJAM_FREE( args );}int maxline(){    OSVERSIONINFO os_info;    os_info.dwOSVersionInfoSize = sizeof(os_info);    GetVersionEx(&os_info);        return (os_info.dwMajorVersion == 3)        ? 996 /* NT 3.5.1 */        : 2047 /* NT >= 4.x */        ;}/* Convert a command string into arguments for spawnvp.  The original * code, inherited from ftjam, tried to break up every argument on the * command-line, dealing with quotes, but that's really a waste of * time on Win32, at least.  It turns out that all you need to do is * get the raw path to the executable in the first argument to * spawnvp, and you can pass all the rest of the command-line * arguments to spawnvp in one, un-processed string. * * New strategy: break the string in at most one place. */static char** string_to_args( const char*  string ){    int src_len;    int in_quote;    char* line;    char const* src;    char* dst;    char** argv;    /* drop leading and trailing whitespace if any */    while (isspace(*string))        ++string;      src_len = strlen( string );    while ( src_len > 0 && isspace( string[src_len - 1] ) )        --src_len;    /* Copy the input string into a buffer we can modify     */    line = (char*)BJAM_MALLOC_ATOMIC( src_len+1 );    if (!line)        return 0;    /* allocate the argv array.     *   element 0: stores the path to the executable     *   element 1: stores the command-line arguments to the executable     *   element 2: NULL terminator     */    argv = (char**)BJAM_MALLOC( 3 * sizeof(char*) );    if (!argv)    {        BJAM_FREE( line );        return 0;    }        /* Strip quotes from the first command-line argument and find     * where it ends.  Quotes are illegal in Win32 pathnames, so we     * don't need to worry about preserving escaped quotes here.     * Spaces can't be escaped in Win32, only enclosed in quotes, so     * removing backslash escapes is also a non-issue.     */    in_quote = 0;    for ( src = string, dst = line ; *src; src++ )    {        if (*src == '"')            in_quote = !in_quote;        else if (!in_quote && isspace(*src))            break;        else            *dst++ = *src;    }    *dst++ = 0;    argv[0] = line;    /* skip whitespace in src */    while (isspace(*src))        ++src;    argv[1] = dst;    /* Copy the rest of the arguments verbatim */        src_len -= src - string;    /* Use strncat because it appends a trailing nul */    *dst = 0;    strncat(dst, src, src_len);    argv[2] = 0;        return argv;}static void onintr( int disp ){    intr++;    printf( "...interrupted\n" );}/* * can_spawn() - If the command is suitable for execution via spawnvp, * return a number >= the number of characters it would occupy on the * command-line.  Otherwise, return zero. */long can_spawn(char* command){    char *p;        char inquote = 0;    /* Move to the first non-whitespace */    command += strspn( command, " \t" );    p = command;        /* Look for newlines and unquoted i/o redirection */    do    {        p += strcspn( p, "'\n\"<>|" );        switch (*p)        {        case '\n':            /* skip over any following spaces */            while( isspace( *p ) )                ++p;            /* Must use a .bat file if there is anything significant             * following the newline             */            if (*p)                return 0;            break;                    case '"':        case '\'':            if (p > command && p[-1] != '\\')            {                if (inquote == *p)                    inquote = 0;                else if (inquote == 0)                    inquote = *p;            }                            ++p;            break;                    case '<':        case '>':        case '|':            if (!inquote)                return 0;            ++p;            break;        }    }    while (*p);    /* Return the number of characters the command will occupy     */    return p - command;}/* 64-bit arithmetic helpers *//* Compute the carry bit from the addition of two 32-bit unsigned numbers */#define add_carry_bit(a, b) ( (((a) | (b)) >> 31) & (~((a) + (b)) >> 31) & 0x1 )/* Compute the high 32 bits of the addition of two 64-bit unsigned numbers, h1l1 and h2l2 */#define add_64_hi(h1, l1, h2, l2) ((h1) + (h2) + add_carry_bit(l1, l2))/* Add two 64-bit unsigned numbers, h1l1 and h2l2 */static FILETIME add_64(    unsigned long h1, unsigned long l1,    unsigned long h2, unsigned long l2){    FILETIME result;    result.dwLowDateTime = l1 + l2;    result.dwHighDateTime = add_64_hi(h1, l1, h2, l2);    return result;}static FILETIME add_FILETIME(FILETIME t1, FILETIME t2){    return add_64(        t1.dwHighDateTime, t1.dwLowDateTime      , t2.dwHighDateTime, t2.dwLowDateTime);}static FILETIME negate_FILETIME(FILETIME t){    /* 2s complement negation */    return add_64(~t.dwHighDateTime, ~t.dwLowDateTime, 0, 1);}/* Convert a FILETIME to a number of seconds */static double filetime_seconds(FILETIME t){    return t.dwHighDateTime * ((double)(1UL << 31) * 2.0 * 1.0e-7) + t.dwLowDateTime * 1.0e-7;}/* What should be a simple conversion, turns out to be horribly complicated by the defficiencies of MSVC and the Win32 API. */static time_t filetime_dt(FILETIME t_utc){    static int calc_time_diff = 1;    static double time_diff;    if ( calc_time_diff )    {        struct tm t0_;        FILETIME f0_local,f0_;        SYSTEMTIME s0_;        GetSystemTime(&s0_);        t0_.tm_year = s0_.wYear-1900;        t0_.tm_mon = s0_.wMonth-1;        t0_.tm_wday = s0_.wDayOfWeek;        t0_.tm_mday = s0_.wDay;        t0_.tm_hour = s0_.wHour;        t0_.tm_min = s0_.wMinute;        t0_.tm_sec = s0_.wSecond;        t0_.tm_isdst = 0;        SystemTimeToFileTime(&s0_,&f0_local);        LocalFileTimeToFileTime(&f0_local,&f0_);        time_diff = filetime_seconds(f0_)-((double)mktime(&t0_));        calc_time_diff = 0;    }    return ceil(filetime_seconds(t_utc)-time_diff);}static void record_times(HANDLE process, timing_info* time){    FILETIME creation, exit, kernel, user;        if (GetProcessTimes(process, &creation, &exit, &kernel, &user))    {        time->system = filetime_seconds(kernel);        time->user = filetime_seconds(user);        time->start = filetime_dt(creation);        time->end = filetime_dt(exit);    }}#define IO_BUFFER_SIZE (16*1024)static char ioBuffer[IO_BUFFER_SIZE+1];static void read_pipe(    HANDLE in, /* the pipe to read from */    string * out    ){    DWORD bytesInBuffer = 0;    DWORD bytesAvailable = 0;        do    {        /* check if we have any data to read */        if ( ! PeekNamedPipe( in, ioBuffer, IO_BUFFER_SIZE, &bytesInBuffer, &bytesAvailable, NULL ) )        {            bytesAvailable = 0;        }        

⌨️ 快捷键说明

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