/* 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); } }
/** * 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(); } }