Exemple #1
0
int main(void) {
    pid_t pid;
    int argc, status;
    char command[MAXLINE], *argv[MAXARGS], path[MAXPATH];

    printf("Welcome to the mini-shell, msh!\n");

    for (;;) {
        printf("msh > ");
        fflush(stdout);
        fgets(command, MAXLINE, stdin);

        argc = parse_input(command, argv);

        /* if nothing is entered do nothing */
        if (*argv == NULL) continue;

        /* exit */
        if (strcmp("exit", argv[0]) == 0) exit(EXIT_SUCCESS);

        /* print working directory */
        if (strcmp("pwd", argv[0]) == 0) {
            printf("%s\n", getenv("PWD"));
            continue;
        }

        /* error handling for invalid commands */
        if (*argv[0] == '<' || *argv[0] == '>') {
            _exit_error("No command.", false);
            continue;
        }

        /* cd */
        if (strcmp("cd", argv[0]) == 0) {
            // not Kansas
            if (argc > 1) chdir(argv[1]);
            // Kansas, there is no place like home Toto.
            else chdir(getenv("HOME"));

            // lets make sure to update PWD.
            getcwd(path, MAXPATH);
            setenv("PWD", path, 1);
            continue;
        }

        pid = fork();

        /* Unable to fork, reached fork limit? */
        if (pid == -1) perror("Shell programming error, unable to fork.\n");

        /* inside the child process */
        else if (pid == 0) process_input(argc, argv);
        /* inside the parent process, waiting on child */
        else {
            if (wait(&status) == -1) perror("Shell program error");
            else printf("Child returned status: %d\n", status);
        }
    }
    return 0;
}
Exemple #2
0
/* Executes a simple command that is not a builtin function, redirecting input
 * and output as appropriate. As with all exec_XXX() functions, assumes that
 * the parent has forked if necessary. Does not return.
 *
 * @simple = CMD to be executed
 */
void exec_simple(CMD* simple)
{
    if (simple->fromFile && redirect_input(simple) < 0) _exit(EXIT_FAILURE);
    if (simple->toFile && redirect_output(simple) < 0) _exit(EXIT_FAILURE);

    assert(simple && simple->type == SIMPLE);

    execvp(simple->argv[0], &simple->argv[0]);
    _exit_error(EXIT_FAILURE); // execvp only returns on an error
}
Exemple #3
0
/* Executes a stage that is not a builtin command.  Delegates to exec_simple()
 * and exec_subcmd() as appropriate. As with all exec_XXX() functions, assumes
 * that the parent has forked if necessary. Does not return.
 *
 * @stage = CMD to be executed
 */
void exec_stage(CMD* stage)
{
    assert(!is_builtin(stage));

    if (stage->type == SIMPLE) {
        exec_simple(stage);
    } else if (stage->type == SUBCMD) {
        exec_subcmd(stage);
    } else { // Should never hit here
        assert(false);
        _exit_error(EXIT_FAILURE);
    }
}
Exemple #4
0
void process_input(int argc, char **argv) {
    int fd;
    bool flag = false;

    for (int i = 0; i < argc; i++) {
        if (argv[i][0] == '<') {
            // error checking
            if (flag) _exit_error("Can't have two input redirects.", true);
            if (argv[i + 1] == NULL) _exit_error("No input redictions file specified.", true);
            // open a fd
            if((fd = open(argv[i + 1], O_RDONLY)) < 0) perror("open");
            // dup the fd and close the fd
            if(dup2(fd, 0) < 0) perror("dup2");
            close(fd);
            argv[i] = NULL;
            flag = true;
        } else if (strcmp(">", argv[i]) == 0) {
            if (argv[i + 1] == NULL) _exit_error("No output file specified.", true);
            if ((fd = open(argv[i + 1], O_TRUNC | O_WRONLY | O_CREAT, 0666)) < 0) perror("open");
            if (dup2(fd, 1) < 0) perror("dup2");
            close(fd);
            argv[i] = NULL;
        } else if (strcmp(">>", argv[i]) == 0) {
            if (argv[i + 1] == NULL) _exit_error("No output file specified.", true);
            if ((fd = open(argv[i + 1], O_APPEND | O_WRONLY | O_CREAT, 0666)) < 0) perror("open");
            if (dup2(fd, 1) < 0) perror("dup2");
            close(fd);
            argv[i] = NULL;
        }
    }

    if (execvp(*argv, argv) == -1) {
        perror("process_input, shell program.");
        _exit(-1);
    }
}