int main (int argc, char *argv[] ) { struct rusage kid_usage; pid_t kid; int kid_status; int i, opt, echo_args = 0, exit_flag; long int sample_time=0, time = 0; int maxkbytes=0; //kilobytes int maxseconds=0; //seconds long int maxmillis=0; unsigned int max_vsize = 0, max_rss = 0; unsigned int start, end; struct memtime_info info; // struct rlimit currentl; if (argc < 2) { char *tmp = strrchr(argv[0], '/'); tmp = (tmp ? tmp + 1 : argv[0]); fprintf(stderr, "%s: usage %s [-t <interval>] [-e] [-m <maxkilobytes>] [-c <maxcpuseconds>] <cmd> [<params>]\n", tmp,tmp); exit(EXIT_FAILURE); } while ((opt = getopt(argc, argv, "+et:m:c:")) != -1) { switch (opt) { case 'e' : echo_args = 1; break; case 't' : errno = 0; sample_time = strtol(optarg, NULL, 0); if (errno) { perror("Illegal argument to t option"); exit(EXIT_FAILURE); } break; case 'm' : errno = 0; maxkbytes = atoi(optarg); if (errno) { perror("Illegal argument to m option"); exit(EXIT_FAILURE); } break; case 'c' : errno = 0; maxseconds = atoi(optarg); if (errno) { perror("Illegal argument to c option"); exit(EXIT_FAILURE); } maxmillis=1000*maxseconds; break; } } if (echo_args) { fprintf(stderr,"Command line: "); for (i = optind; i < argc; i++) fprintf(stderr,"%s ", argv[i]); fprintf(stderr,"\n"); } start = get_time(); switch (kid = fork()) { case -1 : perror("fork failed"); exit(EXIT_FAILURE); case 0 : #if defined(CAN_USE_RLIMIT_RSS) if (maxkbytes>0) { set_mem_limit((long int)maxkbytes*1024); } #endif #if defined(CAN_USE_RLIMIT_CPU) if (maxseconds>0) { set_cpu_limit((long int)maxseconds); } #endif execvp(argv[optind], &(argv[optind])); perror("exec failed"); exit(EXIT_FAILURE); default : break; } if (!init_machdep(kid)) { fprintf(stderr, "%s: Failed to initialise sampling.\n", argv[0]); exit(EXIT_FAILURE); } do { get_sample(&info); max_vsize = (info.vsize_kb > max_vsize ? info.vsize_kb : max_vsize); max_rss = (info.rss_kb > max_rss ? info.rss_kb : max_rss); if (sample_time) { time++; if (time == 10 * sample_time) { end = get_time(); fprintf(stderr,"%.2f user, %.2f system, %.2f elapsed" " -- VSize = %dKB, RSS = %dKB\n", (double)info.utime_ms/1000.0, (double)info.stime_ms/1000.0, (double)(end - start)/1000.0, info.vsize_kb, info.rss_kb); fflush(stdout); time = 1; } } usleep(100000); exit_flag = ((wait4(kid, &kid_status, WNOHANG, &kid_usage) == kid) && (WIFEXITED(kid_status) || WIFSIGNALED(kid_status))); #if !defined(CAN_USE_RLIMIT_RSS) if ((maxkbytes>0) && (max_vsize>maxkbytes)) { kill(kid,SIGKILL); } #endif #if !defined(CAN_USE_RLIMIT_CPU) if ((maxmillis>0) && (info.utime_ms>maxmillis)) { kill(kid,SIGKILL); } #endif } while (!exit_flag); end = get_time(); if (WIFEXITED(kid_status)) { fprintf(stderr, "Exit [%d]\n", WEXITSTATUS(kid_status)); } else { fprintf(stderr, "Killed [%d]\n", WTERMSIG(kid_status)); } { double kid_utime = ((double)kid_usage.ru_utime.tv_sec + (double)kid_usage.ru_utime.tv_usec / 1E6); double kid_stime = ((double)kid_usage.ru_stime.tv_sec + (double)kid_usage.ru_stime.tv_usec / 1E6); fprintf(stderr, "%.2f user, %.2f system, %.2f elapsed -- " "Max VSize = %dKB, Max RSS = %dKB\n", kid_utime, kid_stime, (double)(end - start) / 1000.0, max_vsize, max_rss); } exit(EXIT_SUCCESS); }
void toolong( int sig) { char *id = "toolong"; struct stat sb; pid_t cpid; log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, "scheduling iteration took too long"); DBPRT(("scheduling iteration too long\n")) if (connector >= 0 && server_disconnect(connector)) log_err(errno, id, "server_disconnect"); if (close(server_sock)) log_err(errno, id, "close"); if ((cpid = fork()) > 0) /* parent re-execs itself */ { rpp_terminate(); #ifndef linux sleep(5); #endif /* hopefully, that gave the child enough */ /* time to do its business. anyhow: */ (void)waitpid(cpid, NULL, 0); if (chdir(oldpath) == -1) { sprintf(log_buffer, "chdir to %s", oldpath); log_err(errno, id, log_buffer); } sprintf(log_buffer, "restart dir %s object %s", oldpath, glob_argv[0]); log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer); execvp(glob_argv[0], glob_argv); log_err(errno, id, "execv"); exit(3); } /* ** Child (or error on fork) gets here and tried ** to dump core. */ if (stat("core", &sb) == -1) { if (errno == ENOENT) { log_close(1); abort(); rpp_terminate(); exit(2); /* not reached (hopefully) */ } log_err(errno, id, "stat"); } log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, "exiting without core dump"); log_close(1); rpp_terminate(); exit(0); }
static bool fork_program(char **arglist, int &pipe_in, int &pipe_out) { #if defined(MSDOS) || defined(__MSDOS__) || defined(__WINDOWS__) || defined(__NT__) FrWarning("Sorry, fork() is not available under MS-DOS or Windoze.\n" "Change the program's configuration to indicate a socket number\n" "other than -1 to permit the use of " #ifdef FrUSING_POPEN "popen" #else "spawn" #endif /* FrUSING_POPEN */ "(), which IS supported.") ; (void)arglist ; (void)pipe_in ; (void)pipe_out ; return false ; #else int pipe_desc[2] ; pipe_desc[0] = EOF ; pipe_desc[1] = EOF ; errno = 0 ; int pipe_stat = pipe( pipe_desc ) ; if (pipe_stat) { if (pipe_desc[0] != EOF) close(pipe_desc[0]) ; if (pipe_desc[1] != EOF) close(pipe_desc[1]) ; FrErrorVA("bad write pipe (errno=%d: %s)",errno,strerror(errno)) ; return false ; } int pipe_in_child = pipe_desc[0] ; int pipe_out_parent = pipe_desc[1] ; errno = 0 ; pipe_stat = pipe( pipe_desc ) ; if (pipe_stat) { close(pipe_in_child) ; close(pipe_out_parent) ; if (pipe_desc[0] != EOF && pipe_desc[0] != pipe_in_child) (void)close(pipe_desc[0]) ; if (pipe_desc[1] != EOF && pipe_desc[1] != pipe_out_parent) (void)close(pipe_desc[1]) ; FrErrorVA("bad read pipe (errno=%d: %s)",errno,strerror(errno)) ; return false ; } int pipe_in_parent = pipe_desc[0] ; int pipe_out_child = pipe_desc[1] ; errno = 0 ; int pid = fork() ; if (pid == -1) { close(pipe_in_parent) ; close(pipe_in_child) ; close(pipe_out_parent) ; close(pipe_out_child) ; FrErrorVA("unable to fork %s (errno=%d)",arglist[0],errno) ; return false ; } else if (pid == 0) { dup2( pipe_in_child, 0 ) ; // put the read end of the pipe on stdin dup2( pipe_out_child, 1 ) ; // put the write end of the pipe on stdout // dup2( 1, 2 ) ; // also put stderr thru the pipe if (!FramepaC_verbose) { close(2) ; open(FrNULL_DEVICE,O_WRONLY) ; } close(pipe_in_child) ; close(pipe_out_child) ; close( pipe_in_parent ) ; // close the unused ends of the pipes close( pipe_out_parent ) ; errno = 0 ; execvp( arglist[0], arglist) ; // not reached except when error FrErrorVA("couldn't exec program %s (errno=%d) -- check configuration file", arglist[0],errno) ; return false ; } else { close(pipe_in_child) ; // close the unused ends of the pipes close(pipe_out_child) ; pipe_in = pipe_in_parent ; pipe_out = pipe_out_parent ; set_child_pid(pid) ; } return true ; #endif /* __WINDOWS__ || __NT__ */ }
int run(char *program_name[], char **program_argv[], unsigned int count) { int child[count]; int num_proc = 0; int soyhijo = 0; int pipes[count][2]; char buf[1024]; //char buf_sal[1024]; //char *newenviron[] = { NULL }; //int haydatos = 0; //int status = 0; while (num_proc < count && soyhijo == 0) { //creo un nuevo pipe if (pipe(pipes[num_proc]) < 0) { perror("pipe"); } //creo un nuevo proceso child[num_proc] = fork(); if (child[num_proc] == 0) { soyhijo = 1; } else { num_proc++; } } if (soyhijo == 1) { //printf("Soy el hijo %d\n", num_proc); for (int i = 0; i < num_proc; i++) { close(pipes[i][1]); if (i != num_proc-1) { close(pipes[i][0]); } } close(pipes[num_proc][0]); //close(0); if (num_proc > 0) { dup2(pipes[num_proc-1][0], 0); //if (read(pipes[num_proc-1][0], buf, 1024) < 0) { // perror("leyendo datos"); //} //haydatos = 1; } //printf("Pude pasar. Soy el hijo %d\n", num_proc); /*if (haydatos == 1) { printf("Datos: %s\n", buf); int noencontre = 1; int j = 0; while (noencontre) { if (program_argv[num_proc][j] == NULL) { noencontre = 0; program_argv[num_proc][j] = buf; program_argv[num_proc][j+1] = NULL; } printf("%d: %s\n", j, program_argv[num_proc][j]); j++; } printf("%d: %s\n", j, program_argv[num_proc][j]); }*/ //printf("%s\n", program_argv[num_proc][0]); //printf("%s\n", program_argv[num_proc][1]); dup2(pipes[num_proc][1], 1); //perror("antes de ejecutar"); printf("asd\n"); execvp(program_name[num_proc], program_argv[num_proc]); if (num_proc > 0) { close(pipes[num_proc-1][0]); close(0); } close(pipes[num_proc][1]); //perror("despues de ejecutar"); /*if (write(pipes[num_proc][1], buf_sal, sizeof(buf_sal)) < 0) { perror("escribiendo datos"); }*/ } else { for (int i = 0; i < count - 1; i++) { close(pipes[i][1]); close(pipes[i][0]); } close(pipes[count-1][1]); //dup2(1, pipes[count-1][0]); //waitpid(child[count-1], &status, 1); if (read(pipes[count-1][0], buf, 1024) < 0) { perror("leyendo datos"); } printf("%s", buf); close(pipes[count-1][0]); //perror("Soy el padre saliendo"); } return 0; }
int compile(int lang) { int pid; const char * CP_C[] = { "gcc", "Main.c", "-o", "Main", "-O2","-Wall", "-lm", "--static", "-std=c99", "-DONLINE_JUDGE", NULL }; const char * CP_X[] = { "g++", "Main.cc", "-o", "Main", "-O2", "-Wall", "-lm", "--static", "-DONLINE_JUDGE", NULL }; const char * CP_P[] = { "fpc", "Main.pas", "-O2","-Co", "-Ct","-Ci", NULL }; const char * CP_J[] = { "javac", "-J-Xms32m", "-J-Xmx256m", "Main.java", NULL }; const char * CP_R[] = { "ruby", "-c", "Main.rb", NULL }; const char * CP_B[] = { "chmod", "+rx", "Main.sh", NULL }; const char * CP_Y[] = { "python","-c","import py_compile; py_compile.compile(r'Main.py')", NULL }; const char * CP_PH[] = { "php", "-l","Main.php", NULL }; const char * CP_PL[] = { "perl","-c", "Main.pl", NULL }; const char * CP_CS[] = { "gmcs","-warn:0", "Main.cs", NULL }; pid = fork(); if (pid == 0) { struct rlimit LIM; LIM.rlim_max = 60; LIM.rlim_cur = 60; setrlimit(RLIMIT_CPU, &LIM); LIM.rlim_max = 8 * STD_MB; LIM.rlim_cur = 8 * STD_MB; setrlimit(RLIMIT_FSIZE, &LIM); LIM.rlim_max = 1024 * STD_MB; LIM.rlim_cur = 1024 * STD_MB; setrlimit(RLIMIT_AS, &LIM); if (lang != 2) { freopen("ce.txt", "w", stderr); //freopen("/dev/null", "w", stdout); } else { freopen("ce.txt", "w", stdout); } switch (lang) { case 0: execvp(CP_C[0], (char * const *) CP_C); break; case 1: execvp(CP_X[0], (char * const *) CP_X); break; case 2: execvp(CP_P[0], (char * const *) CP_P); break; case 3: execvp(CP_J[0], (char * const *) CP_J); break; case 4: execvp(CP_R[0], (char * const *) CP_R); break; case 5: execvp(CP_B[0], (char * const *) CP_B); break; case 6: execvp(CP_Y[0], (char * const *) CP_Y); break; case 7: execvp(CP_PH[0], (char * const *) CP_PH); break; case 8: execvp(CP_PL[0], (char * const *) CP_PL); break; case 9: execvp(CP_CS[0], (char * const *) CP_CS); break; default: printf("nothing to do!\n"); } if (DEBUG) printf("compile end!\n"); exit(!system("cat ce.txt")); //exit(0); } else { int status=0; waitpid(pid, &status, 0); if(lang>3&&lang<7) status=get_file_size("ce.txt"); if (DEBUG) printf("status=%d\n", status); return status; } }
int main() { char* buffer = malloc(sizeof(char)*BUFF_MAX); char* tokens = malloc(sizeof(char)*BUFF_MAX); char* rin_fname = malloc(sizeof(char)*ARGLEN_MAX); char* rout_fname = malloc(sizeof(char)*ARGLEN_MAX); char** args = NULL; int i = 0; int numargs = 0; int go = 1; startloop: while(go){ int background_flag = 0; int pipedcnt = 0; int fdout = 0; int fdin = 0; numargs = 0; if (isatty(STDIN_FILENO)) printf("sish:> "); if (fgets(buffer, BUFF_MAX, stdin) == NULL) goto end; //printf("buffer: %s\n", buffer); // special commands or exits if (feof(stdin)) go = 0; if (!strcmp(buffer, "\0")) goto end; if (!strcmp(buffer, "exit\n")) goto end; if (!strcmp(buffer, "\n")) goto startloop; // check for the placement of special characters (<, >, &, |) int rinflag = 0; int routflag = 0; int pipeflag = 0; for (i = 0; buffer[i] != '\0'; i++) { if (buffer[i] == '&') { if (i > 0 && buffer[i-1] == ' ' && (buffer[i+1] == '\n' || buffer[i+1] == '\0')) { background_flag = 1; buffer[i] = ' '; } else { printf("ERROR: misplaced &\n"); goto startloop; } } if (buffer[i] == '>') { if (routflag) { printf("ERROR: too many > characters\n"); goto startloop; } else if (i == 0) { printf("ERROR: can't start with >\n"); goto startloop; } routflag = 1; } if (buffer[i] == '|') { if (i == 0) { printf("ERROR: can't start with |\n"); goto startloop; } pipeflag = 1; if (routflag == 1) { printf("ERROR: misplaced >\n"); goto startloop; } } if (buffer[i] == '<'){ if (i == 0) { printf("ERROR: can't start with <\n"); goto startloop; } if (rinflag) { printf("ERROR: too many > characters\n"); goto startloop; } rinflag = 1; if (pipeflag == 1) { printf("ERROR: misplaced <\n"); goto startloop; } } } // count the number of piped commands char* buffcopy = malloc(sizeof(char)*(strlen(buffer)+1)); strcpy(buffcopy, buffer); strtok(buffcopy, "|"); pipedcnt++; while(strtok(NULL, "|") != NULL) pipedcnt++; strcpy(buffcopy, buffer); // put the commands in an array char** cmds = malloc(sizeof(char*)*pipedcnt); cmds[0] = strtok(buffcopy, "|"); for (i=1; i<pipedcnt; i++) cmds[i] = strtok(NULL, "|"); // create pipes int** pfds = malloc(sizeof(int*)*pipedcnt-1); for (i=0; i < pipedcnt-1; i++) { pfds[i] = malloc(sizeof(int)*2); if (pipe(pfds[i]) != 0) { printf("ERROR: pipe could not be created\n"); goto startloop; } } // divide line by pipe chars int procno; pid_t lastpid; int status; for(procno = 0; procno < pipedcnt; procno++) { // prepare command char* cmd = malloc(sizeof(char)*(strlen(cmds[procno])+1)); strcpy(cmd, cmds[procno]); // get redirects if (procno == 0 && rinflag) { // redirect in // get the filename char* tempstr; tempstr = strtok(cmd, "<"); strcpy(cmd, tempstr); tempstr = strtok(NULL, " \n\t"); if (tempstr == NULL) { printf("ERROR: nothing before the redirect\n"); free(cmd); goto startloop; } strcpy(rin_fname, tempstr); // check if file is valid FILE* fin = fopen(rin_fname, "r"); if (fin == NULL) { printf("ERROR: file %s does not exist\n", rin_fname); goto startloop; } else fclose(fin); // copy the rest of the args back in tempstr = strtok(NULL, " \n\t"); while (tempstr != NULL) { strcat(cmd, " "); strcat(cmd, tempstr); tempstr = strtok(NULL, " \n\t"); } } if (procno == pipedcnt-1 && routflag) { // redirect out // get the filename char* tempstr; tempstr = strtok(cmd, ">"); strcpy(cmd, tempstr); tempstr = strtok(NULL, " \n\t"); if (tempstr == NULL) { printf("ERROR: nothing before the redirect\n"); free(cmd); goto startloop; } strcpy(rout_fname, tempstr); // copy the rest of the args back in tempstr = strtok(NULL, " \n\t"); while (tempstr != NULL) { strcat(cmd, " "); strcat(cmd, tempstr); tempstr = strtok(NULL, " \n\t"); } } // separate args char* t = strtok(cmd, " \n\t"); numargs = 0; while (t != NULL) { args = realloc(args, sizeof(char*)*(numargs+1)); args[numargs] = realloc(args[numargs], sizeof(char)*ARGLEN_MAX); strcpy(args[numargs], t); t = strtok(NULL, " \n\t"); numargs++; } args = realloc(args, sizeof(char*)*(numargs+1)); args[numargs] = NULL; // fork it. fork this project. switch (lastpid = fork()) { case 0: if (pipedcnt > 1) { if (procno != 0) { // redirect child's input to the last pipe dup2(pfds[procno-1][0], STDIN_FILENO); close(pfds[procno-1][1]); } if (procno != pipedcnt-1) { // redirect child's output to pipe dup2(pfds[procno][1], STDOUT_FILENO); } } if (procno == 0 && rinflag) { fdin = open(rin_fname, O_RDONLY); close(STDIN_FILENO); dup2(fdin, STDIN_FILENO); close(fdin); } if (procno == pipedcnt-1 && routflag) { fdout = open(rout_fname, O_WRONLY | O_CREAT | O_TRUNC, 0644); close(STDOUT_FILENO); dup2(fdout, STDOUT_FILENO); close(fdout); } if (background_flag) { if (setsid() < 0) printf("ERROR: could not set sessionid\n"); signal(SIGCHLD, SIG_IGN); } if (execvp(args[0], args) == -1) { printf("ERROR: could not execute %s\n", args[0]); goto end; } break; case -1: printf("ERROR: could not create new process"); goto startloop; break; default: if (pipedcnt > 1 && procno != 0) { // squeeze the last pipe close(pfds[procno-1][0]); close(pfds[procno-1][1]); } break; } // free memory free(cmd); } if (!background_flag) waitpid(lastpid, &status, 0); for (i=0; i < pipedcnt-1; i++) { free(pfds[i]); } free(pfds); } end: free(buffer); free(tokens); free(rin_fname); free(rout_fname); for (i=0 ; i <= numargs; i++) { if (args != NULL && args[i] != NULL) free(args[i]); } if (args != NULL) free(args); return 0; }
void p_child(char **commands){ execvp(commands[0], commands); }
int start_command(struct child_process *cmd) { int need_in, need_out, need_err; int fdin[2], fdout[2], fderr[2]; /* * In case of errors we must keep the promise to close FDs * that have been passed in via ->in and ->out. */ need_in = !cmd->no_stdin && cmd->in < 0; if (need_in) { if (pipe(fdin) < 0) { if (cmd->out > 0) close(cmd->out); return -ERR_RUN_COMMAND_PIPE; } cmd->in = fdin[1]; } need_out = !cmd->no_stdout && !cmd->stdout_to_stderr && cmd->out < 0; if (need_out) { if (pipe(fdout) < 0) { if (need_in) close_pair(fdin); else if (cmd->in) close(cmd->in); return -ERR_RUN_COMMAND_PIPE; } cmd->out = fdout[0]; } need_err = !cmd->no_stderr && cmd->err < 0; if (need_err) { if (pipe(fderr) < 0) { if (need_in) close_pair(fdin); else if (cmd->in) close(cmd->in); if (need_out) close_pair(fdout); else if (cmd->out) close(cmd->out); return -ERR_RUN_COMMAND_PIPE; } cmd->err = fderr[0]; } fflush(NULL); cmd->pid = fork(); if (!cmd->pid) { if (cmd->no_stdin) dup_devnull(0); else if (need_in) { dup2(fdin[0], 0); close_pair(fdin); } else if (cmd->in) { dup2(cmd->in, 0); close(cmd->in); } if (cmd->no_stderr) dup_devnull(2); else if (need_err) { dup2(fderr[1], 2); close_pair(fderr); } if (cmd->no_stdout) dup_devnull(1); else if (cmd->stdout_to_stderr) dup2(2, 1); else if (need_out) { dup2(fdout[1], 1); close_pair(fdout); } else if (cmd->out > 1) { dup2(cmd->out, 1); close(cmd->out); } if (cmd->dir && chdir(cmd->dir)) die("exec %s: cd to %s failed (%s)", cmd->argv[0], cmd->dir, strerror(errno)); if (cmd->env) { for (; *cmd->env; cmd->env++) { if (strchr(*cmd->env, '=')) putenv((char*)*cmd->env); else unsetenv(*cmd->env); } } if (cmd->preexec_cb) cmd->preexec_cb(); if (cmd->perf_cmd) { execv_perf_cmd(cmd->argv); } else { execvp(cmd->argv[0], (char *const*) cmd->argv); } exit(127); } if (cmd->pid < 0) { int err = errno; if (need_in) close_pair(fdin); else if (cmd->in) close(cmd->in); if (need_out) close_pair(fdout); else if (cmd->out) close(cmd->out); if (need_err) close_pair(fderr); return err == ENOENT ? -ERR_RUN_COMMAND_EXEC : -ERR_RUN_COMMAND_FORK; } if (need_in) close(fdin[0]); else if (cmd->in) close(cmd->in); if (need_out) close(fdout[1]); else if (cmd->out) close(cmd->out); if (need_err) close(fderr[1]); return 0; }
// main method - program entry point int main() { char cmd[81]; // array of chars(a string) char* cmdTokens[20]; // array of strings int count; // number of times to execute command int parallel; // whether to run in parallel or sequentially int timeout; // max seconds to run set of each command while (TRUE) { // main shell input loop // begin parsing code printf("vas> "); fgets(cmd, sizeof(cmd), stdin); if (cmd[0] == '\n') continue; readCmdTokens(cmd, cmdTokens); if(strcmp(cmdTokens[0],"exit")==0) exit(0); do{ printf(" count> "); scanf("%d",&count); while(getchar()!='\n'); }while(count<0); printf(" [p]arallel or [s]equential> "); parallel = (readChar() == 'p') ? TRUE : FALSE; if(parallel==FALSE) { do{ printf(" timeout> "); scanf("%d",&timeout); while(getchar()!='\n'); }while(timeout<0); } // end parsing code if(parallel==FALSE) //sequential with timeout { int i,stat; time_t t; pid_t wpid; for(i=0;i<count;i++) { pid_t p; p=fork(); if(p<0)printf("\nProcess creation failed"); else if(p>0) //parent process { int waittime=0; do //parent waiting { wpid=waitpid(p,&stat,WNOHANG); if(wpid==0) { if(waittime<timeout) { sleep(1); waittime+=1; } else kill(p,SIGKILL); //kill child on timeout } }while(wpid==0 && waittime<=timeout); if(WIFSIGNALED(stat))printf("\nTimeout\n"); } else //child process { t=time(NULL); char* time; time=ctime(&t); printf("\nProcess with ID: %d starts at time: %s",getpid(),time); if(execvp(cmdTokens[0], cmdTokens)<0) printf("\nCannot execute %s",cmdTokens[0]); } } } /*if(parallel==FALSE) //sequential w/o timeout { pid_t p[10]; int i; for(i=0;i<count;i++) { p[i]=fork(); if(p[i]<0)printf("\nFork failed"); else if(p[i]>0)wait(); //parent process else //child process { time_t t; t=time(NULL); char* time; time=ctime(&t); printf("\nProcess with ID: %d starts at time: %s",getpid(),time); if(execvp(cmdTokens[0],cmdTokens)<0)printf("\nCannot execute %s",cmdTokens[0]); } } }*/ //sequential ends /*else //parallel with timeout { int i,stat; pid_t wpid; #pragma omp parallel private(i) shared(cmdTokens) //creating threads { #pragma omp for //parallel for for(i=0;i<count;i++) { pid_t p; p=fork(); if(p<0)printf("\nfork failed"); else if(p>0) //parent process { int waittime=0; do //parent process waiting { wpid=waitpid(p,&stat,WNOHANG); if(wpid==0) { if(waittime<timeout) { sleep(1); waittime++; } else { kill(p,SIGKILL); //kill child process on timeout //wait(); } } else break; }while(wpid==0 && waittime<=timeout); if(WIFSIGNALED(stat))printf("\nTimeout\n"); } else //child process { time_t t; t=time(NULL); char* time; time=ctime(&t); printf("\nProcess with ID: %d starts at time: %s",getpid(),time); if(execvp(cmdTokens[0], cmdTokens)<0) { printf("\nCannot execute %s",cmdTokens[0]); //exit(0); } } } } }*/ //parallel ends else //parallel w/o timeout { int i; pid_t p[100]; #pragma omp parallel private(i) shared(cmdTokens) //creating threads { #pragma omp for //parallel for for(i=0;i<count;i++) { p[i]=fork(); if(p[i]<0)printf("\nfork failed"); else if(p[i]>0) wait(); //parent process else //child process { time_t t; t=time(NULL); char* time; time=ctime(&t); printf("\nProcess with ID: %d starts at time: %s",getpid(),time); if(execvp(cmdTokens[0], cmdTokens)<0) { printf("\nCannot execute %s",cmdTokens[0]); //exit(0); } } } } } //parallel ends } //while ends }
// runProcess: Run a command line process (replacement for QProcess which // does not exist in the bootstrap library). bool runProcess(const QString &binary, const QStringList &args, const QString &workingDirectory, unsigned long *exitCode, QByteArray *stdOut, QByteArray *stdErr, QString *errorMessage) { QScopedArrayPointer<char> stdOutFileName; QScopedArrayPointer<char> stdErrFileName; int stdOutFile = 0; if (stdOut) { stdOutFileName.reset(tempFilePattern()); stdOutFile = mkstemp(stdOutFileName.data()); if (stdOutFile < 0) { *errorMessage = QStringLiteral("mkstemp() failed: ") + QString::fromLocal8Bit(strerror(errno)); return false; } } int stdErrFile = 0; if (stdErr) { stdErrFileName.reset(tempFilePattern()); stdErrFile = mkstemp(stdErrFileName.data()); if (stdErrFile < 0) { *errorMessage = QStringLiteral("mkstemp() failed: ") + QString::fromLocal8Bit(strerror(errno)); return false; } } const pid_t pID = fork(); if (pID < 0) { *errorMessage = QStringLiteral("Fork failed: ") + QString::fromLocal8Bit(strerror(errno)); return false; } if (!pID) { // Child if (stdOut) { dup2(stdOutFile, STDOUT_FILENO); close(stdOutFile); } if (stdErr) { dup2(stdErrFile, STDERR_FILENO); close(stdErrFile); } if (!workingDirectory.isEmpty() && !QDir::setCurrent(workingDirectory)) { std::wcerr << "Failed to change working directory to " << workingDirectory << ".\n"; ::_exit(-1); } char **argv = new char *[args.size() + 2]; // Create argv. char **ap = argv; *ap++ = encodeFileName(binary); foreach (const QString &a, args) *ap++ = encodeFileName(a); *ap = 0; execvp(argv[0], argv); ::_exit(-1); } int status; pid_t waitResult; do { waitResult = waitpid(pID, &status, 0); } while (waitResult == -1 && errno == EINTR); if (stdOut) { *stdOut = readOutRedirectFile(stdOutFile); unlink(stdOutFileName.data()); } if (stdErr) { *stdErr = readOutRedirectFile(stdErrFile); unlink(stdErrFileName.data()); } if (waitResult < 0) { *errorMessage = QStringLiteral("Wait failed: ") + QString::fromLocal8Bit(strerror(errno)); return false; } if (!WIFEXITED(status)) { *errorMessage = binary + QStringLiteral(" did not exit cleanly."); return false; } if (exitCode) *exitCode = WEXITSTATUS(status); return true; }
void heap_cmd(int argc, char **argv) { char libname[72]; int len; heap_options_parse(argc, argv); len = strlen(heap_options_tmppath); if(len > 64 || len <= 0) R_UTILS_ERRX("Bad tmp path len ! (can't excess 64 chars)"); strcpy(libname, heap_options_tmppath); if(libname[len-1] != '/') { libname[len] = '/'; libname[len+1] = 0; len++; } strcat(libname, "libheap_tmp.so"); heap_dump_lib(libname); if(setenv("LD_PRELOAD", libname, 1) == -1) { fprintf(stderr, "Can't set LD_PRELOAD environment variable\n"); exit(EXIT_FAILURE); } if(heap_options_color) if(setenv("LIBHEAP_COLOR", "1", 0) == -1) { fprintf(stderr, "Can't set LIBHEAP_COLOR environment variable\n"); exit(EXIT_FAILURE); } if(heap_options_trace_free) if(setenv("LIBHEAP_TRACE_FREE", "1", 0) == -1) { fprintf(stderr, "Can't set LIBHEAP_TRACE_FREE environment variable\n"); exit(EXIT_FAILURE); } if(heap_options_trace_malloc) if(setenv("LIBHEAP_TRACE_MALLOC", "1", 0) == -1) { fprintf(stderr, "Can't set LIBHEAP_TRACE_MALLOC environment variable\n"); exit(EXIT_FAILURE); } if(heap_options_trace_calloc) if(setenv("LIBHEAP_TRACE_CALLOC", "1", 0) == -1) { fprintf(stderr, "Can't set LIBHEAP_TRACE_CALLOC environment variable\n"); exit(EXIT_FAILURE); } if(heap_options_trace_realloc) if(setenv("LIBHEAP_TRACE_REALLOC", "1", 0) == -1) { fprintf(stderr, "Can't set LIBHEAP_TRACE_REALLOC environment variable\n"); exit(EXIT_FAILURE); } if(heap_options_dumpdata) if(setenv("LIBHEAP_DUMPDATA", "1", 0) == -1) { fprintf(stderr, "Can't set LIBHEAP_DUMPDATA environment variable\n"); exit(EXIT_FAILURE); } if(heap_options_output) if(setenv("LIBHEAP_OUTPUT", heap_options_output, 0) == -1) { fprintf(stderr, "Can't set LIBHEAP_OUTPUT environment variable\n"); exit(EXIT_FAILURE); } execvp(heap_options_command[0], heap_options_command); }
int main(int argc, char *argv[]){ if(argc < 2){ fprintf (stderr, "Usage: %s command filename1 [filename2] ...\n", argv[0]); return 0; } int i; int return_value; int child; char path[] = "/usr/bin/gcc"; char **snew; if((snew = (char **)malloc(sizeof(char *)*(argc + 3))) == NULL){ perror("Unable to allocate exec arguments"); return 0; } *snew = path; //*(snew + 1) = "testreadline.o"; //*(snew + 2) = "readline.o"; for(i = 1; i < argc; i++){ const char *str_name = argv[i]; char *name_o; if((name_o = malloc(strlen(str_name) + 1)) == NULL) return 0; strcpy(name_o, str_name); strcat(name_o, ".o"); *(snew + i) = name_o; } *(snew + argc) = "-o"; *(snew + argc + 1) = argv[1]; *(snew + argc + 2) = 0; //char *snew[] = {"gcc", "testreadline.o", "readline.o" ,"-o", "testreadline", 0}; fprintf(stderr, "makeserial written by Zijing Mao\n"); for(i = 1; i < argc; i++){ return_value = compile(path, argv[i]); fprintf(stderr, "%s\n", argv[i]); fprintf(stderr, "%s %d\n", argv[i], return_value); if(return_value == 0){ perror("Compile failed to compile an object"); return 0; } } child = fork(); if(child < 0){ perror("Fail to fork\n"); return 0; } if(child == 0){ /*Child code*/ execvp(path, snew); perror("Child failed to exec the command"); return 0; } free(*snew); free(snew); while(r_wait(NULL) > 0); /* wait for all children */ return 1; }
void execute(char **argv){ execvp(argv[0], argv); perror(SHELL_ERROR_IDENTIFIER); exit(EXIT_FAILURE); }
pid_t _DtTermPrimSubprocExec(Widget w, char *ptyName, Boolean consoleMode, char *cwd, char *cmd, char **argv, Boolean loginShell) { DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w; static char *defaultCmd = (char *) 0; int i; int pty; pid_t pid; char *c; int err; #ifdef MOVE_FDS int saveFd[3]; #else /* MOVE_FDS */ int savedStderr; #endif /* MOVE_FDS */ Boolean argvFree = False; struct sigaction sa; sigset_t ss; char buffer[BUFSIZ]; Widget parent; char *namebuf; struct passwd * pw; _Xgetpwparams pw_buf; _Xgetloginparams login_buf; #ifdef ALPHA_ARCHITECTURE /* merge code from xterm, ignore so that TIOCSWINSZ doesn't block */ signal(SIGTTOU, SIG_IGN); #endif /* ALPHA_ARCHITECTURE */ /* build a default exec command and argv list if one wasn't supplied... */ /* cmd... */ /* the command will be taken as follows: * - from the passed in cmd, * - from $SHELL, * - from the /etc/passwd entry for the /etc/utmp entry for this * terminal, * - from the /etc/passwd entry for this userid, or * - /bin/sh. */ if (!cmd || !*cmd) { if (!defaultCmd) { /* from $SHELL... */ c = getenv("SHELL"); /* if not valid, try the /etc/passwd entry for the username * associated with the /etc/utmp entry for this tty... */ if (!c || !*c) { /* get the /etc/passwd entry for the username associated with * /etc/utmp... */ if ((namebuf = _XGetlogin(login_buf)) != NULL) { /* get the user's passwd entry... */ pw = _XGetpwnam(namebuf, pw_buf); /* if we weren't able to come up with one for the * username... */ if (pw != NULL) c = pw->pw_shell; } } /* if not valid, try the /etc/passwd entry for the username * associate with the real uid... */ if (!c || !*c) { /* if we weren't able to come up with one for the userid... */ pw = _XGetpwuid(getuid(), pw_buf); if (pw != NULL) { c = pw->pw_shell; } } /* if not valid, use /bin/sh... */ if (!c || !*c) { c = DEFAULT_SHELL; } /* malloc space for this string. It will be free'ed in the * destroy function... */ defaultCmd = XtMalloc(strlen(c) + 1); (void) strcpy(defaultCmd, c); } cmd = defaultCmd; } if (!argv) { /* base it on cmd... */ argv = (char **) XtMalloc(2 * sizeof(char *)); /* if loginShell is set, then pre-pend a '-' to argv[0]. That's * also why we allocate an extra byte in argv[0]... */ argv[0] = XtMalloc(strlen(cmd) + 2); *argv[0] = '\0'; if (loginShell) { /* pre-pend an '-' for loginShell... */ (void) strcat(argv[0], "-"); if (c = strrchr(cmd, '/')) { strcat(argv[0], ++c); } else { strcat(argv[0], cmd); } } else { (void) strcat(argv[0], cmd); } /* null term the list... */ argv[1] = (char *) 0; /* we will need to free it up later... */ argvFree = True; } #ifdef OLDCODE /* this is left around from when we were using vfork().... */ /* open the pty slave so that we can set the modes. * * NOTE: this code depends on support for the O_NOCTTY ioctl. This * ioctl allows us to open the device without becoming the * session group leader for it. If that can't be done, it may * be necessary to rethink the way we open the pty slave... */ if ((pty = open(ptyName, O_RDWR | O_NOCTTY, 0)) < 0) { (void) perror(ptyName); return((pid_t) -1); } #endif /* OLDCODE */ #ifdef MOVE_FDS /* move fd[0:2] out of the way for now... */ for (i = 0; i <= 2; i++) { saveFd[i] = fcntl(i, F_DUPFD, 3); (void) close(i); } #else /* MOVE_FDS */ savedStderr = fcntl(2, F_DUPFD, 3); #endif /* MOVE_FDS */ /* set close on exec flags on all files... */ for (i = 0; i < _NFILE; i++) { (void) fcntl(i, F_SETFD, 1); } /* fork. We can't use vfork() since we need to do lots of stuff * below... */ if (isDebugSet('T')) { #ifdef BBA #pragma BBA_IGNORE #endif /*BBA*/ (void) timeStamp("about to fork()"); } _DtTermProcessLock(); for (i = 0; ((pid = FakeFork()) < 0) && (i < 10); i++) { /* if we are out of process slots, then let's sleep a bit and * try again... */ if (errno != EAGAIN) { break; } /* give it a chance to clear up... */ (void) sleep((unsigned long) 2); } if (pid < 0) { (void) perror("fork()"); #ifdef OLDCODE /* this is left around from when we were using vfork().... */ (void) close(pty); #endif /* OLDCODE */ return((pid_t) - 1); } else if (pid == 0) { /* child... */ _DtTermProcessUnlock(); #if defined(ALPHA_ARCHITECTURE) || defined(CSRG_BASED) || defined(LINUX_ARCHITECTURE) /* establish a new session for child */ setsid(); #else /* do a setpgrp() so that we can... */ (void) setpgrp(); #endif /* ALPHA_ARCHITECTURE */ #if defined(LINUX_ARCHITECTURE) /* set the ownership and mode of the pty... */ (void) _DtTermPrimSetupPty(ptyName, pty); #endif /* open the pty slave as our controlling terminal... */ pty = open(ptyName, O_RDWR, 0); if (pty < 0) { (void) perror(ptyName); (void) _exit(1); } #if defined(ALPHA_ARCHITECTURE) || defined(CSRG_BASED) || defined(LINUX_ARCHITECTURE) /* BSD needs to do this to acquire pty as controlling terminal */ if (ioctl(pty, TIOCSCTTY, (char *)NULL) < 0) { (void) close(pty); (void) perror("Error acquiring pty slave as controlling terminal"); /* exit the subprocess */ _exit(1); } /* Do it when no controlling terminal doesn't work for OSF/1 */ _DtTermPrimPtyGetDefaultModes(); #endif /* ALPHA_ARCHITECTURE */ #if !defined(LINUX_ARCHITECTURE) /* set the ownership and mode of the pty... */ (void) _DtTermPrimSetupPty(ptyName, pty); #endif /* LINUX_ARCHITECTURE */ /* apply the ttyModes... */ _DtTermPrimPtyInit(pty, tw->term.ttyModes, tw->term.csWidth); /* set the window size... */ _DtTermPrimPtySetWindowSize(pty, tw->term.columns * tw->term.widthInc + (2 * (tw->primitive.shadow_thickness + tw->primitive.highlight_thickness + tw->term.marginWidth)), tw->term.rows * tw->term.heightInc + (2 * (tw->primitive.shadow_thickness + tw->primitive.highlight_thickness + tw->term.marginHeight)), tw->term.rows, tw->term.columns); /* if we are in console mode, turn it on... */ if (consoleMode) { _DtTermPrimPtyConsoleModeEnable(pty); } #ifdef MOVE_FDS /* that should have open'ed into fd 0. Dup it into fd's 1 and 2... */ (void) dup(pty); (void) dup(pty); #else /* MOVE_FDS */ /* dup pty into fd's 0, 1, and 2... */ for (i = 0; i < 3; i++) { if (i != pty) { (void) close(i); (void) dup(pty); } } if (pty >= 3) { (void) close(pty); } #endif /* MOVE_FDS */ /* reset any alarms... */ (void) alarm(0); /* reset all signal handlers... */ sa.sa_handler = SIG_DFL; (void) sigemptyset(&sa.sa_mask); sa.sa_flags = 0; for (i = 1; i < NSIG; i++) { (void) sigaction(i, &sa, (struct sigaction *) 0); } /* unblock all signals... */ (void) sigemptyset(&ss); (void) sigprocmask(SIG_SETMASK, &ss, (sigset_t *) 0); /* ** Restore the original (pre-DT) environment, removing any ** DT-specific environment variables that were added before ** we... */ #if defined(HPVUE) #if (OSMINORVERSION > 01) (void) VuEnvControl(VUE_ENV_RESTORE_PRE_VUE); #endif /* (OSMINORVERSION > 01) */ #else /* (HPVUE) */ (void) _DtEnvControl(DT_ENV_RESTORE_PRE_DT); #endif /* (HPVUE) */ /* ** set a few environment variables of our own... */ for (parent = w; !XtIsShell(parent); parent = XtParent(parent)) ; (void) sprintf(buffer, "%ld", XtWindow(parent)); _DtTermPrimPutEnv("WINDOWID=", buffer); _DtTermPrimPutEnv("DISPLAY=", XDisplayString(XtDisplay(w))); if (((DtTermPrimitiveWidget)w)->term.emulationId) { _DtTermPrimPutEnv("TERMINAL_EMULATOR=", ((DtTermPrimitiveWidget)w)->term.emulationId); } /* set our utmp entry... */ (void) _DtTermPrimUtmpEntryCreate(w, getpid(), ((DtTermPrimitiveWidget)w)->term.tpd->utmpId); if (isDebugSet('T')) { #ifdef BBA #pragma BBA_IGNORE #endif /*BBA*/ (void) timeStamp("about to execvp()"); } /* turn off suid forever... */ _DtTermPrimRemoveSuidRoot(); /* change to the requested directory... */ if (cwd && *cwd) { (void) chdir(cwd); } #ifdef BBA _bA_dump(); #endif /* BBA */ _DtEnvControl(DT_ENV_RESTORE_PRE_DT); (void) execvp(cmd, argv); /* if we got to this point we error'ed out. Let's write out the * error... */ err = errno; /* restore stderr... */ (void) close(2); (void) dup(savedStderr); /* restore errno... */ errno = err; (void) perror(cmd); /* and we need to exit the subprocess... */ _exit(1); } /* parent... */ _DtTermProcessUnlock(); if (isDebugSet('T')) { #ifdef BBA #pragma BBA_IGNORE #endif /*BBA*/ (void) timeStamp("parent resuming"); } #ifdef MOVE_FDS /* DKS: we should check this out and see if it is necessary... */ (void) close(0); (void) close(1); (void) close(2); /* move fd[0:2] back in place... */ for (i = 0; i <= 2; i++) { if (saveFd[i] >= 0) { (void) fcntl(saveFd[i], F_DUPFD, i); (void) close(saveFd[i]); } } #else /* MOVE_FDS */ (void) close(savedStderr); #endif /* MOVE_FDS */ /* clean up malloc'ed memory... */ if (argvFree) { (void) XtFree(argv[0]); (void) XtFree((char *) argv); } #ifdef OLDCODE /* since we no longer open it in the parent, we probably don't want * to close it either... */ (void) close(pty); #endif /* OLDCODE */ /* assume that our child set up a utmp entry (since we have no way * for it to report to us) and add it to the list to cleanup)... */ _DtTermPrimUtmpAddEntry(((DtTermPrimitiveWidget)w)->term.tpd->utmpId); return(pid); }
int main (int argc, char **argv) { // command line check if (argc != 2) { printf("mandelmovie: Usage: mandelmovie <numProcesses>\n"); exit(1); } // make sure argv[1] is an int int i; for (i = 0; argv[1][i] != '\0'; ++i) { if (!isdigit(argv[1][i])) { printf("mandelmovie: numProcesses must be an integer.\n"); exit(1); } } int maxP = atoi(argv[1]); if (maxP <= 0) maxP = 1; int numP = 0; double zoom = 2; double endZoom = .0000000001; for (i = 0; i < NUM_FRAMES; ++i) { while (numP >= maxP) { int status; pid_t pidR = wait(&status); if (pidR == -1) { if (errno == ECHILD) { // this should not happen, but if no children then reset numP numP = 0; } else { printf("mandelmovie: wait: %s\n\n", strerror(errno)); exit(1); } } if (status != 0) { printf("mandelmovie: ./mandel failed. Exit status = %d.\n", status); exit(1); } --numP; } int pid = fork(); if (pid < 0) { printf("mandelmovie: fork: %s\n", strerror(errno)); exit(1); } else if (pid == 0) { //is child char cmd[256]; char *cmdWords[32]; sprintf(cmd, "./mandel -x .3855 -y .15 -s %lf -m 1500 -W 1360 -H 1360 -o mandel%d.bmp", zoom, i); int j; cmdWords[0] = strtok(cmd, " "); for (j = 1; j < 32; ++j) { cmdWords[j] = strtok(0, " "); if (cmdWords[j] == NULL) break; } execvp(cmdWords[0], cmdWords); // if get here, there is some error printf("mandelmovie: execvp: %s\n", strerror(errno)); exit(1); } else { // update numP and zoom for next iteration ++numP; zoom *= exp(log(endZoom / zoom)/NUM_FRAMES); } } // wait for the remaining processes while (numP > 0) { int status; pid_t pidR = wait(&status); if (pidR == -1) { if (errno == ECHILD) { // this should not happen, but if no children then reset numP numP = 0; } else { printf("mandelmovie: wait: %s\n\n", strerror(errno)); exit(1); } } if (status != 0) { printf("mandelmovie: ./mandel failed. Exit status = %d.\n", status); exit(1); } --numP; } return 0; }
/** * bidirectional popen() call * * @param rwepipe - int array of size three * @param exe - program to run * @param argv - argument list * @return pid or -1 on error * * The caller passes in an array of three integers (rwepipe), on successful * execution it can then write to element 0 (stdin of exe), and read from * element 1 (stdout) and 2 (stderr). */ static int popenRWE(int *rwepipe, const char *exe, const char *const argv[]) { int in[2]; int out[2]; int err[2]; int pid; int rc; rc = pipe(in); if (rc < 0) goto error_in; rc = pipe(out); if (rc < 0) goto error_out; rc = pipe(err); if (rc < 0) goto error_err; pid = fork(); if (pid > 0) { /* parent */ close(in[0]); close(out[1]); close(err[1]); rwepipe[0] = in[1]; rwepipe[1] = out[0]; rwepipe[2] = err[0]; return pid; } else if (pid == 0) { /* child */ close(in[1]); close(out[0]); close(err[0]); close(0); rc = dup(in[0]); close(1); rc = dup(out[1]); close(2); rc = dup(err[1]); execvp(exe, (char **)argv); exit(1); } else goto error_fork; return pid; error_fork: close(err[0]); close(err[1]); error_err: close(out[0]); close(out[1]); error_out: close(in[0]); close(in[1]); error_in: return -1; }
gboolean services_os_action_execute(svc_action_t * op, gboolean synchronous) { int rc, lpc; int stdout_fd[2]; int stderr_fd[2]; if (pipe(stdout_fd) < 0) { crm_err("pipe() failed"); } if (pipe(stderr_fd) < 0) { crm_err("pipe() failed"); } op->pid = fork(); switch (op->pid) { case -1: crm_err("fork() failed"); close(stdout_fd[0]); close(stdout_fd[1]); close(stderr_fd[0]); close(stderr_fd[1]); return FALSE; case 0: /* Child */ /* Man: The call setpgrp() is equivalent to setpgid(0,0) * _and_ compiles on BSD variants too * need to investigate if it works the same too. */ setpgid(0, 0); close(stdout_fd[0]); close(stderr_fd[0]); if (STDOUT_FILENO != stdout_fd[1]) { if (dup2(stdout_fd[1], STDOUT_FILENO) != STDOUT_FILENO) { crm_err("dup2() failed (stdout)"); } close(stdout_fd[1]); } if (STDERR_FILENO != stderr_fd[1]) { if (dup2(stderr_fd[1], STDERR_FILENO) != STDERR_FILENO) { crm_err("dup2() failed (stderr)"); } close(stderr_fd[1]); } /* close all descriptors except stdin/out/err and channels to logd */ for (lpc = getdtablesize() - 1; lpc > STDERR_FILENO; lpc--) { close(lpc); } /* Setup environment correctly */ add_OCF_env_vars(op); /* execute the RA */ execvp(op->opaque->exec, op->opaque->args); switch (errno) { /* see execve(2) */ case ENOENT: /* No such file or directory */ case EISDIR: /* Is a directory */ rc = PCMK_OCF_NOT_INSTALLED; #if SUPPORT_NAGIOS if (safe_str_eq(op->standard, "nagios")) { rc = NAGIOS_NOT_INSTALLED; } #endif break; case EACCES: /* permission denied (various errors) */ rc = PCMK_OCF_INSUFFICIENT_PRIV; #if SUPPORT_NAGIOS if (safe_str_eq(op->standard, "nagios")) { rc = NAGIOS_INSUFFICIENT_PRIV; } #endif break; default: rc = PCMK_OCF_UNKNOWN_ERROR; break; } _exit(rc); } /* Only the parent reaches here */ close(stdout_fd[1]); close(stderr_fd[1]); op->opaque->stdout_fd = stdout_fd[0]; set_fd_opts(op->opaque->stdout_fd, O_NONBLOCK); op->opaque->stderr_fd = stderr_fd[0]; set_fd_opts(op->opaque->stderr_fd, O_NONBLOCK); if (synchronous) { int status = 0; int timeout = (1 + op->timeout) / 1000; crm_trace("Waiting for %d", op->pid); while ((op->timeout < 0 || timeout > 0) && waitpid(op->pid, &status, WNOHANG) <= 0) { sleep(1); read_output(op->opaque->stdout_fd, op); read_output(op->opaque->stderr_fd, op); timeout--; } crm_trace("Child done: %d", op->pid); if (timeout == 0) { int killrc = kill(op->pid, 9 /*SIGKILL*/); op->rc = PCMK_OCF_UNKNOWN_ERROR; op->status = PCMK_LRM_OP_TIMEOUT; crm_warn("%s:%d - timed out after %dms", op->id, op->pid, op->timeout); if (killrc && errno != ESRCH) { crm_err("kill(%d, KILL) failed: %d", op->pid, errno); } } else if (WIFEXITED(status)) { op->status = PCMK_LRM_OP_DONE; op->rc = WEXITSTATUS(status); crm_info("Managed %s process %d exited with rc=%d", op->id, op->pid, op->rc); } else if (WIFSIGNALED(status)) { int signo = WTERMSIG(status); op->status = PCMK_LRM_OP_ERROR; crm_err("Managed %s process %d exited with signal=%d", op->id, op->pid, signo); } #ifdef WCOREDUMP if (WCOREDUMP(status)) { crm_err("Managed %s process %d dumped core", op->id, op->pid); } #endif read_output(op->opaque->stdout_fd, op); read_output(op->opaque->stderr_fd, op); } else { crm_trace("Async waiting for %d - %s", op->pid, op->opaque->exec); mainloop_add_child(op->pid, op->timeout, op->id, op, operation_finished); op->opaque->stdout_gsource = mainloop_add_fd(op->id, G_PRIORITY_LOW, op->opaque->stdout_fd, op, &stdout_callbacks); op->opaque->stderr_gsource = mainloop_add_fd(op->id, G_PRIORITY_LOW, op->opaque->stderr_fd, op, &stderr_callbacks); } return TRUE; }
void run_symlink(int argc, char **argv) { EUID_ASSERT(); char *program = strrchr(argv[0], '/'); if (program) program += 1; else program = argv[0]; if (strcmp(program, "firejail") == 0) return; // find the real program // probably the first entry returend by "which -a" is a symlink - use the second entry! char *p = getenv("PATH"); if (!p) { fprintf(stderr, "Error: PATH environment variable not set\n"); exit(1); } char *path = strdup(p); if (!path) errExit("strdup"); char *selfpath = realpath("/proc/self/exe", NULL); if (!selfpath) errExit("realpath"); // look in path for our program char *tok = strtok(path, ":"); int found = 0; while (tok) { char *name; if (asprintf(&name, "%s/%s", tok, program) == -1) errExit("asprintf"); struct stat s; if (stat(name, &s) == 0) { char* rp = realpath(name, NULL); if (!rp) errExit("realpath"); if (strcmp(selfpath, rp) != 0) { program = strdup(name); found = 1; free(rp); break; } free(rp); } free(name); tok = strtok(NULL, ":"); } if (!found) { fprintf(stderr, "Error: cannot find the program in the path\n"); exit(1); } free(selfpath); // start the argv[0] program in a new sandbox char *firejail; if (asprintf(&firejail, "%s/bin/firejail", PREFIX) == -1) errExit("asprintf"); printf("Redirecting symlink to %s\n", program); // run command char *a[3 + argc]; a[0] = firejail; a[1] = program; int i; for (i = 0; i < (argc - 1); i++) a[i + 2] = argv[i + 1]; a[i + 2] = NULL; execvp(a[0], a); perror("execvp"); exit(1); }
static void find_all_symbols(char *filename) { char *vec[4]; /* kerneldoc -list file NULL */ pid_t pid; int ret, i, count, start; char real_filename[PATH_MAX + 1]; int pipefd[2]; char *data, *str; size_t data_len = 0; vec[0] = KERNELDOC; vec[1] = LIST; vec[2] = filename; vec[3] = NULL; if (pipe(pipefd)) { perror("pipe"); exit(1); } switch (pid=fork()) { case -1: perror("fork"); exit(1); case 0: close(pipefd[0]); dup2(pipefd[1], 1); memset(real_filename, 0, sizeof(real_filename)); strncat(real_filename, kernsrctree, PATH_MAX); strncat(real_filename, "/" KERNELDOCPATH KERNELDOC, PATH_MAX - strlen(real_filename)); execvp(real_filename, vec); fprintf(stderr, "exec "); perror(real_filename); exit(1); default: close(pipefd[1]); data = malloc(4096); do { while ((ret = read(pipefd[0], data + data_len, 4096)) > 0) { data_len += ret; data = realloc(data, data_len + 4096); } } while (ret == -EAGAIN); if (ret != 0) { perror("read"); exit(1); } waitpid(pid, &ret ,0); } if (WIFEXITED(ret)) exitstatus |= WEXITSTATUS(ret); else exitstatus = 0xff; count = 0; /* poor man's strtok, but with counting */ for (i = 0; i < data_len; i++) { if (data[i] == '\n') { count++; data[i] = '\0'; } } start = all_list_len; all_list_len += count; all_list = realloc(all_list, sizeof(char *) * all_list_len); str = data; for (i = 0; i < data_len && start != all_list_len; i++) { if (data[i] == '\0') { all_list[start] = str; str = data + i + 1; start++; } } }
int main(int argc, char *argv[]) { int conn; struct addrinfo hints; struct addrinfo *res; char *host; char *port; char rhost[NI_MAXHOST + NI_MAXSERV]; char rport[NI_MAXSERV]; int error; int opt; int sock; if (argc < 4) { fprintf(stderr, "Usage: %s <host> <port> ['zfs recv' args ...]\n", argv[0]); exit(2); } host = argv[1]; port = argv[2]; bzero((char *)&hints, sizeof (struct addrinfo)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; hints.ai_flags |= AI_NUMERICHOST; hints.ai_flags |= AI_NUMERICSERV; if ((error = getaddrinfo(host, port, &hints, &res))) { fprintf(stderr, "zfs_recv: getaddrinfo(): %s\n", gai_strerror(error)); exit(1); } sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (sock < 0) { perror("zfs_recv: socket()"); exit(1); } opt = 1; if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof (opt)) < 0) { perror("zfs_recv: setsockopt()"); exit(1); } if (bind(sock, (struct sockaddr *)res->ai_addr, res->ai_addrlen) < 0) { perror("zfs_recv: bind()"); exit(1); } if (listen(sock, 1) < 0) { perror("zfs_recv: listen()"); exit(1); } error = getnameinfo(res->ai_addr, res->ai_addrlen, rhost, sizeof (rhost), rport, sizeof (rport), NI_NUMERICHOST|NI_NUMERICSERV); if (error != 0) { fprintf(stderr, "zfs_recv: getnameinfo(): %s\n", gai_strerror(error)); exit(1); } fprintf(stderr, "Waiting for stream on: {'host': '%s', 'port': '%s'}\n", rhost, rport); freeaddrinfo(res); if ((conn = accept(sock, NULL, NULL)) < 0) { perror("zfs_recv: accept()"); exit(1); } /* redir stdout and stderr to the socket, keep stderr (caller can log it) */ if (dup2(conn, 0) < 0) { perror("zfs_recv: dup2(stdin)"); exit(1); } if (dup2(conn, 1) < 0) { perror("zfs_recv: dup2(stdout)"); exit(1); } /* run the <program> and its args */ argv++; argc--; argv[0] = "/usr/sbin/zfs"; // replace host argv[1] = "recv"; // replace port execvp(*argv, argv); // now 'zfs recv <args>' /* if we got here we failed. */ perror("zfs_recv: execvp()"); exit(1); }
void bg_child(char **commands){ execvp(commands[1], commands); }
int main(int argc, char *argv[]) { pid_t child_pid; struct termios tty_attr; struct winsize window_size; int pty_master; int retval = 0; /* for select */ fd_set readfds; fd_set writefds; fd_set exceptfds; int err_count = 0; /* for sigtimedwait() */ struct timespec timeout; char buf[16384]; if (argc == 1) { printf("usage: %s PROGRAM [ARGS]...\n", argv[0]); exit(1); } sigset_t signal_set; siginfo_t signalinfo; /* set up SIGCHLD */ sigemptyset(&signal_set); /* no signals */ sigaddset(&signal_set, SIGCHLD); /* Add sig child */ sigprocmask(SIG_BLOCK, &signal_set, NULL); /* Block the signal */ /* Set both to 0, so sigtimed wait just does a poll */ timeout.tv_sec=0; timeout.tv_nsec=0; if(isatty(fileno(stdin))) { /* get terminal parameters associated with stdout */ if(tcgetattr(fileno(stdout), &tty_attr) < 0) { perror("tcgetattr:"); exit(EX_OSERR); } /* end of if(tcsetattr(&tty_attr)) */ /* get window size */ if( ioctl(fileno(stdout), TIOCGWINSZ, &window_size) < 0 ) { perror("ioctl stdout:"); exit(1); } child_pid = forkpty(&pty_master, NULL, &tty_attr, &window_size); } /* end of if(isatty(fileno(stdin))) */ else { /* not interactive */ child_pid = forkpty(&pty_master, NULL, NULL, NULL); } if(child_pid < 0) { perror("Fork:"); fflush(stdout); fflush(stderr); exit(EX_OSERR); } /* end of if(child_pid < 0) */ if(child_pid == 0) { /* in the child */ struct termios s_tty_attr; if(tcgetattr(fileno(stdin), &s_tty_attr)) { perror("Child:"); fflush(stdout); fflush(stderr); exit(EXIT_FAILURE); } /* Turn off echo */ s_tty_attr.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); /* Also turn of NL to CR?LF on output */ s_tty_attr.c_oflag &= ~(ONLCR); if(tcsetattr(fileno(stdin), TCSANOW, &s_tty_attr)) { perror("Child:"); exit(EXIT_FAILURE); } { /* There is no reason to block sigchild for the process we shall exec here */ sigset_t chld_signal_set; /* release SIGCHLD */ sigemptyset(&chld_signal_set); /* no signals */ sigaddset(&chld_signal_set, SIGCHLD); /* Add sig child */ sigprocmask(SIG_UNBLOCK, &chld_signal_set, NULL); /* Unblock the signal */ } if ( execvp(argv[1], argv + 1) ) { perror("Exec:"); fflush(stdout); fflush(stderr); exit(EXIT_FAILURE); } } /* end of if(child_pid == 0) */ /* * OK. Prepare to handle IO from the child. We need to transfer * everything from the child's stdout to ours. */ FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds); /* * Read current file descriptor flags, preparing to do non blocking reads */ retval=fcntl(pty_master,F_GETFL); if(retval<0) { perror("fcntl_get"); fflush(stdout); fflush(stderr); exit(EX_IOERR); } /* Set the connection to be non-blocking */ if(fcntl(pty_master,F_SETFL, retval | O_NONBLOCK) < 0) { perror("fcnt_setFlag_nonblock:"); fflush(stdout); fflush(stderr); exit(1); } FD_SET(pty_master, &readfds); FD_SET(pty_master, &writefds); FD_SET(fileno(stdin), &readfds); if(isatty(fileno(stdin))) { if(tty_semi_raw(fileno(stdin)) < 0) { perror("Error: settingraw mode:"); fflush(stdout); fflush(stderr); } /* end of if(tty_raw(fileno(stdin)) < 0) */ if(atexit(tty_atexit) < 0) { perror("Atexit setup:"); fflush(stdout); fflush(stderr); } /* end of if(atexit(tty_atexit) < 0) */ } /* ignore return from nice, but lower our priority */ int ignore __attribute__ ((unused)) = nice(19); /* while no signal, we loop around */ int done = 0; while(! done) { struct timeval interval; fd_set t_readfds; fd_set t_writefds; fd_set t_exceptfds; /* * We still use a blocked signal, and check for SIGCHLD every * loop, since waiting infinitely did not really help the load * when running, say, top. */ interval.tv_sec = 0; interval.tv_usec = 200000; /* so, check for signals every 200 milli seconds */ t_readfds = readfds; t_writefds = writefds; t_exceptfds = exceptfds; /* check for the signal */ retval = sigtimedwait(&signal_set, &signalinfo,&timeout); if( retval == SIGCHLD ) { /* child terminated */ done = 1; /* in case they do not close off their file descriptors */ } else { if( retval < 0 ) { if(errno != EAGAIN) { perror("sigtimedwait"); fflush(stdout); fflush(stderr); exit(EX_IOERR); } else { /* No signal in set was delivered within the timeout period specified */ } } } /* end of else */ if(select (pty_master + 1, &t_readfds, &t_writefds, &t_exceptfds, &interval) < 0) { perror("Select:"); fflush(stdout); fflush(stderr); exit (EX_IOERR); } if(FD_ISSET(pty_master, &t_readfds)) { retval = read(pty_master, buf, (unsigned int)16384); if(retval < 0) { if(errno != EINTR && errno != EAGAIN) { /* Nothing left to read? */ fflush(stdout); fflush(stderr); /* fprintf(stderr, "DEBUG: %d: Nothing left to read?\n", __LINE__);*/ exit (EXIT_SUCCESS); } /* end of else */ } /* end of if(retval < 0) */ else { if(retval == 0) { if(++err_count > 5) { /* child closed connection */ fflush(stdout); fflush(stderr); /*fprintf(stderr, "DEBUG: %d: child closed connection?\n", __LINE__);*/ exit (EXIT_SUCCESS); } } /* end of if(retval == 0) */ else { ssize_t nleft = retval; ssize_t nwritten = 0; char * ptr = buf; while(nleft > 0) { if((nwritten = write(fileno(stdout), ptr, (unsigned int)nleft)) <= 0) { if(errno == EINTR) { nwritten = 0; } /* end of if(errno == EINTR) */ else { perror("write"); fflush(stdout); fflush(stderr); exit (EXIT_SUCCESS); } /* end of else */ } /* end of if((nwritten = write(sockfd, ptr, nleft)) <= 0) */ nleft -= nwritten; ptr += nwritten; } /* end of while(nleft > 0) */ /* fprintf(stderr, "DEBUG: %d: wrote %d\n", __LINE__, retval);*/ fflush(stdout); } /* end of else */ } /* end of else */ } if(FD_ISSET(fileno(stdin), &t_readfds)) { if(FD_ISSET(pty_master, &t_writefds)) { retval = read(fileno(stdin), buf, (unsigned int)16384); if(retval < 0) { if(errno != EINTR && errno != EAGAIN) { /* Nothing left to read? */ fflush(stdout); fflush(stderr); exit (EXIT_SUCCESS); } /* end of else */ } /* end of if(retval < 0) */ else { if(retval == 0) { if(++err_count > 5) { /* lost controlling tty */ fflush(stdout); fflush(stderr); exit (EXIT_SUCCESS); } } /* end of if(retval == 0) */ else { ssize_t nleft = retval; ssize_t nwritten = 0; char * ptr = buf; while(nleft > 0) { if((nwritten = write(pty_master, ptr, (unsigned int)nleft)) <= 0) { if(errno == EINTR) { nwritten = 0; } /* end of if(errno == EINTR) */ else { perror("write"); fflush(stdout); fflush(stderr); exit (EXIT_SUCCESS); } /* end of else */ } /* end of if((nwritten = write(sockfd, ptr, nleft)) <= 0) */ nleft -= nwritten; ptr += nwritten; } /* end of while(nleft > 0) */ fflush(stdout); } /* end of else */ } /* end of else */ } /* end of if(FD_ISSET(pty_master, &writefds)) */ } /* something to read on stdin */ } /* Loop */ fflush(stdout); fflush(stderr); exit(EXIT_SUCCESS); } /* end of main() */
int main(int argc, char *argv[]) { char **args = alloca(sizeof(char*) * (argc+12)); int i, j; char execpath[PATH_MAX+1]; char sdkpath[PATH_MAX+1]; char codesign_allocate[64]; char osvermin[64]; char *compiler; char *target; char *sdk; char *cpu; char *osmin; target_info(argv, &target, &compiler); if (!get_executable_path(execpath, sizeof(execpath))) abort(); snprintf(sdkpath, sizeof(sdkpath), "%s/../SDK", execpath); snprintf(codesign_allocate, sizeof(codesign_allocate), "%s-codesign_allocate", target); setenv("CODESIGN_ALLOCATE", codesign_allocate, 1); setenv("IOS_FAKE_CODE_SIGN", "1", 1); env(&sdk, "IOS_SDK_SYSROOT", sdkpath); env(&cpu, "IOS_TARGET_CPU", TARGET_CPU); env(&osmin, "IPHONEOS_DEPLOYMENT_TARGET", OS_VER_MIN); unsetenv("IPHONEOS_DEPLOYMENT_TARGET"); snprintf(osvermin, sizeof(osvermin), "-miphoneos-version-min=%s", osmin); for (i = 1; i < argc; ++i) { if (!strcmp(argv[i], "-arch")) { cpu = NULL; break; } } i = 0; args[i++] = compiler; args[i++] = "-target"; args[i++] = target; args[i++] = "-isysroot"; args[i++] = sdk; if (cpu) { args[i++] = "-arch"; args[i++] = cpu; } args[i++] = osvermin; args[i++] = "-mlinker-version=241.9"; for (j = 1; j < argc; ++i, ++j) args[i] = argv[j]; args[i] = NULL; setenv("COMPILER_PATH", execpath, 1); execvp(compiler, args); fprintf(stderr, "cannot invoke compiler!\n"); return 1; }
/** * mate_execute_async_with_env_fds: * @dir: Directory in which child should be executed, or %NULL for current * directory * @argc: Number of arguments * @argv: Argument vector to exec child * @envc: Number of environment slots * @envv: Environment vector * @close_fds: If %TRUE will close all fds but 0,1, and 2 * * Description: Like mate_execute_async_with_env() but has a flag to * decide whether or not to close fd's * * Returns: the process id, or %-1 on error. **/ int mate_execute_async_with_env_fds (const char* dir, int argc, char* const argv[], int envc, char* const envv[], gboolean close_fds) { #ifndef G_OS_WIN32 int parent_comm_pipes[2], child_comm_pipes[2]; int child_errno, itmp, i, open_max; gssize res; char** cpargv; pid_t child_pid, immediate_child_pid; if(pipe(parent_comm_pipes)) return -1; child_pid = immediate_child_pid = fork(); switch (child_pid) { case -1: close(parent_comm_pipes[0]); close(parent_comm_pipes[1]); return -1; case 0: /* START PROCESS 1: child */ child_pid = -1; res = pipe(child_comm_pipes); close(parent_comm_pipes[0]); if (!res) child_pid = fork(); switch (child_pid) { case -1: itmp = errno; child_pid = -1; /* simplify parent code */ write(parent_comm_pipes[1], &child_pid, sizeof(child_pid)); write(parent_comm_pipes[1], &itmp, sizeof(itmp)); close(child_comm_pipes[0]); close(child_comm_pipes[1]); _exit(0); break; /* END PROCESS 1: monkey in the middle dies */ default: { char buf[16]; close(child_comm_pipes[1]); while ((res = safe_read(child_comm_pipes[0], buf, sizeof(buf))) > 0) write(parent_comm_pipes[1], buf, res); close(child_comm_pipes[0]); _exit(0); /* END PROCESS 1: monkey in the middle dies */ } break; case 0: /* START PROCESS 2: child of child */ close(parent_comm_pipes[1]); /* pre-exec setup */ close (child_comm_pipes[0]); set_cloexec (child_comm_pipes[1]); child_pid = getpid(); res = write(child_comm_pipes[1], &child_pid, sizeof(child_pid)); if (envv) { for (itmp = 0; itmp < envc; itmp++) putenv(envv[itmp]); } if (dir) { if (chdir(dir)) _exit(-1); } cpargv = g_alloca((argc + 1) * sizeof(char *)); memcpy(cpargv, argv, argc * sizeof(char *)); cpargv[argc] = NULL; if(close_fds) { int stdinfd; /* Close all file descriptors but stdin stdout and stderr */ open_max = sysconf(_SC_OPEN_MAX); for (i = 3; i < open_max; i++) set_cloexec (i); if(child_comm_pipes[1] != 0) { close(0); /* Open stdin as being nothingness, so that if someone tries to read from this they don't hang up the whole MATE session. BUGFIX #1548 */ stdinfd = open("/dev/null", O_RDONLY); g_assert(stdinfd >= 0); if (stdinfd != 0) { dup2(stdinfd, 0); close(stdinfd); } } } setsid(); signal(SIGPIPE, SIG_DFL); /* doit */ execvp(cpargv[0], cpargv); /* failed */ itmp = errno; write(child_comm_pipes[1], &itmp, sizeof(itmp)); _exit(1); break; /* END PROCESS 2 */ } break; default: /* parent process */ /* do nothing */ break; } close(parent_comm_pipes[1]); res = safe_read(parent_comm_pipes[0], &child_pid, sizeof(child_pid)); if (res != sizeof(child_pid)) { g_message("res is %ld instead of %d", (long) res, (int) sizeof(child_pid)); child_pid = -1; /* really weird things happened */ } else if (safe_read(parent_comm_pipes[0], &child_errno, sizeof(child_errno)) == sizeof(child_errno)) { errno = child_errno; child_pid = -1; } /* do this after the read's in case some OS's handle blocking on pipe writes * differently */ while ((waitpid(immediate_child_pid, &itmp, 0)== -1) && (errno == EINTR)) ; /* eat zombies */ close(parent_comm_pipes[0]); if(child_pid < 0) g_message("mate_execute_async_with_env_fds: returning %d", child_pid); return child_pid; #else /* !G_OS_WIN32 */ /* FIXME: Implement if needed */ g_warning("mate_execute_async_with_env_fds: Not implemented"); return -1; #endif /* G_OS_WIN32 */ }
PRIVATE void run_a_command ARGS1(char *, command) { char **argv; int argc; char *str; int alen; alen = 10; argv = (char **)malloc(10 * sizeof(char *)); if (argv == NULL) { return; } argc = 0; str = strtok(command, " \t\n"); while (str != NULL) { argv[argc] = strdup(str); argc++; if (argc >= alen) { int i; char **tmp_av; tmp_av = (char **)malloc((alen + 10) * sizeof(char *)); if (tmp_av == NULL) { return; } for (i=0; i<alen; i++) { tmp_av[i] = argv[i]; } alen += 10; free((char *)argv); argv = tmp_av; } str = strtok(NULL, " \t\n"); } argv[argc] = NULL; if (fork() == 0) { execvp(argv[0], argv); } else { int i; /* * The signal handler in main.c will clean this child * up when it exits. */ for (i=0; i<argc; i++) { if (argv[i] != NULL) { free(argv[i]); } } free((char *)argv); } }
void spawn_filter(const char *filter_command) { int input_pipe_fds[2]; int output_pipe_fds[2]; mypipe(input_pipe_fds); filter_input_fd = input_pipe_fds[1]; /* rlwrap writes filter input to this */ mypipe(output_pipe_fds); filter_output_fd = output_pipe_fds[0]; /* rlwrap reads filter output from here */ DPRINTF1(DEBUG_FILTERING, "preparing to spawn filter <%s>", filter_command); assert(!command_pid || signal_handlers_were_installed); /* if there is a command, then signal handlers are installed */ if ((filter_pid = fork()) < 0) myerror(FATAL|USE_ERRNO, "Cannot spawn filter '%s'", filter_command); else if (filter_pid == 0) { /* child */ int signals_to_allow[] = {SIGPIPE, SIGCHLD, SIGALRM, SIGUSR1, SIGUSR2}; char **argv; unblock_signals(signals_to_allow); /* when we run a pager from a filter we want to catch these */ DEBUG_RANDOM_SLEEP; i_am_child = TRUE; /* set environment for filter (it needs to know at least the file descriptors for its input and output) */ if (!getenv("RLWRAP_FILTERDIR")) mysetenv("RLWRAP_FILTERDIR", add2strings(DATADIR,"/rlwrap/filters")); mysetenv("PATH", add3strings(getenv("RLWRAP_FILTERDIR"),":",getenv("PATH"))); mysetenv("RLWRAP_VERSION", VERSION); mysetenv("RLWRAP_COMMAND_PID", as_string(command_pid)); mysetenv("RLWRAP_COMMAND_LINE", command_line); if (impatient_prompt) mysetenv("RLWRAP_IMPATIENT", "1"); mysetenv("RLWRAP_INPUT_PIPE_FD", as_string(input_pipe_fds[0])); mysetenv("RLWRAP_OUTPUT_PIPE_FD", as_string(output_pipe_fds[1])); mysetenv("RLWRAP_MASTER_PTY_FD", as_string(master_pty_fd)); close(filter_input_fd); close(filter_output_fd); if (scan_metacharacters(filter_command, "'|\"><")) { /* if filter_command contains shell metacharacters, let the shell unglue them */ char *exec_command = add3strings("exec", " ", filter_command); argv = list4("sh", "-c", exec_command, NULL); } else { /* if not, split and feed to execvp directly (cheaper, better error message) */ argv = split_with(filter_command, " "); } assert(argv[0]); if(execvp(argv[0], argv) < 0) { char *sorry = add3strings("Cannot exec filter '", argv[0], add2strings("': ", strerror(errno))); write_message(output_pipe_fds[1], TAG_ERROR, sorry, "to stdout"); /* this will kill rlwrap */ mymicrosleep(100 * 1000); /* 100 sec for rlwrap to go away should be enough */ exit (-1); } assert(!"not reached"); } else { DEBUG_RANDOM_SLEEP; signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE - we have othere ways to deal with filter death */ DPRINTF1(DEBUG_FILTERING, "spawned filter with pid %d", filter_pid); close (input_pipe_fds[0]); close (output_pipe_fds[1]); } }
/* Start frozen application in a subprocess. The frozen application runs * in a subprocess. */ int pyi_utils_create_child(const char *thisfile, const int argc, char *const argv[]) { pid_t pid = 0; int rc = 0; int i; argv_pyi = (char**)calloc(argc+1,sizeof(char*)); argc_pyi = 0; for (i = 0; i < argc; i++) { #if defined(__APPLE__) && defined(WINDOWED) // if we are on a Mac, it passes a strange -psnxxx argument. Filter it out. if (strstr(argv[i],"-psn") == argv[i]) { // skip } else #endif { argv_pyi[argc_pyi++] = strdup(argv[i]); } } #if defined(__APPLE__) && defined(WINDOWED) process_apple_events(); #endif pid = fork(); /* Child code. */ if (pid == 0) /* Replace process by starting a new application. */ execvp(thisfile, argv_pyi); /* Parent code. */ else { child_pid = pid; /* Redirect termination signals received by parent to child process. */ signal(SIGINT, &_signal_handler); signal(SIGKILL, &_signal_handler); signal(SIGTERM, &_signal_handler); } wait(&rc); /* Parent code. */ if(child_pid != 0 ) { /* When child process exited, reset signal handlers to default values. */ signal(SIGINT, SIG_DFL); signal(SIGKILL, SIG_DFL); signal(SIGTERM, SIG_DFL); for (i = 0; i < argc_pyi; i++) free(argv_pyi[i]); free(argv_pyi); } if (WIFEXITED(rc)) return WEXITSTATUS(rc); /* Process ended abnormally */ if (WIFSIGNALED(rc)) /* Mimick the signal the child received */ raise(WTERMSIG(rc)); return 1; }
int main(int argc, char *argv[]) { fd_set rfds; /* the structure for the select call */ int code; /* return code from system calls */ char out_buff[MAXLINE]; /* from child and stdin */ int out_flag[MAXLINE] ; /* initialize the output flags */ char *program; /* a string to hold the child program invocation */ char **pargs = 0; /* holds parts of the command line */ int not_command = 1; /* a flag while parsing the command line */ /* try to get a pseudoterminal to play with */ if (ptyopen(&contNum, &serverNum, controllerPath, serverPath) == -1) { perror("ptyopen failed"); exit(-1); } /* call the routine that handles signals */ catch_signals(); /* parse the command line arguments - as with the aixterm the command argument -e should be last on the line. */ while(*++argv && not_command) { if(!strcmp(*argv, "-f")) load_wct_file(*++argv); else if(!strcmp(*argv, "-e")) { not_command = 0; pargs = ++argv; } else { fprintf(stderr, "usage: clef [-f fname] -e command\n"); exit(-1); } } skim_wct(); #ifdef log sprintf(logpath, "/tmp/cleflog%d", getpid()); logfd = open(logpath, O_CREAT | O_RDWR, 0666); #endif /* get the original termio settings, so the child has them */ if(tcgetattr(0,&childbuf) == -1) { perror("clef trying to get the initial terminal settings"); exit(-1); } /* start the child process */ child_pid = fork(); switch(child_pid) { case -1 : perror("clef can't create a new process"); exit(-1); case 0: /* CHILD */ /* Dissasociate form my parents group so all my child processes look at my terminal as the controlling terminal for the group */ setsid(); serverNum = open(serverPath,O_RDWR); if (serverNum == -1) perror("open serverPath failed"); /* since I am the child, I can close ptc, and dup pts for all it standard descriptors */ if (dup2(serverNum, 0) == -1) perror("dup2 0 failed"); if (dup2(serverNum, 1) == -1) perror("dup2 1 failed"); if (dup2(serverNum, 2) == -1) perror("dup2 2 failed"); if( (dup2(serverNum, 0) == -1) || (dup2(serverNum, 1) == -1) || (dup2(serverNum, 2) == -1) ) { perror("clef trying to dup2"); exit(-1); } /* since they have been duped, close them */ close(serverNum); close(contNum); /* To make sure everything is nice, set off enhedit */ /* childbuf.c_line = 0; */ /* reconfigure the child's terminal get echoing */ if(tcsetattr(0, TCSAFLUSH, &childbuf) == -1) { perror("clef child trying to set child's terminal"); exit(-1); } /* fire up the child's process */ if(pargs){ execvp( pargs[0], pargs); perror("clef trying to execvp its argument"); fprintf(stderr, "Process --> %s\n", pargs[0]); } else{ program = getenv("SHELL"); if (!program) program = strdup("/bin/sh"); else program = strdup (program); execlp( program,program, 0); perror("clef trying to execlp the default child"); fprintf(stderr, "Process --> %s\n", program); } exit(-1); break; /* end switch */ } /* PARENT */ /* Since I am the parent, I should start to initialize some stuff. I have to close the pts side for it to work properly */ close(serverNum); ppid = getppid(); /* Iinitialize some stuff for the reading and writing */ init_flag(out_flag, MAXLINE); define_function_keys(); init_reader(); PTY = 1; init_parent(); /* Here is the main loop, it simply starts reading characters from the std input, and from the child. */ while(1) { /* loop forever */ /* use select to see who has stuff waiting for me to handle */ /* set file descriptors for ptc and stdin */ FD_ZERO(&rfds); FD_SET(contNum,&rfds); FD_SET(0,&rfds); set_function_chars(); #ifdef log { char modepath[30]; sprintf(modepath, "\nMODE = %d\n", MODE); write(logfd, modepath, strlen(modepath)); } #endif #ifdef logterm { struct termio ptermio; char pbuff[1024]; tcgetattr(contNum, &ptermio); sprintf(pbuff, "child's settings: Lflag = %d, Oflag = %d, Iflag = %d\n", ptermio.c_lflag, ptermio.c_oflag, ptermio.c_iflag); write(logfd, pbuff, strlen(pbuff)); } #endif code = select(FD_SETSIZE,(void *) &rfds, NULL, NULL, NULL); for(; code < 0 ;) { if(errno == EINTR) { check_flip(); code = select(FD_SETSIZE,(void *) &rfds, NULL, NULL, NULL); } else { perror("clef select failure"); exit(-1); } } /* reading from the child **/ if( FD_ISSET(contNum,&rfds)) { if( (num_read = read(contNum, out_buff, MAXLINE)) == -1) { num_read = 0; } #ifdef log write(logfd, "OUT<<<<<", strlen("OUT<<<<<")); write(logfd, out_buff, num_read); #endif if(num_read > 0) { /* now do the printing to the screen */ if(MODE!= CLEFRAW) { back_up(buff_pntr); write(1,out_buff, num_read); print_whole_buff(); /* reprint the input buffer */ } else write(1,out_buff, num_read); } } /* done the child stuff */ /* I should read from std input */ else { if(FD_ISSET(0,&rfds)) { num_read = read(0, in_buff, MAXLINE); #ifdef log write(logfd, "IN<<<<<", strlen("IN<<<<<")); write(logfd, in_buff, num_read); #endif check_flip(); if(MODE == CLEFRAW ) write(contNum, in_buff, num_read); else do_reading(); } } } }
int main(int argc, char *argv[], char *envp[]) { pid_t pid = 0, tree_id = 0; int ret = -1; bool usage_error = true; bool has_exec_cmd = false; int opt, idx; int log_level = LOG_UNSET; char *imgs_dir = "."; char *work_dir = NULL; static const char short_opts[] = "dSsRf:F:t:p:hcD:o:n:v::x::Vr:jlW:L:M:"; static struct option long_opts[] = { { "tree", required_argument, 0, 't' }, { "pid", required_argument, 0, 'p' }, { "leave-stopped", no_argument, 0, 's' }, { "leave-running", no_argument, 0, 'R' }, { "restore-detached", no_argument, 0, 'd' }, { "restore-sibling", no_argument, 0, 'S' }, { "daemon", no_argument, 0, 'd' }, { "contents", no_argument, 0, 'c' }, { "file", required_argument, 0, 'f' }, { "fields", required_argument, 0, 'F' }, { "images-dir", required_argument, 0, 'D' }, { "work-dir", required_argument, 0, 'W' }, { "log-file", required_argument, 0, 'o' }, { "namespaces", required_argument, 0, 'n' }, { "root", required_argument, 0, 'r' }, { USK_EXT_PARAM, optional_argument, 0, 'x' }, { "help", no_argument, 0, 'h' }, { SK_EST_PARAM, no_argument, 0, 1042 }, { "close", required_argument, 0, 1043 }, { "log-pid", no_argument, 0, 1044 }, { "version", no_argument, 0, 'V' }, { "evasive-devices", no_argument, 0, 1045 }, { "pidfile", required_argument, 0, 1046 }, { "veth-pair", required_argument, 0, 1047 }, { "action-script", required_argument, 0, 1049 }, { LREMAP_PARAM, no_argument, 0, 1041 }, { OPT_SHELL_JOB, no_argument, 0, 'j' }, { OPT_FILE_LOCKS, no_argument, 0, 'l' }, { "page-server", no_argument, 0, 1050 }, { "address", required_argument, 0, 1051 }, { "port", required_argument, 0, 1052 }, { "prev-images-dir", required_argument, 0, 1053 }, { "ms", no_argument, 0, 1054 }, { "track-mem", no_argument, 0, 1055 }, { "auto-dedup", no_argument, 0, 1056 }, { "libdir", required_argument, 0, 'L' }, { "cpu-cap", optional_argument, 0, 1057 }, { "force-irmap", no_argument, 0, 1058 }, { "ext-mount-map", required_argument, 0, 'M' }, { "exec-cmd", no_argument, 0, 1059 }, { "manage-cgroups", optional_argument, 0, 1060 }, { "cgroup-root", required_argument, 0, 1061 }, { "inherit-fd", required_argument, 0, 1062 }, { "feature", required_argument, 0, 1063 }, { "skip-mnt", required_argument, 0, 1064 }, { "enable-fs", required_argument, 0, 1065 }, { "enable-external-sharing", no_argument, 0, 1066 }, { "enable-external-masters", no_argument, 0, 1067 }, { "freeze-cgroup", required_argument, 0, 1068 }, { "ghost-limit", required_argument, 0, 1069 }, { }, }; BUILD_BUG_ON(PAGE_SIZE != PAGE_IMAGE_SIZE); cr_pb_init(); if (restrict_uid(getuid(), getgid())) return 1; setproctitle_init(argc, argv, envp); if (argc < 2) goto usage; init_opts(); if (init_service_fd()) return 1; if (!strcmp(argv[1], "swrk")) { if (argc < 3) goto usage; /* * This is to start criu service worker from libcriu calls. * The usage is "criu swrk <fd>" and is not for CLI/scripts. * The arguments semantics can change at any tyme with the * corresponding lib call change. */ opts.swrk_restore = true; return cr_service_work(atoi(argv[2])); } while (1) { idx = -1; opt = getopt_long(argc, argv, short_opts, long_opts, &idx); if (opt == -1) break; switch (opt) { case 's': opts.final_state = TASK_STOPPED; break; case 'R': opts.final_state = TASK_ALIVE; break; case 'x': if (optarg && unix_sk_ids_parse(optarg) < 0) return 1; opts.ext_unix_sk = true; break; case 'p': pid = atoi(optarg); if (pid <= 0) goto bad_arg; break; case 't': tree_id = atoi(optarg); if (tree_id <= 0) goto bad_arg; break; case 'c': opts.show_pages_content = true; break; case 'f': opts.show_dump_file = optarg; break; case 'F': opts.show_fmt = optarg; break; case 'r': opts.root = optarg; break; case 'd': opts.restore_detach = true; break; case 'S': opts.restore_sibling = true; break; case 'D': imgs_dir = optarg; break; case 'W': work_dir = optarg; break; case 'o': opts.output = optarg; break; case 'n': if (parse_ns_string(optarg)) goto bad_arg; break; case 'v': if (log_level == LOG_UNSET) log_level = 0; if (optarg) { if (optarg[0] == 'v') /* handle -vvvvv */ log_level += strlen(optarg) + 1; else log_level = atoi(optarg); } else log_level++; break; case 1041: pr_info("Will allow link remaps on FS\n"); opts.link_remap_ok = true; break; case 1042: pr_info("Will dump TCP connections\n"); opts.tcp_established_ok = true; break; case 1043: { int fd; fd = atoi(optarg); pr_info("Closing fd %d\n", fd); close(fd); break; } case 1044: opts.log_file_per_pid = 1; break; case 1045: opts.evasive_devices = true; break; case 1046: opts.pidfile = optarg; break; case 1047: { char *aux; aux = strchr(optarg, '='); if (aux == NULL) goto bad_arg; *aux = '\0'; if (veth_pair_add(optarg, aux + 1)) return 1; } break; case 1049: if (add_script(optarg, 0)) return 1; break; case 1050: opts.use_page_server = true; break; case 1051: opts.addr = optarg; break; case 1052: opts.ps_port = htons(atoi(optarg)); if (!opts.ps_port) goto bad_arg; break; case 'j': opts.shell_job = true; break; case 'l': opts.handle_file_locks = true; break; case 1053: opts.img_parent = optarg; break; case 1055: opts.track_mem = true; break; case 1056: opts.auto_dedup = true; break; case 1057: if (parse_cpu_cap(&opts, optarg)) goto usage; break; case 1058: opts.force_irmap = true; break; case 1054: opts.check_ms_kernel = true; break; case 'L': opts.libdir = optarg; break; case 1059: has_exec_cmd = true; break; case 1060: if (parse_manage_cgroups(&opts, optarg)) goto usage; break; case 1061: { char *path, *ctl; path = strchr(optarg, ':'); if (path) { *path = '\0'; path++; ctl = optarg; } else { path = optarg; ctl = NULL; } if (new_cg_root_add(ctl, path)) return -1; } break; case 1062: if (inherit_fd_parse(optarg) < 0) return 1; break; case 1063: if (check_add_feature(optarg) < 0) return 1; break; case 1064: if (!add_skip_mount(optarg)) return 1; break; case 1065: if (!add_fsname_auto(optarg)) return 1; break; case 1066: opts.enable_external_sharing = true; break; case 1067: opts.enable_external_masters = true; break; case 1068: opts.freeze_cgroup = optarg; break; case 1069: opts.ghost_limit = parse_size(optarg); break; case 'M': { char *aux; if (strcmp(optarg, "auto") == 0) { opts.autodetect_ext_mounts = true; break; } aux = strchr(optarg, ':'); if (aux == NULL) goto bad_arg; *aux = '\0'; if (ext_mount_add(optarg, aux + 1)) return 1; } break; case 'V': pr_msg("Version: %s\n", CRIU_VERSION); if (strcmp(CRIU_GITID, "0")) pr_msg("GitID: %s\n", CRIU_GITID); return 0; case 'h': usage_error = false; goto usage; default: goto usage; } } if (!opts.restore_detach && opts.restore_sibling) { pr_msg("--restore-sibling only makes sense with --restore-detach\n"); return 1; } if (!opts.autodetect_ext_mounts && (opts.enable_external_masters || opts.enable_external_sharing)) { pr_msg("must specify --ext-mount-map auto with --enable-external-{sharing|masters}"); return 1; } if (work_dir == NULL) work_dir = imgs_dir; if (optind >= argc) { pr_msg("Error: command is required\n"); goto usage; } if (has_exec_cmd) { if (argc - optind <= 1) { pr_msg("Error: --exec-cmd requires a command\n"); goto usage; } if (strcmp(argv[optind], "restore")) { pr_msg("Error: --exec-cmd is available for the restore command only\n"); goto usage; } if (opts.restore_detach) { pr_msg("Error: --restore-detached and --exec-cmd cannot be used together\n"); goto usage; } opts.exec_cmd = xmalloc((argc - optind) * sizeof(char *)); if (!opts.exec_cmd) return 1; memcpy(opts.exec_cmd, &argv[optind + 1], (argc - optind - 1) * sizeof(char *)); opts.exec_cmd[argc - optind - 1] = NULL; } else if (optind + 1 != argc) { pr_err("Unable to handle more than one command\n"); goto usage; } /* We must not open imgs dir, if service is called */ if (strcmp(argv[optind], "service")) { ret = open_image_dir(imgs_dir); if (ret < 0) return 1; } if (chdir(work_dir)) { pr_perror("Can't change directory to %s", work_dir); return 1; } log_set_loglevel(log_level); if (log_init(opts.output)) return 1; if (!list_empty(&opts.inherit_fds)) { if (strcmp(argv[optind], "restore")) { pr_err("--inherit-fd is restore-only option\n"); return 1; } /* now that log file is set up, print inherit fd list */ inherit_fd_log(); } if (opts.img_parent) pr_info("Will do snapshot from %s\n", opts.img_parent); if (!strcmp(argv[optind], "dump")) { preload_socket_modules(); if (!tree_id) goto opt_pid_missing; return cr_dump_tasks(tree_id); } if (!strcmp(argv[optind], "pre-dump")) { if (!tree_id) goto opt_pid_missing; return cr_pre_dump_tasks(tree_id) != 0; } if (!strcmp(argv[optind], "restore")) { if (tree_id) pr_warn("Using -t with criu restore is obsoleted\n"); ret = cr_restore_tasks(); if (ret == 0 && opts.exec_cmd) { close_pid_proc(); execvp(opts.exec_cmd[0], opts.exec_cmd); pr_perror("Failed to exec command %s", opts.exec_cmd[0]); ret = 1; } return ret != 0; } if (!strcmp(argv[optind], "show")) return cr_show(pid) != 0; if (!strcmp(argv[optind], "check")) return cr_check() != 0; if (!strcmp(argv[optind], "exec")) { if (!pid) pid = tree_id; /* old usage */ if (!pid) goto opt_pid_missing; return cr_exec(pid, argv + optind + 1) != 0; } if (!strcmp(argv[optind], "page-server")) return cr_page_server(opts.daemon_mode, -1) > 0 ? 0 : 1; if (!strcmp(argv[optind], "service")) return cr_service(opts.daemon_mode); if (!strcmp(argv[optind], "dedup")) return cr_dedup() != 0; if (!strcmp(argv[optind], "cpuinfo")) { if (!argv[optind + 1]) goto usage; if (!strcmp(argv[optind + 1], "dump")) return cpuinfo_dump(); else if (!strcmp(argv[optind + 1], "check")) return cpuinfo_check(); } pr_msg("Error: unknown command: %s\n", argv[optind]); usage: pr_msg("\n" "Usage:\n" " criu dump|pre-dump -t PID [<options>]\n" " criu restore [<options>]\n" " criu check [--ms]\n" " criu exec -p PID <syscall-string>\n" " criu page-server\n" " criu service [<options>]\n" " criu dedup\n" "\n" "Commands:\n" " dump checkpoint a process/tree identified by pid\n" " pre-dump pre-dump task(s) minimizing their frozen time\n" " restore restore a process/tree\n" " check checks whether the kernel support is up-to-date\n" " exec execute a system call by other task\n" " page-server launch page server\n" " service launch service\n" " dedup remove duplicates in memory dump\n" " cpuinfo dump writes cpu information into image file\n" " cpuinfo check validates cpu information read from image file\n" ); if (usage_error) { pr_msg("\nTry -h|--help for more info\n"); return 1; } pr_msg("\n" "Dump/Restore options:\n" "\n" "* Generic:\n" " -t|--tree PID checkpoint a process tree identified by PID\n" " -d|--restore-detached detach after restore\n" " -S|--restore-sibling restore root task as sibling\n" " -s|--leave-stopped leave tasks in stopped state after checkpoint\n" " -R|--leave-running leave tasks in running state after checkpoint\n" " -D|--images-dir DIR directory for image files\n" " --pidfile FILE write root task, service or page-server pid to FILE\n" " -W|--work-dir DIR directory to cd and write logs/pidfiles/stats to\n" " (if not specified, value of --images-dir is used)\n" " --cpu-cap [CAP] require certain cpu capability. CAP: may be one of:\n" " 'cpu','fpu','all','ins','none'. To disable capability, prefix it with '^'.\n" " --exec-cmd execute the command specified after '--' on successful\n" " restore making it the parent of the restored process\n" " --freeze-cgroup\n" " use cgroup freezer to collect processes\n" "\n" "* Special resources support:\n" " -x|--" USK_EXT_PARAM "inode,.." " allow external unix connections (optionally can be assign socket's inode that allows one-sided dump)\n" " --" SK_EST_PARAM " checkpoint/restore established TCP connections\n" " -r|--root PATH change the root filesystem (when run in mount namespace)\n" " --evasive-devices use any path to a device file if the original one\n" " is inaccessible\n" " --veth-pair IN=OUT map inside veth device name to outside one\n" " can optionally append @<bridge-name> to OUT for moving\n" " the outside veth to the named bridge\n" " --link-remap allow one to link unlinked files back when possible\n" " --ghost-limit size specify maximum size of deleted file contents to be carried inside an image file\n" " --action-script FILE add an external action script\n" " -j|--" OPT_SHELL_JOB " allow one to dump and restore shell jobs\n" " -l|--" OPT_FILE_LOCKS " handle file locks, for safety, only used for container\n" " -L|--libdir path to a plugin directory (by default " CR_PLUGIN_DEFAULT ")\n" " --force-irmap force resolving names for inotify/fsnotify watches\n" " -M|--ext-mount-map KEY:VALUE\n" " add external mount mapping\n" " -M|--ext-mount-map auto\n" " attempt to autodetect external mount mapings\n" " --enable-external-sharing\n" " allow autoresolving mounts with external sharing\n" " --enable-external-masters\n" " allow autoresolving mounts with external masters\n" " --manage-cgroups [m] dump or restore cgroups the process is in usig mode:\n" " 'none', 'props', 'soft' (default), 'full' and 'strict'.\n" " --cgroup-root [controller:]/newroot\n" " change the root cgroup the controller will be\n" " installed into. No controller means that root is the\n" " default for all controllers not specified.\n" " --skip-mnt PATH ignore this mountpoint when dumping the mount namespace.\n" " --enable-fs FSNAMES a comma separated list of filesystem names or \"all\".\n" " force criu to (try to) dump/restore these filesystem's\n" " mountpoints even if fs is not supported.\n" "\n" "* Logging:\n" " -o|--log-file FILE log file name\n" " --log-pid enable per-process logging to separate FILE.pid files\n" " -v[NUM] set logging level (higher level means more output):\n" " -v1|-v - only errors and messages\n" " -v2|-vv - also warnings (default level)\n" " -v3|-vvv - also information messages and timestamps\n" " -v4|-vvvv - lots of debug\n" "\n" "* Memory dumping options:\n" " --track-mem turn on memory changes tracker in kernel\n" " --prev-images-dir DIR path to images from previous dump (relative to -D)\n" " --page-server send pages to page server (see options below as well)\n" " --auto-dedup when used on dump it will deduplicate \"old\" data in\n" " pages images of previous dump\n" " when used on restore, as soon as page is restored, it\n" " will be punched from the image.\n" "\n" "Page/Service server options:\n" " --address ADDR address of server or service\n" " --port PORT port of page server\n" " -d|--daemon run in the background after creating socket\n" "\n" "Other options:\n" " -h|--help show this text\n" " -V|--version show version\n" " --ms don't check not yet merged kernel features\n" ); return 0; opt_pid_missing: pr_msg("Error: pid not specified\n"); return 1; bad_arg: if (idx < 0) /* short option */ pr_msg("Error: invalid argument for -%c: %s\n", opt, optarg); else /* long option */ pr_msg("Error: invalid argument for --%s: %s\n", long_opts[idx].name, optarg); return 1; }
int main(int argc, char** argv) { pid_t pid; glob_t globbuf; while (1) { printf("$"); char buf[MAX_LINE]; char **argvv = tokenizeInput(buf); if (strcmp(argvv[0], "exit") == 0) { kill(pid, SIGKILL); exit(1); } pid = fork(); if (pid < 0) { fprintf(stderr, "Fork failed"); exit(1); } else if (pid == 0) { // child // backup stdout, stdin int stdin_save, stdout_save; // exec, redirecting streams as necessary if (is_redirect_in) { stdin_save = dup(STDIN_FILENO); freopen(redirect_stream, "r", stdin); execvp(argvv[0], argvv); dup2(stdin_save, STDIN_FILENO); exit(1); } else if (is_redirect_out) { stdout_save = dup(STDOUT_FILENO); freopen(redirect_stream, "w", stdout); execvp(argvv[0], argvv); dup2(stdout_save, STDOUT_FILENO); exit(1); } else if (has_wildcard) { // usage as detailed in `man glob` globbuf.gl_offs = argv_count - 1; // the GLOB_DOOFFS allocates gl_offs for us to merge glob(wildcard_expr, GLOB_DOOFFS, NULL, &globbuf); // merge the existing argvv array int i; for (i = 0; i < argv_count - 1; ++i) { globbuf.gl_pathv[i] = argvv[i]; } execvp(argvv[0], globbuf.gl_pathv); exit(1); } else { execvp(argvv[0], argvv); exit(1); } } else { // parent if (is_fg) { wait(NULL); } } } return 0; }