コード例 #1
0
ファイル: amudp_spawn.cpp プロジェクト: Improbus/CPEG614
  extern int AMUDP_SPMDGlunixSpawn(int nproc, int argc, char **argv) {
    /* GLUNIX has good built-in facilities for remote spawn */
    int forkRet;

    if (!AMUDP_SPMDSpawnRunning) {
      AMUDP_Err("Spawn functions should never be run directly - only passed to AMUDP_SPMDStartup()"); 
      return FALSE;
    }

    forkRet = fork();
    if (forkRet == -1) {
      perror("fork");
      return FALSE;
    } else if (forkRet != 0) {
      AMUDP_SPMDRedirectStdsockets = FALSE; /* GLUNIX has it's own console redirection facilities */
      return TRUE;  
    } else {  /*  this is the child - exec the new process */
      if (!Glib_Initialize())
        AMUDP_FatalErr("failed to Glib_Initialize()")
      /*AMUDP_assert(Glib_AmIStartup() > 0);*/
      Glib_Spawn(nproc, argv[0], argv); /* should never return */
      AMUDP_FatalErr("failed to Glib_Spawn()")
      return FALSE;
    }
  }
コード例 #2
0
ファイル: amudp_spawn.cpp プロジェクト: Improbus/CPEG614
/* ------------------------------------------------------------------------------------ 
 *  spawn jobs on local machine
 * ------------------------------------------------------------------------------------ */
extern int AMUDP_SPMDLocalSpawn(int nproc, int argc, char **argv) {
  /* just a simple fork/exec */
  int i;

  if (!AMUDP_SPMDSpawnRunning) {
    AMUDP_Err("Spawn functions should never be run directly - only passed to AMUDP_SPMDStartup()"); 
    return FALSE;
  }

  for (i = 0; i < nproc; i++) {
    #if PLATFORM_OS_MSWINDOWS && !PLATFORM_OS_CYGWIN
      if (_spawnv(_P_NOWAIT, argv[0], argv) == -1)
        AMUDP_FatalErr("failed _spawnv()");
    #elif PLATFORM_ARCH_CRAYX1
      { char **nargv = (char **)AMUDP_malloc(sizeof(char *)*(argc+2));
        nargv[0] = argv[0];
        memcpy(nargv+1,argv,argc*sizeof(char *));
        nargv[argc+1] = NULL;
        if (execsp(nargv, environ, NULL) == -1)
          AMUDP_FatalErr("failed execsp()");
      }
    #else
      int forkRet = fork();
      if (forkRet == -1) {
        perror("fork");
        return FALSE;
      } else if (forkRet != 0) continue;  /*  this is the parent, will go back to the top of the loop */
      else {  /*  this is the child - exec the new process */
        /*  could close some resources here (like AMUDP_SPMDListenSocket) but not strictly necessary */

        #if 0
          /*  put new process in a separate process group */
          if (setsid() == -1) perror("setsid"); 
        #endif

        /*  exec the program, with the given arguments  */
        execv(argv[0], argv);

        /*  if execv returns, an error occurred */
        perror("execv");
        _exit(1); /*  use _exit() to prevent corrupting parent's io buffers */
      } /*  child */
    #endif
  }
  return TRUE;
}
コード例 #3
0
ファイル: amudp_spawn.cpp プロジェクト: Improbus/CPEG614
  int AMUDP_SPMDRexecSpawn(int nproc, int argc, char **argv) {
    int i;
    char *rexec_cmd;
    char *rexec_options;
    char cmd1[1024],cmd2[1024];
    int pid;

    if (!AMUDP_SPMDSpawnRunning) {
      AMUDP_Err("Spawn functions should never be run directly - only passed to AMUDP_SPMDStartup()"); 
      return FALSE;
    }

    pid = getpid();

    rexec_cmd = AMUDP_getenv_prefixed_withdefault("REXEC_CMD", "rexec");
    rexec_options = AMUDP_getenv_prefixed_withdefault("REXEC_OPTIONS", "-q");

    cmd1[0] = '\0';
    for (i = 0; i < argc; i++) {
      AMUDP_assert(argv[i]);
      strcat(cmd1,"'");
      strcat(cmd1,argv[i]);
      strcat(cmd1,"' ");
    }
    AMUDP_assert(!argv[i]);

    /* build the rexec command */
    sprintf(cmd2, "%s %s -n %i /bin/sh -c \"%s%s\" " /* shell wrapper required because of crappy rexec implementation */
     " || ( echo \"rexec spawn failed.\" ; kill %i ) ",
      rexec_cmd, rexec_options, nproc,

      (AMUDP_SilentMode?"":"echo connected to \\`uname -n\\`... ; "),

      cmd1, pid

    );

    { int forkRet;
      forkRet = fork(); /* fork a new process to hold rexec master */

      if (forkRet == -1) {
        perror("fork");
        return FALSE;
      } else if (forkRet != 0) {
        AMUDP_SPMDRedirectStdsockets = FALSE; /* REXEC has it's own console redirection facilities */
        return TRUE;  
      } else {  /*  this is the child - exec the new process */
        if (!AMUDP_SilentMode) 
          printf("system(%s)\n", cmd2); fflush(stdout);
        if (system(cmd2) == -1)
           AMUDP_FatalErr("Failed to call system() to spawn rexec");
        exit(0);
      }
    }
    return TRUE;
}
コード例 #4
0
ファイル: amudp_spawn.cpp プロジェクト: Ldelaney/chapel
int AMUDP_SPMDCustomSpawn(int nproc, int argc, char **argv, char **extra_env) {
  int i;
  char *spawn_cmd = NULL;
  char *spawn_servers = NULL;
  char workerservers[1024];
  char workercmd[1024];
  char nproc_str[10];
  char cwd[1024];
  char cmd[1024];
#if PLATFORM_OS_MSWINDOWS || PLATFORM_OS_CYGWIN
  int spawn_use_create_process;
#endif
  int spawn_route_output;
  int pid;

  if (!AMUDP_SPMDSpawnRunning) {
    AMUDP_Err("Spawn functions should never be run directly - only passed to AMUDP_SPMDStartup()"); 
    return FALSE;
  }

  pid = getpid();

  spawn_cmd = AMUDP_getenv_prefixed_withdefault("CSPAWN_CMD","");
  if (!strlen(spawn_cmd)) {
    AMUDP_Err("You must set the " AMUDP_ENV_PREFIX_STR"_CSPAWN_CMD environment variable to use the custom spawn function"); 
    return FALSE;
  }
  spawn_servers = AMUDP_getenv_prefixed_withdefault("CSPAWN_SERVERS","");
  if (!strlen(spawn_servers)) spawn_servers = NULL;
  spawn_route_output = 
    strcmp(AMUDP_getenv_prefixed_withdefault("CSPAWN_ROUTE_OUTPUT","0"),"0");
#if PLATFORM_OS_MSWINDOWS || PLATFORM_OS_CYGWIN
  spawn_use_create_process =
    strcmp(AMUDP_getenv_prefixed_withdefault("CSPAWN_USE_CREATE_PROCESS","0"),"0");
#endif


  if (spawn_servers) { /* build server list */
    char *p = spawn_servers;
    char servername[255];
    char serverDelim[2];
    strcpy(serverDelim," "); /* default to space */
    workerservers[0] = '\0';
    for (i = 0; i < nproc; i++) { /* check we have enough servers & copy the right number */
      char *end;
      while (*p && strchr(SSH_SERVERS_DELIM_CHARS, *p)) p++;
      end = p + strcspn(p, SSH_SERVERS_DELIM_CHARS);
      if (p == end) {
        printf("Not enough machines in environment variable " AMUDP_ENV_PREFIX_STR"_CSPAWN_SERVERS to satisfy request for (%i).\n"
          "Only (%i) machines available: %s\n", nproc, i, spawn_servers);
        return FALSE;
      }
      strncpy(servername, p, end-p);
      servername[end-p] = '\0';
      if (workerservers[0]) strcat(workerservers, serverDelim);
      if (*end) serverDelim[0] = *end;
      strcat(workerservers, servername);
      if (*end) p = end+1;
      else p = end;
    }
  } 

  sprintf(nproc_str, "%i", nproc);

  if (!getcwd(cwd, 1024)) {
    printf("Error calling getcwd()\n");
    return FALSE;
  }

    /* build the worker command */
  { char temp[2048]; // TODO: allocate dynamically
    temp[0] = '\0';
    if (extra_env && extra_env[0]) {
      const char *envcmd = AMUDP_getenv_prefixed_withdefault("ENV_CMD", "env");
      strcat(temp,envcmd);
      strcat(temp," ");
      for (i=0; extra_env[i]; ++i) {
        strcat(temp,"'");
        strcat(temp,extra_env[i]);
        strcat(temp,"' ");
      }
    }
    for (i = 0; i < argc; i++) {
      AMUDP_assert(argv[i] != NULL);
      char *qarg = quote_for_local(argv[i]);
      strcat(temp,qarg);
      strcat(temp," ");
      AMUDP_free(qarg);
    }
    AMUDP_assert(!argv[i]);

  #if PLATFORM_OS_MSWINDOWS || PLATFORM_OS_CYGWIN
    strcpy(workercmd, temp);
  #else
    sprintf(workercmd, "/bin/sh -c \"%s%s\" || ( echo \"spawn failed.\" ; kill %i ) ",
      (AMUDP_SilentMode?"":"echo connected to `uname -n`... ; "),
      temp, pid
    );
  #endif
  }

  strcpy(cmd, spawn_cmd);
  { char tmp[1024];
    char *p = cmd;
    while ((p = strchr(p, '%'))) {
      const char *replacement;
      switch (*(p+1)) {
        case 'M': case 'm': 
          if (!spawn_servers) { /* user failed to provide servers and now is asking for them */
            AMUDP_Err("You must set the " AMUDP_ENV_PREFIX_STR"_CSPAWN_SERVERS environment "
                       "variable to use the %%M option in " AMUDP_ENV_PREFIX_STR"_CSPAWN_CMD");
          }
          replacement = workerservers; 
          break;
        case 'N': case 'n': replacement = nproc_str; break;
        case 'C': case 'c': replacement = workercmd; break;
        case 'D': case 'd': replacement = cwd; break;
        case 'P': case 'p': replacement = argv[0]; break;
        case '%': replacement = "%"; break;
        default: replacement = "";
      }
      strcpy(tmp, cmd);
      tmp[p-cmd] = '\0';
      strcat(tmp, replacement);
      if (*(p+1)) strcat(tmp, p+2);
      p += strlen(replacement);
      strcpy(cmd, tmp);
    }
  }

  AMUDP_SPMDRedirectStdsockets = spawn_route_output; 

  {
  #if !PLATFORM_OS_MSWINDOWS
    int forkRet;
    forkRet = fork(); /* fork a new process to hold cmd master */

    if (forkRet == -1) {
      perror("fork");
      return FALSE;
    }
    else if (forkRet != 0) {
      return TRUE;  
    }
    else 
  #endif
    {  /*  this is the child - exec the new process */
      if (!AMUDP_SilentMode) 
        printf("system(%s)\n", cmd); fflush(stdout);
    #if PLATFORM_OS_MSWINDOWS || PLATFORM_OS_CYGWIN
      if (spawn_use_create_process) {
        STARTUPINFO si;
        PROCESS_INFORMATION pi;
        DWORD code;

        ZeroMemory(&si, sizeof(STARTUPINFO));
        si.cb = sizeof(STARTUPINFO);
        si.hStdError = GetStdHandle(STD_OUTPUT_HANDLE); 
        si.hStdOutput = GetStdHandle(STD_ERROR_HANDLE); 
        si.dwFlags |= STARTF_USESTDHANDLES;

        if (   TRUE != CreateProcess(0, strdup(cmd), 0, 0, TRUE, 0, 0, 0, &si, &pi)
            || WAIT_FAILED == WaitForSingleObject(pi.hProcess, INFINITE)
            || 0 == GetExitCodeProcess(pi.hProcess, &code)
            || 0 != code)
          AMUDP_FatalErr("Failed while calling CreateProcess() with custom spawn command:\n%s", cmd);
      } else
    #endif
      if (system(cmd) != 0)
         AMUDP_FatalErr("Failed while calling system() with custom spawn command:\n%s", cmd);
      exit(0);
    }
  }

  return TRUE;
}
コード例 #5
0
ファイル: amudp_spawn.cpp プロジェクト: Ldelaney/chapel
/* ------------------------------------------------------------------------------------ 
 *  spawn jobs on local machine
 * ------------------------------------------------------------------------------------ */
extern int AMUDP_SPMDLocalSpawn(int nproc, int argc, char **argv, char **extra_env) {
  /* just a simple fork/exec */
  int i;

  if (!AMUDP_SPMDSpawnRunning) {
    AMUDP_Err("Spawn functions should never be run directly - only passed to AMUDP_SPMDStartup()"); 
    return FALSE;
  }

  /* Temporarily assume values from extra_env[] (which we modify in-place) */
  char **save_env = NULL;
  int envc = 0;
  if (extra_env && extra_env[0]) {
    for (envc=0; extra_env[envc]; ++envc) {/*empty*/}
    save_env = (char **)AMUDP_malloc(sizeof(char *)*envc);
    for (i=0;i<envc;++i) {
      char *var = extra_env[i];
      char *delim = strchr(var,'=');
      AMUDP_assert(delim);
      *delim = '\0';
      save_env[i] = getenv(var);
      setenv(var,delim+1,1);
    }
  }

  for (i = 0; i < nproc; i++) {
    #if PLATFORM_OS_MSWINDOWS && !PLATFORM_OS_CYGWIN
      if (_spawnv(_P_NOWAIT, argv[0], argv) == -1)
        AMUDP_FatalErr("failed _spawnv()");
    #elif PLATFORM_ARCH_CRAYX1
      { char **nargv = (char **)AMUDP_malloc(sizeof(char *)*(argc+2));
        nargv[0] = argv[0];
        memcpy(nargv+1,argv,argc*sizeof(char *));
        nargv[argc+1] = NULL;
        if (execsp(nargv, environ, NULL) == -1)
          AMUDP_FatalErr("failed execsp()");
      }
    #else
      int forkRet = fork();
      if (forkRet == -1) {
        perror("fork");
        return FALSE;
      } else if (forkRet != 0) continue;  /*  this is the parent, will go back to the top of the loop */
      else {  /*  this is the child - exec the new process */
        /*  could close some resources here (like AMUDP_SPMDListenSocket) but not strictly necessary */

        #if 0
          /*  put new process in a separate process group */
          if (setsid() == -1) perror("setsid"); 
        #endif

        /*  exec the program, with the given arguments  */
        execv(argv[0], argv);

        /*  if execv returns, an error occurred */
        perror("execv");
        _exit(1); /*  use _exit() to prevent corrupting parent's io buffers */
      } /*  child */
    #endif
  }

  /* Restore saved environment var(s) */
  for (i=0;i<envc;++i) {
    char *name = extra_env[i];
    if (save_env[i]) {
      setenv(name,save_env[i],1);
    } else {
      unsetenv(name);
    }
    /* Revert our in-place modification of extra_env[]: */
    name[strlen(name)] = '=';
  }
  AMUDP_free(save_env);

  return TRUE;
}