예제 #1
0
int execute_simple_command(simple_command *cmd) {
	pid_t pid;
	int status;
	int result = 0;



	if(cmd->builtin == BUILTIN_CD){
		return execute_cd(cmd->tokens);
	}
	else if(cmd->builtin == BUILTIN_EXIT){
		exit(0);
	}
	else if(cmd->builtin == 0){
		if((pid = fork()) == -1){
			perror("fork");
			exit(EXIT_FAILURE);
		}
		else if(pid > 0){
			waitpid(pid, &status, 0);
			return status;
		}
		else if(pid == 0){
			execute_nonbuiltin(cmd);
			exit(0);
		}
	}
	else{
		printf("execute_simple error");
		exit(EXIT_FAILURE);
	}
	return result;
}
예제 #2
0
파일: shell.c 프로젝트: dklambauer/shell
/**
 * Executes a simple command (no pipes).
 */
int execute_simple_command(simple_command *cmd) {

    /**
     * Check if the command is builtin.
     * 1. If it is, then handle BUILTIN_CD (see execute_cd function provided) 
     *    and BUILTIN_EXIT (simply exit with an appropriate exit status).
     * 2. If it isn't, then you must execute the non-builtin command. 
     * - Fork a process to execute the nonbuiltin command 
     *   (see execute_nonbuiltin function above).
     * - The parent should wait for the child.
     *   (see wait man pages).
     */
    int command_number;
    /* Handle builtin commands. */
    if((command_number = is_builtin(*(cmd->tokens)))) {
        switch(command_number) {
            case(BUILTIN_CD):
                if(execute_cd(cmd->tokens) != EXIT_SUCCESS) {
                    printf("No such file or directory.\n");
                }
                return 0;
                break;
            case(BUILTIN_EXIT):
                return -1;
                break;
        }
    /* Handle nonbuiltin commands.
     * Fork a process and use execute_nonbuiltin to execute the command.
     */
    } else {
        int pid;
        if((pid = fork()) < 0) {
            perror("fork");
            return EXIT_FAILURE;
        } else if (pid == 0) { //child
            /* 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(cmd));
        } else { //parent
            int status;
            /* Wait for the command to return, then return its exit status*/
            if(wait(&status) != -1) {
                if(WIFEXITED(status)) {
                    return WEXITSTATUS(status);
                } else {
                    return EXIT_FAILURE;
                }
            } else {
                perror("wait");
                return EXIT_FAILURE;
            }
        }
    }
    return EXIT_FAILURE;
}
예제 #3
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;
}
예제 #4
0
파일: shell.c 프로젝트: imnxllet/CSC209
/**
 * Executes a simple command (no pipes).
 */
int execute_simple_command(simple_command *cmd) {

	/**
	 * TODO: 
	 * Check if the command is builtin.
	 * 1. If it is, then handle BUILTIN_CD (see execute_cd function provided) 
	 *    and BUILTIN_EXIT (simply exit with an appropriate exit status).
	 * 2. If it isn't, then you must execute the non-builtin command. 
	 * - Fork a process to execute the nonbuiltin command 
	 *   (see execute_nonbuiltin function above).
	 * - The parent should wait for the child.
	 *   (see wait man pages).
	 */
	if(cmd->builtin != 0){
	    if(is_builtin(cmd->tokens[0]) == BUILTIN_CD){
		 execute_cd(cmd->tokens);
		 

	    }else if(is_builtin(cmd->tokens[0]) == BUILTIN_EXIT){
		 return -1;
	    }    

	}else{
             int r,status; 
	     if ((r = fork()) == -1){ // fork failed 
                 perror("fork"); 
	         exit(-1); 
	       
	    } 
	     else if (r > 1){ // parent process 
                 wait(&status); 
	       
	    } else if (r == 0){ // child process 
                 execute_nonbuiltin(cmd);
		 exit(1);
	      
	    }
	}
	return 0;
	
}
예제 #5
0
파일: shell.c 프로젝트: dklambauer/shell
/**
 * 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;
}