Ejemplo n.º 1
0
Archivo: link.c Proyecto: WebDrake/dmd
int runProgram()
{
    //printf("runProgram()\n");
    if (global.params.verbose)
    {
        fprintf(global.stdmsg, "%s", global.params.exefile);
        for (size_t i = 0; i < global.params.runargs_length; i++)
            fprintf(global.stdmsg, " %s", (char *)global.params.runargs[i]);
        fprintf(global.stdmsg, "\n");
    }

    // Build argv[]
    Strings argv;

    argv.push(global.params.exefile);
    for (size_t i = 0; i < global.params.runargs_length; i++)
    {   const char *a = global.params.runargs[i];

#if _WIN32
        // BUG: what about " appearing in the string?
        if (strchr(a, ' '))
        {   char *b = (char *)mem.malloc(3 + strlen(a));
            sprintf(b, "\"%s\"", a);
            a = b;
        }
#endif
        argv.push(a);
    }
    argv.push(NULL);

#if _WIN32
    const char *ex = FileName::name(global.params.exefile);
    if (ex == global.params.exefile)
        ex = FileName::combine(".", ex);
    else
        ex = global.params.exefile;
    // spawnlp returns intptr_t in some systems, not int
    return spawnv(0,ex,argv.tdata());
#elif linux || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun
    pid_t childpid;
    int status;

    childpid = fork();
    if (childpid == 0)
    {
        const char *fn = argv[0];
        if (!FileName::absolute(fn))
        {   // Make it "./fn"
            fn = FileName::combine(".", fn);
        }
        execv(fn, (char **)argv.tdata());
        perror(fn);             // failed to execute
        return -1;
    }

    waitpid(childpid, &status, 0);

    if (WIFEXITED(status))
    {
        status = WEXITSTATUS(status);
        //printf("--- errorlevel %d\n", status);
    }
    else if (WIFSIGNALED(status))
    {
        printf("--- killed by signal %d\n", WTERMSIG(status));
        status = 1;
    }
    return status;
#else
    assert(0);
#endif
}
Ejemplo n.º 2
0
/* Set up in, out, err pipes and spawn a program, waiting or otherwise. */
HANDLE spawn (
    const char *program,
    const char *const *argv,
    int in,
    int out,
    int err,
    int search,
    char *envp,
    char *ptyname,
    int wait,
    char *pwd
    )
{
    int stdout_backup, stdin_backup, stderr_backup, wait_mode;
    HANDLE hProcess;
    HANDLE hReturn;

    /* Duplicate and save the original stdin/out/err handles. */
    stdout_backup = _dup (  _fileno ( stdout ) );
    stdin_backup  = _dup (  _fileno ( stdin  ) );
    stderr_backup = _dup (  _fileno ( stderr ) );

    /* If we are not using stdin/out/err
     * then duplicate the new pipes to current stdin/out/err handles.
     *
     * Default std fds are used if in, out or err parameters
     * are -1. */

    hReturn = (HANDLE)-1;
    hProcess = (HANDLE)-1;
    if ( ( out >= 0 ) && ( out != _fileno ( stdout ) ) ) {
        if ( _dup2 ( out, _fileno ( stdout ) ) != 0 ) goto error_exit;
    }
    if ( ( in >= 0 ) && ( in != _fileno ( stdin ) ) ) {
        if ( _dup2 ( in,  _fileno ( stdin )  ) != 0 ) goto error_exit_out;
    }
    if ( ( err >= 0 ) && ( err != _fileno ( stderr ) ) ) {
        if ( _dup2 ( err, _fileno ( stderr ) ) != 0 ) goto error_exit_in;
    }

    /* Set the wait mode. */
    if ( 0 == wait ) {
        wait_mode = P_NOWAIT;
    } else {
        wait_mode = P_WAIT;
    }

    /* Change working directory if supplied. */
    if (pwd) {
        if (chdir(pwd) < 0) {
            goto error_exit;
        }
    }

    /* Spawn process given on the command line*/
    if (search)
        hProcess = (HANDLE) spawnvp ( wait_mode, program, (char* const* )argv );
    else
        hProcess = (HANDLE) spawnv ( wait_mode, program, (char* const* )argv );

    /* Now that the process is launched, replace the original
     * in/out/err handles and close the backups. */

    if ( _dup2 ( stderr_backup, _fileno ( stderr ) ) != 0 ) goto error_exit;
 error_exit_in:
    if ( _dup2 ( stdin_backup,  _fileno ( stdin )  ) != 0 ) goto error_exit;
 error_exit_out:
    if ( _dup2 ( stdout_backup, _fileno ( stdout ) ) != 0 ) goto error_exit;

    hReturn = hProcess;

 error_exit:
    close ( stdout_backup );
    close ( stdin_backup  );
    close ( stderr_backup );

    return hReturn;

}
Ejemplo n.º 3
0
int main( int argc, char * const argv[] )
{
    char                myfile[ sizeof __FILE__ ];
    int                 child = argc > 1;
    int                 handle;
    int                 status;
    int                 handle_out;
    long                size;


    /*** Initialize ***/
    strcpy( ProgramName, argv[0] );     /* store filename */
    strlwr( ProgramName );              /* and lower case it */
    strcpy( myfile, __FILE__ );
    strlwr( myfile );

    if( child ) {
        char    *env_var;

        if( argc == 4 ) {        
        /* Verify expected command line contents */
            VERIFY( !strcmp( argv[1], ARG1 ) );
            VERIFY( !strcmp( argv[2], ARG2 ) );
            VERIFY( !strcmp( argv[3], ARG3 ) );

        /* Verify expected environment contents */
            env_var = getenv( VAR_NAME );
            VERIFY( env_var );
            VERIFY( !strcmp( env_var, VAR_TEXT ) );

            if( NumErrors != 0 ) {
                return( EXIT_FAILURE );
            } else {
                return( CHILD_RC );
            }
        } else {
            if( argc == 2 ) {
            /* Verify expected command line contents */
                VERIFY( !strcmp( argv[1], ARG_REDIR ) );

            /* Write text to stdout */
                printf( REDIR_TEXT );

                if( NumErrors != 0 ) {
                    return( EXIT_FAILURE );
                } else {
                    return( CHILD_RC );
                }
            }
            else
                return( EXIT_FAILURE );
        }                   
    } else {
        int         rc;
        char        **env;
        const char  *path = NULL;
        const char  *child_args[] = { ProgramName, ARG1, ARG2, ARG3, NULL };
        const char  *child_envp[] = { NULL, VAR_NAME "=" VAR_TEXT, "DOS4G=QUIET", NULL };

        /* We need to pass PATH down to the child because DOS/4GW style stub
         * programs rely on it to function properly.
         */
        env = environ;
        while( env ) {
            if( !strncmp( *env, "PATH=", 5 ) ) {
                path = *env;
                break;
            }
            ++env;
        }

        child_envp[0] = path;

        /* Test spawn functions */
        rc = spawnle( P_WAIT, ProgramName, ProgramName, ARG1, ARG2, ARG3, NULL, child_envp );
        VERIFY( rc == CHILD_RC );

        rc = spawnlpe( P_WAIT, ProgramName, ProgramName, ARG1, ARG2, ARG3, NULL, child_envp );
        VERIFY( rc == CHILD_RC );

        rc = spawnve( P_WAIT, ProgramName, child_args, child_envp );
        VERIFY( rc == CHILD_RC );

        rc = spawnvpe( P_WAIT, ProgramName, child_args, child_envp );
        VERIFY( rc == CHILD_RC );

        /* Modify our environment that child will inherit */
        VERIFY( !setenv( VAR_NAME, VAR_TEXT, 1 ) );
        
        rc = spawnl( P_WAIT, ProgramName, ProgramName, ARG1, ARG2, ARG3, NULL );
        VERIFY( rc == CHILD_RC );

        rc = spawnlp( P_WAIT, ProgramName, ProgramName, ARG1, ARG2, ARG3, NULL );
        VERIFY( rc == CHILD_RC );

        rc = spawnv( P_WAIT, ProgramName, child_args );
        VERIFY( rc == CHILD_RC );

        rc = spawnvp( P_WAIT, ProgramName, child_args );
        VERIFY( rc == CHILD_RC );

        /* Check inherited output redirection */
        handle_out = dup( STDOUT_FILENO );
        
        handle = creat( "test.fil", S_IREAD|S_IWRITE );
        VERIFY( handle != -1 );

        status = dup2( handle, STDOUT_FILENO );
        VERIFY( status != -1 );

        status = close( handle );
        VERIFY( status == 0 );

        rc = spawnl( P_WAIT, ProgramName, ProgramName, ARG_REDIR, NULL );
        VERIFY( rc == CHILD_RC );

        status = dup2( handle_out, STDOUT_FILENO );
        VERIFY( status != -1 );
        
        handle = open( "test.fil", O_RDWR );
        VERIFY( handle != -1 );

        size = filelength( handle );
        VERIFY( size == strlen( REDIR_TEXT ) );

        status = close( handle );
        VERIFY( status == 0 );

        status = unlink( "test.fil" );
        VERIFY( status == 0 );
        
        signal_count = 0;
        signal_number = 0;
        /* Install SIGBREAK handler */
        VERIFY( signal( SIGBREAK, break_handler ) == SIG_DFL );

        /* Raise signal and verify results */
        VERIFY( raise( SIGBREAK ) == 0 );
        VERIFY( signal_count == 1 );
        VERIFY( signal_number == SIGBREAK );

        /* Raise again - nothing should have happened */
        VERIFY( raise( SIGBREAK ) == 0 );
        VERIFY( signal_count == 1 );

        /*** Print a pass/fail message and quit ***/
        if( NumErrors != 0 ) {
            printf( "%s: FAILURE (%d errors).\n", ProgramName, NumErrors );
            return( EXIT_FAILURE );
        }
        printf( "Tests completed (%s).\n", ProgramName );
    }

    return( 0 );
}
Ejemplo n.º 4
0
int main(int argc, char **argv) {
  char python_bin[PATH_MAX + 1], argv0_bin[PATH_MAX + 1], *p, *q;
  char prog_py[PATH_MAX + 1];
  const char *moreargv[ARGV_MAX + 1];
  int i;
  (void)argc;
  p = argv[0];
  q = NULL;
  while (*p != '\0') {
    if (*p++ == FILE_SEP) q = p;
  }
  if (q == NULL) {  // Try to find argv[0] on $PATH.
    p = argv[0];
    strncpy(argv0_bin, p, sizeof argv0_bin);
    q = NULL;
    while (*p != '\0') {
      if (*p++ == '.') q = p;
    }
    if (q == NULL) {
      argv0_bin[sizeof argv0_bin - 5] = '\0';
      strcat(argv0_bin, ".exe");
    } else {
      argv0_bin[sizeof argv0_bin - 1] = '\0';
    }
    find_on_path(argv0_bin, python_bin);
  } else {  // Put dirname(argv[0]) to python_bin.
    p = argv[0];
    --q;
    if (q - p > PATH_MAX) {
      q = p + PATH_MAX;
    }
    strncpy(python_bin, p, q - p);
    python_bin[q - p] = '\0';
  }

  if (python_bin[0] == '\0') {
    python_bin[0] = '.';
    python_bin[1] = '\0';
  }
  strcpy(prog_py, python_bin);

  i = strlen(python_bin);
  if (i + strlen(python_exe) > PATH_MAX) {
    i = PATH_MAX - strlen(python_exe);
  }
  python_bin[i] = FILE_SEP;
  strcpy(python_bin + i + 1, python_exe);

  i = strlen(prog_py);
  if (i + strlen(pdfsizeopt_py) > PATH_MAX) {
    i = PATH_MAX - strlen(pdfsizeopt_py);
  }
  prog_py[i] = FILE_SEP;
  strcpy(prog_py + i + 1, pdfsizeopt_py);

  moreargv[0] = "python26";
  moreargv[1] = prog_py;
  for (i = 1; argv[i] != NULL; ++i) {
    moreargv[i + 1] = argv[i];
  }
  moreargv[i + 1] = NULL;
  

  // execv(...) and P_OVERLAY don't work well in wine-1.2.2 and Windows XP,
  // because they make this process return before the started process finishes.
  i = spawnv(P_WAIT, python_bin, moreargv);
  if (i < 0) {
    fprintf(stderr, "error: could not start %s: %s\n",
            python_bin, strerror(errno));
    return 120;
  }
  return i;
}