Example #1
0
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);
}
Example #2
0
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);
  }
Example #3
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__ */
}
Example #4
0
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;
}
Example #5
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;
	}

}
Example #6
0
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;
}
Example #7
0
void p_child(char **commands){
	execvp(commands[0], commands);
}
Example #8
0
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;
}
Example #9
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
    
}
Example #10
0
// 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;
}
Example #11
0
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);
}
Example #12
0
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;
}
Example #13
0
void execute(char **argv){
  execvp(argv[0], argv);
  perror(SHELL_ERROR_IDENTIFIER);
  exit(EXIT_FAILURE);
}
Example #14
0
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);
}
Example #15
0
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;
}
Example #16
0
File: bti.c Project: sunng87/bti
/**
 * 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;
}
Example #17
0
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;
}
Example #18
0
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);
}
Example #19
0
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++;
		}
	}
}
Example #20
0
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);
}
Example #21
0
void bg_child(char **commands){
	execvp(commands[1], commands);
}
Example #22
0
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() */
Example #23
0
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 */
}
Example #25
0
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);
	}
}
Example #26
0
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]);
  }
}
Example #27
0
/* 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;
}
Example #28
0
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();
      }
    }
  }
}
Example #29
0
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;
}
Example #30
0
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;
}