コード例 #1
0
ファイル: pipe.c プロジェクト: benji62f/Lille1Sync
void do_pipe(char *cmds[MAXCMDS][MAXARGS], int nbcmd, int bg) {
	int **fds;
	int i, j;
	int pgid, job;
	char cmdsNames[MAXLINE] = "";
	if(verbose)
		printf("do_pipe: entering\n");

	if((fds = malloc((nbcmd-1) * sizeof(int*))) == NULL){
		if(verbose)
			printf("do_pipe: malloc of rows failed\n");
		return;
	}

	for(i=0 ; i<nbcmd-1 ; i++){
		if ((fds[i] = malloc(2 * sizeof(int))) == NULL){
			if(verbose)
				printf("do_pipe: malloc of columns failed\n");
			return;
		}
	}

	for(i=0 ; i<nbcmd-1 ; i++)
		pipe(fds[i]);

	if(verbose)
		printf("do_pipe: first case\n");
	switch(pgid = fork()){
		case -1:
			if(verbose)
				printf("do_pipe: fork failed\n");
			return;
		case 0:
			setpgid(0, 0);
			if(dup2(fds[0][1], STDOUT_FILENO) == -1 && verbose)
				printf("do_pipe: dup2 failed\n");
			for(i=0 ; i<nbcmd-1 ; i++){
				close(fds[i][0]);
				close(fds[i][1]);
			}
			if(execvp(cmds[0][0], cmds[0]) != 0){
				perror("execvp");
				exit(EXIT_FAILURE);
			}
	}

	for(j=1 ; j<nbcmd-1 ; j++){
		if(verbose){
			printf("do_pipe: central case\n");
			printf("do_pipe: pipe fds[%d]\n", j);
		}
		switch(fork()){
			case -1:
				if(verbose)
					printf("do_pipe: fork failed\n");
				return;
			case 0:
				setpgid(0, pgid);
				dup2(fds[j-1][0], STDIN_FILENO);
				dup2(fds[j][1], STDOUT_FILENO);
				for(i=0 ; i<nbcmd-1 ; i++){
					close(fds[i][0]);
					close(fds[i][1]);
				}
				if(execvp(cmds[j][0], cmds[j]) != 0){
					perror("execvp");
					exit(EXIT_FAILURE);
				}
		}
	}

	if(verbose)
		printf("do_pipe: last case\n");
	switch(fork()){
		case -1:
			if(verbose)
				printf("do_pipe: fork failed\n");
			return;
		case 0:
			setpgid(0, pgid);
			if(dup2(fds[nbcmd-2][0], STDIN_FILENO) == -1 && verbose)
				printf("do_pipe: dup2 failed\n");
			for(i=0 ; i<nbcmd-1 ; i++){
				close(fds[i][0]);
				close(fds[i][1]);
			}
			if(execvp(cmds[nbcmd-1][0], cmds[nbcmd-1]) != 0){
				perror("execvp");
				exit(EXIT_FAILURE);
			}
	}

	for(i=0 ; i<nbcmd-1 ; i++){
		close(fds[i][0]);
		close(fds[i][1]);
	}

	for(i=0 ; i<nbcmd ; i++){
		if(i!=0)
			strcat(cmdsNames, " | ");
		strcat(cmdsNames, cmds[i][0]);
	}

	if(bg)
		job = jobs_addjob(pgid, BG, cmdsNames);
	else
		job = jobs_addjob(pgid, FG, cmdsNames);

	if(!bg)
		waitfg(pgid);
	else
		printf("[%d] (%d) %s\n",job , pgid, cmdsNames);

	free(fds);

	if(verbose)
		printf("do_pipe: exiting\n");
	return;
}
コード例 #2
0
ファイル: mshell.c プロジェクト: CharlesVaneenoo/TP_L3S5
void eval(char *cmdline) {
    char *token[MAXCMDS][MAXARGS];      /* token[i] is a command typed in the command line */
    int nbcmd;                          /* number of commands typed in the command line */
    int bg;                             /* should the job run in bg or fg? */
    pid_t pid;                          /* process id */
    sigset_t mask;                      /* signal mask */
    char **argv;

    /* Parse command line */
    bg = parseline(cmdline, token, &nbcmd);

    if (nbcmd > 1)              /* a command pipeline has been typed in */
        do_pipe(token, nbcmd, bg);
    else {                      /* no pipeline, only one command */
        argv = token[0];
        if (!builtin_cmd(argv)) {
            /*
             * This is a little tricky. Block SIGCHLD, SIGINT, and SIGTSTP
             * signals until we can add the job to the job list. This
             * eliminates some nasty races between adding a job to the job
             * list and the arrival of SIGCHLD, SIGINT, and SIGTSTP signals.
             */

            if (sigemptyset(&mask) < 0)
                unix_error("sigemptyset error");
            if (sigaddset(&mask, SIGCHLD))
                unix_error("sigaddset error");
            if (sigaddset(&mask, SIGINT))
                unix_error("sigaddset error");
            if (sigaddset(&mask, SIGTSTP))
                unix_error("sigaddset error");
            if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0)
                unix_error("sigprocmask error");

            /* Create a child process */
            if ((pid = fork()) < 0)
                unix_error("fork error");

            /*
             * Child  process
             */
            if (pid == 0) {
                /* Child unblocks signals */
                sigprocmask(SIG_UNBLOCK, &mask, NULL);

                /* Each new job must get a new process group ID
                   so that the kernel doesn't send ctrl-c and ctrl-z
                   signals to all of the shell's jobs */
                if (setpgid(0, 0) < 0)
                    unix_error("setpgid error");

                /* Now load and run the program in the new job */
                if (execvp(argv[0], argv) < 0) {
                    printf("%s: Command not found\n", argv[0]);
                    exit(EXIT_FAILURE);
                }
            }

            /*
             * Parent process
             */
            /* Parent adds the job, and then unblocks signals so that
               the signals handlers can run again */
            jobs_addjob(pid, (bg == 1 ? BG : FG), cmdline);
            sigprocmask(SIG_UNBLOCK, &mask, NULL);

            if (!bg)
                waitfg(pid);
            else
                printf("[%d] (%d) %s\n", jobs_pid2jid(pid), (int) pid, cmdline);
        }
    }
    return;
}
コード例 #3
0
ファイル: pipe.c プロジェクト: marie-j/PDS-TP7-
void do_pipe(char *cmds[MAXCMDS][MAXARGS], int nbcmd, int bg) {

    int fd[2][2], i;
    pid_t pid;

    if (verbose) printf("Entering pipe\n");

    if (verbose) printf("Pipe creation\n");


    if (pipe(fd[0]) == -1) {

      if (verbose) printf("Error in pipe creation\n");
    }

    for (i = 0; i < nbcmd; i++) {

      if (i == 0) {

        switch(pid = fork()) {
          case -1 :

            if (verbose) unix_error("fork cmd 1 error");

          case 0 :
            if (verbose) printf("First son process\n");

            setpgid(0, 0);
            dup2(fd[0][1],STDOUT_FILENO);

            close(fd[0][0]);
            close(fd[0][1]);

            execvp(cmds[0][0],cmds[0]);

            printf("execvp error\n");
            exit(EXIT_FAILURE);

          default :
            if (verbose) printf("Father process\n");
        }
      }

      else if (i > 0 && i < nbcmd -1) {

        switch(pid = fork()) {
          case -1 :
            unix_error("fork cmd 2 error");

          case 0 :

            if (verbose) printf("the %dth process\n",i);

            assert(pipe(fd[i%2]) != -1);

            setpgid(0, pid);
            dup2(fd[(i+1)%2][0], STDIN_FILENO);
            dup2(fd[i%2][1], STDOUT_FILENO);
            close(fd[0][0]);
            close(fd[0][1]);
            close(fd[1][1]);
            close(fd[1][0]);
            execvp(cmds[i][0],cmds[i]);
            printf("execvp 2 error\n");
            exit(EXIT_FAILURE);

          default :

            close(fd[(i+1)%2][0]);
            close(fd[(i+1)%2][1]);
        }
      }

      else {
        switch(pid = fork()) {
          case -1 :
            unix_error("fork cmd 2 error");

          case 0 :
            if (verbose) {
                printf("Last process\n");
            }
            dup2(fd[(i+1)%2][0], STDIN_FILENO);
            close(fd[(i+1)%2][0]);
            close(fd[(i+1)%2][1]);
            execvp(cmds[i][0],cmds[i]);
            printf("execvp 2 error\n");
            exit(EXIT_FAILURE);

          default:

            close(fd[(i+1)%2][0]);
            close(fd[(i+1)%2][1]);
        }
      }

    }

    jobs_addjob(pid, (bg == 1 ? BG : FG), cmds[0][0]);

    if (!bg) {
      if (verbose) printf("pipe waiting fg \n");

      waitfg(pid);
    }

    return;
}