Esempio n. 1
0
int execute_complex_command(command *c) {
	
	if(c->scmd != NULL){
		if(c->scmd->builtin == 0){
			execute_nonbuiltin(c->scmd);
		}
	}

	if (!strcmp(c->oper, "|")) {

		int pfd[2];
		if(pipe(pfd) == -1){
			perror("pipe");
			exit(EXIT_FAILURE);
		}

		
		pid_t pid1, pid2;
		int status;
		pid1 = fork();

		if(pid1 < 0){
			perror("fork");
			exit(EXIT_FAILURE);
		}
		else if(pid1 == 0){
			close(pfd[0]);
			close(fileno(stdout));
			dup2(pfd[1], fileno(stdout));
			execute_complex_command(c->cmd1);
			exit(0);
		}
		else{
			pid2 = fork();
			if(pid2 < 0){
				perror("fork");
				exit(EXIT_FAILURE);
			}
			else if(pid2 == 0) {
				close(pfd[1]);
				close(fileno(stdin));
				dup2(pfd[0], fileno(stdin));
				execute_complex_command(c->cmd2);
				exit(0);
			}
			else{
				close(pfd[0]);
				close(pfd[1]);
				waitpid(pid1, &status, 0);
				waitpid(pid2, &status, 0);
			}
		}
	}
	return 0;
}
Esempio n. 2
0
/**
 * Executes a complex command.  A complex command is two commands chained 
 * together with a pipe operator.
 */
int execute_complex_command(command *c){
    if (c->scmd){
        execute_simple_command(c->scmd);
      
    }else{
	  int pfd[2];
	  if(pipe(pfd) == -1) {
	    perror("Pipe failed");
	    exit(1);
	  }

	  if(fork() == 0)        //first fork
	  {
	      close(1);          //closing stdout
	      dup(pfd[1]);     //replacing stdout with pipe write 
	      close(pfd[0]);   //closing pipe read
	      close(pfd[1]);

	    execute_complex_command(c->cmd1); 
	    exit(1);
	  }

	  if(fork() == 0)        //creating 2nd child
	  {
	      close(0);          //closing stdin
	      dup(pfd[0]);     //replacing stdin with pipe read
	      close(pfd[1]);   //closing pipe write
	      close(pfd[0]);

	      execute_complex_command(c->cmd2);
	      exit(1);
	  }

	  close(pfd[0]);
	  close(pfd[1]);
	  wait(0);
	  wait(0);
	  return 0;
    }
    return 0;	  
}
Esempio n. 3
0
int main(int argc, char** argv) {
        
        char cwd[MAX_DIRNAME];           /* Current working directory */
        char command_line[MAX_COMMAND];  /* The command */
        char *tokens[MAX_TOKEN];         /* Command tokens (program name, 
                                          * parameters, pipe, etc.) */

        while (1) {

                /* Display prompt */            
                getcwd(cwd, MAX_DIRNAME-1);
                printf("%s> ", cwd);
                
                /* Read the command line */
                fgets(command_line, MAX_COMMAND, stdin);
                /* Strip the new line character */
                if (command_line[strlen(command_line) - 1] == '\n') {
                        command_line[strlen(command_line) - 1] = '\0';
                }
                
                /* Parse the command into tokens */
                parse_line(command_line, tokens);

                /* Check for empty command */
                if (!(*tokens)) {
                        continue;
                }
                
                /* Construct chain of commands, if multiple commands */
                command *cmd = construct_command(tokens);
                // print_command(cmd, 0);
    
                int exitcode = 0;
                if (cmd->scmd) {
                        exitcode = execute_simple_command(cmd->scmd);
                        if (exitcode == -1) {
                                release_command(cmd);
                                break;
                        }
                }
                else {
                        exitcode = execute_complex_command(cmd);
                        if (exitcode == -1) {
                                release_command(cmd);
                                break;
                        }
                }
                release_command(cmd);
        }
    
        return 0;
}
Esempio n. 4
0
int main(int argc, char** argv) {
	
	char cwd[MAX_DIRNAME];           /* Current working directory */
	char command_line[MAX_COMMAND];  /* The command */
	char *tokens[MAX_TOKEN];         /* Command tokens (program name, parameters, pipe, etc.) */

	while (1) {

		/* Display prompt */		
		getcwd(cwd, MAX_DIRNAME-1);
		printf("%s> ", cwd);
		
		/* Read the command line */
		gets(command_line);
		
		/* Parse the command into tokens */
		parse_line(command_line, tokens);

		/* Empty command */
		if (!(*tokens))
			continue;
		
		/* Exit */
		if (strcmp(tokens[0], "exit") == 0)
			exit(0);
				
		/* Construct chain of commands, if multiple commands */
		command *cmd = construct_command(tokens);
    
		int exitcode = 0;
		if (cmd->scmd) {
			exitcode = execute_simple_command(cmd->scmd);
			if (exitcode == -1)
				break;
		}
		else {
			exitcode = execute_complex_command(cmd);
			if (exitcode == -1)
				break;
		}
		release_command(cmd);
	}
    
	return 0;
}
Esempio n. 5
0
/**
 * Executes a complex command.  A complex command is two commands chained 
 * together with a pipe operator.
 */
int execute_complex_command(command *c) {
    
    /**
     * Check if this is a simple command, using the scmd field.
     * Execute nonbuiltin commands only. If it's exit or cd, you should not 
     * execute these in a piped context, so simply ignore builtin commands. 
     */
    if(c->scmd) {
        /* The exit status of the child process will be the return value
         * of execute_nonbuiltin (if there is an error), or the exit
         * status of the command exec'd.
         */
        exit(execute_nonbuiltin(c->scmd));
        // printf("%s\n", c->scmd->tokens[0]);
        return 0;
    }


    /** 
     * Shell currently only supports | operator.
     */

    if (!strcmp(c->oper, "|")) {
        
        /**
         * Create a pipe "pfd" that generates a pair of file 
         * descriptors, to be used for communication between the 
         * parent and the child. Make sure to check any errors in 
         * creating the pipe.
         */
        int pfd[2];
        if(pipe(pfd) != 0) {
            perror("pipe");
            return EXIT_FAILURE;
        }
        /**
         * Fork a new process.
         * In the child:
         *  - close one end of the pipe pfd and close the stdout 
         * file descriptor.
         *  - connect the stdout to the other end of the pipe (the 
         * one you didn't close).
         *  - execute complex command cmd1 recursively. 
         * In the parent: 
         *  - fork a new process to execute cmd2 recursively.
         *  - In child 2:
         *     - close one end of the pipe pfd (the other one than 
         *       the first child), and close the standard input file 
         *       descriptor.
         *     - connect the stdin to the other end of the pipe (the 
         *       one you didn't close).
         *     - execute complex command cmd2 recursively. 
         *  - In the parent:
         *     - close both ends of the pipe. 
         *     - wait for both children to finish.
         */
        
        int pid;
        if((pid = fork()) < 0) {
            perror("fork");
            return EXIT_FAILURE;
        } else if (pid == 0) { //child
            close(pfd[0]);
            if(dup2(pfd[1], fileno(stdout)) < 0) {
                perror("dup2");
                return -1;
            }
            /* The exit status of the child process will be the return value
             * of execute_nonbuiltin (if there is an error), or the exit
             * status of the command exec'd.
             */
            exit(execute_complex_command(c->cmd1));
        } else { //parent
            if((pid = fork()) < 0) { 
                perror("fork");
                return EXIT_FAILURE;
            } else if (pid == 0) { //child
                close(pfd[1]);
                if(dup2(pfd[0], fileno(stdin)) < 0) {
                    perror("dup2");
                    return -1;
                }
                /* The exit status of the child process will be the return
                 * value of execute_nonbuiltin (if there is an error), or 
                 * the exit status of the command exec'd.
                 */
                exit(execute_complex_command(c->cmd2));
            } else { //parent
                close(pfd[0]);
                close(pfd[1]);

                int status;
                int exitcode = -1;
                int waitedPID;
                while ((waitedPID = wait(&status)) > 0) {
                    if(WIFEXITED(status)) {
                        /*exitcode should be the exit status of the
                         *last command in the pipeline.
                         */
                        if(waitedPID == pid) {
                            exitcode = WEXITSTATUS(status);
                        }
                    } else {
                        return EXIT_FAILURE;
                    }
                }
                return exitcode;
            }
        }
    }
    return 0;
}