/* Caller must allocate exec_path of size at least MTCP_MAX_PATH */
char *mtcp_find_executable(char *executable, const char* path_env,
    char exec_path[PATH_MAX])
{
  char *path;
  const char *tmp_env;
  int len;

  if (path_env == NULL) {
    path_env = ""; // Will try stdpath later in this function
  }
  tmp_env = path_env;

  while (*tmp_env != '\0') {
    path = exec_path;
    len = 0;
    while (*tmp_env != ':' && *tmp_env != '\0' && ++len < PATH_MAX - 1)
      *path++ = *tmp_env++;
    if (*tmp_env == ':') /* but if *tmp_env == '\0', will exit while loop */
      tmp_env++;
    *path++ = '/'; /* '...//... is same as .../... in POSIX */
    len++;
    *path++ = '\0';
    mtcp_strncat(exec_path, executable, PATH_MAX - len - 1);
    if (mtcp_is_executable(exec_path))
      return exec_path;
  }

  // In case we're running with PATH environment variable unset:
  const char * stdpath = "/usr/local/bin:/usr/bin:/bin";
  if (mtcp_strcmp(path_env, stdpath) == 0) {
    return NULL;  // Already tried stdpath
  } else {
    return mtcp_find_executable(executable, stdpath, exec_path);
  }
}
Exemple #2
0
/**
 * This function will open the checkpoint file stored at the given filename.
 * It will check the magic number and take the appropriate action.  If the
 * magic number is unknown, we will abort.  The fd returned points to the
 * beginning of the uncompressed data.
 * NOTE: related code in ../dmtcp/src/connectionmanager.cpp:open_ckpt_to_read()
 *
 * @param filename the name of the checkpoint file
 * @return the fd to use
 */
static int open_ckpt_to_read(char *filename, char *envp[])
{
  int fd;
  int fds[2];
  char fc;
  char *gzip_cmd = "gzip";
  static char *gzip_args[] = { "gzip", "-d", "-", NULL };
#ifdef HBICT_DELTACOMP
  char *hbict_cmd = "hbict";
  static char *hbict_args[] = { "hbict", "-r", NULL };
#endif
  char decomp_path[PATH_MAX];
  static char **decomp_args;
  pid_t cpid;

  fc = first_char(filename);
  fd = mtcp_sys_open(filename, O_RDONLY, 0);
  if(fd < 0) {
    MTCP_PRINTF("ERROR: Cannot open checkpoint file %s\n", filename);
    mtcp_abort();
  }

  if (fc == MAGIC_FIRST || fc == 'D') /* no compression ('D' from DMTCP) */
    return fd;
  else if (fc == GZIP_FIRST
#ifdef HBICT_DELTACOMP
           || fc == HBICT_FIRST
#endif
          ) { /* Set prog_path */
    if( fc == GZIP_FIRST ){
      decomp_args = gzip_args;
      if( mtcp_find_executable(gzip_cmd, getenv("PATH"),
                               decomp_path) == NULL ) {
        MTCP_PRINTF("ERROR: Cannot find gunzip to decompress ckpt file!\n");
        mtcp_abort();
      }
    }
#ifdef HBICT_DELTACOMP
    if( fc == HBICT_FIRST ){
      decomp_args = hbict_args;
      if( mtcp_find_executable(hbict_cmd, getenv("PATH"),
                              decomp_path) == NULL ) {
        MTCP_PRINTF("ERROR: Cannot find hbict to decompress ckpt file!\n");
        mtcp_abort();
      }
    }
#endif
    if (mtcp_sys_pipe(fds) == -1) {
      MTCP_PRINTF("ERROR: Cannot create pipe to execute gunzip to decompress"
                  " checkpoint file!\n");
      mtcp_abort();
    }

    cpid = mtcp_sys_fork();

    if(cpid == -1) {
      MTCP_PRINTF("ERROR: Cannot fork to execute gunzip to decompress"
                  " checkpoint file!\n");
      mtcp_abort();
    }
    else if(cpid > 0) /* parent process */ {
      decomp_child_pid = cpid;
      mtcp_sys_close(fd);
      mtcp_sys_close(fds[1]);
      return fds[0];
    }
    else /* child process */ {
      fd = mtcp_sys_dup(mtcp_sys_dup(mtcp_sys_dup(fd)));
      if (fd == -1) {
        MTCP_PRINTF("ERROR: dup() failed!  No restoration will be performed!"
                    " Cancel now!\n");
        mtcp_abort();
      }
      fds[1] = mtcp_sys_dup(fds[1]);
      mtcp_sys_close(fds[0]);
      if (mtcp_sys_dup2(fd, STDIN_FILENO) != STDIN_FILENO) {
        MTCP_PRINTF("ERROR: dup2() failed!  No restoration will be performed!"
                    " Cancel now!\n");
        mtcp_abort();
      }
      mtcp_sys_close(fd);
      mtcp_sys_dup2(fds[1], STDOUT_FILENO);
      mtcp_sys_close(fds[1]);
      mtcp_sys_execve(decomp_path, decomp_args, envp);
      /* should not get here */
      MTCP_PRINTF("ERROR: Decompression failed!  No restoration will be"
                  " performed!  Cancel now!\n");
      mtcp_abort();
    }
  }
  else /* invalid magic number */ {
    MTCP_PRINTF("ERROR: Invalid magic number in this checkpoint file!\n");
    mtcp_abort();
  }
}