示例#1
0
文件: mysh.c 项目: Genki-S/foolish
/* Main function does basic loop */
int main(int argc, char const* argv[])
{
    int i;
    size_t len = 0;
    ssize_t n;
    int pipe_p2c[2], pipe_c2p[2]; /* interaction between patent and child */
    int prevcom_pipe_output_fd = 100; /* dup pipe output for later use (use big integer to organize fds) */

    /* Initialize */
    init();

    /* Prompt -> read -> analyze -> execute loop */
    while (true) {
        printf("%s", g_prompt);
        n = getline(&g_input_line, &len, stdin);

        /* Exit check */
        if (n == -1) { /* Ctrl-D */
            break;
        }
        if (strcmp(g_input_line, "exit\n") == 0) {
            msg("Wise command. Obviously, you should use zsh :)\n");
            break;
        }

        /* Blank command */
        if (strcmp(g_input_line, "\n") == 0) {
            blankcmd(g_input_line);
        }

        /* Parse input */
        init_parser_gv();
        yy_scan_string(g_input_line);
        yyparse();

        /* Execute command (commands if pipes are used) */
        command* com;
        while ( (com = pop_command()) != NULL ) {
            /* Prepare pipes */
            if (pipe(pipe_c2p) < 0) {
                error(0, errno, "Pipe");
                exit(EXIT_FAILURE);
            }
            if (pipe(pipe_p2c) < 0) {
                error(0, errno, "Pipe");
                exit(EXIT_FAILURE);
            }

            /* Fork and execute */
            if ((g_working_child_pid = fork()) == -1) {
                fprintf(stderr, "fork error\n");
            }
            else if (g_working_child_pid == 0) {
                /* child process */
                close(pipe_p2c[WRITE]);
                close(pipe_c2p[READ]);

                /* Search bin */
                char bin[1024];
                if (com->bin[0] == '/') { /* Absolute path */
                    strcpy(bin, com->bin);
                    if (access(bin, X_OK) != 0 || is_dir(bin)) {
                        fprintf(stderr, "Command not found: %s\n", com->bin);
                        exit(EXIT_FAILURE);
                    }
                }
                else { /* Search path for executable */
                    for (i = 0; i < g_path_size; i++) {
                        strcpy(bin, g_paths[i]);
                        strcat(bin, "/");
                        strcat(bin, com->bin);
                        if (access(bin, X_OK) == 0 && !is_dir(bin)) { /* executable command found */
                            break;
                        }
                    }
                    if (i == g_path_size) {
                        fprintf(stderr, "Command not found: %s\n", com->bin);
                        exit(EXIT_FAILURE);
                    }
                }

                /* Error check about file descriptors */
                if (strcmp(com->infile, "") != 0 && com->pipein) {
                    msg("Please do not redirect from file when a command has pipe input.\n");
                    exit(EXIT_FAILURE);
                }
                if (strcmp(com->outfile, "") != 0 && com->pipeout) {
                    msg("Please do not redirect to file when a command has pipe output. Use tee instead.\n");
                    exit(EXIT_FAILURE);
                }

                /* Redirection settings */
                if (strcmp(com->infile, "") != 0) { /* infile is specified */
                    if (access(com->infile, R_OK) != 0) {
                        error(0, errno, "Cannot read from %s", com->infile);
                        exit(EXIT_FAILURE);
                    }
                    close(STDIN_FILENO);
                    open(com->infile, O_RDONLY); /* opens with STDIN_FILENO */
                }
                if (strcmp(com->outfile, "") != 0) {
                    close(STDOUT_FILENO);
                    open(com->outfile, O_CREAT | O_WRONLY | O_TRUNC, 0777); /* opens with STDOUT_FILENO */
                }

                /* Pipe settings */
                if (com->pipein) {
                    dup2(pipe_p2c[READ], STDIN_FILENO);
                }
                if (com->pipeout) {
                    dup2(pipe_c2p[WRITE], STDOUT_FILENO);
                }
                close(pipe_p2c[READ]);
                close(pipe_c2p[WRITE]);
                execv(bin, com->argv);
            }

            /* parent */
            close(pipe_p2c[READ]);
            close(pipe_c2p[WRITE]);

            /* Write previous pipe output if necessary */
            char buf[BUFSIZ];
            if (com->pipein) {
                while ((n = read(prevcom_pipe_output_fd, buf, BUFSIZ)) > 0) {
                    write(pipe_p2c[WRITE], buf, n);
                }
            }
            close(pipe_p2c[WRITE]);

            int status;
            if (wait(&status) == (pid_t)-1) {
                fprintf(stderr, "wait error\n");
                exit(EXIT_FAILURE);
            }

            /* Keep pipe output if necessary */
            if (com->pipeout) {
                dup2(pipe_c2p[READ], prevcom_pipe_output_fd);
            }
            close(pipe_c2p[READ]);


            /* CLEAN UP */

            /* Clear child pid */
            g_working_child_pid = 0;

            /* Free memory */
            for (i = 0; i < com->argc; i++) {
                free(com->argv[i]);
            }
            free(com->argv);
            free(com);

            /* Stop executing command queue if an error has occurred */
            if (WEXITSTATUS(status) == EXIT_FAILURE) {
                while ( (com = pop_command()) != NULL );
                break;
            }
        }
    }

    /* Termination */
    terminate();

    return EXIT_SUCCESS;
}
示例#2
0
int main(void)
{
	entry* entry_head = calloc(sizeof(entry), 1);
	snapshot* snapshot_head = calloc(sizeof(snapshot), 1);

	int latest_snapshotID = 1;

	char buffer[MAX_LINE_LENGTH];

	printf("> ");

	while(fgets(buffer, sizeof(buffer), stdin))
	{
		struct command_struct *command = get_command_struct(buffer);
		if(!command) continue;


		if(strcmp(command->args_malloc_ptr[0], "bye") == 0)
		{
			bye_command(snapshot_head, entry_head);
			free_command(command);
			printf("bye");
			return 0;
		}
		else if(strcmp(command->args_malloc_ptr[0], "help") == 0)
		{
			print_help_string();
		}
		else if(strcmp(command->args_malloc_ptr[0], "list") == 0)
		{
			list_command(command, entry_head, snapshot_head);
		}
		else if(strcmp(command->args_malloc_ptr[0], "get") == 0)
		{
			get_command(command, entry_head);
		}
		else if(strcmp(command->args_malloc_ptr[0], "del") == 0)
		{
			del_command(command, entry_head);
		}
		else if(strcmp(command->args_malloc_ptr[0], "purge") == 0)
		{
			purge_command(command, entry_head, snapshot_head);
		}
		else if(strcmp(command->args_malloc_ptr[0], "set") == 0)
		{
			set_command(command, entry_head);
		}
		else if(strcmp(command->args_malloc_ptr[0], "push") == 0)
		{
			push_command(command, entry_head);
		}
		else if(strcmp(command->args_malloc_ptr[0], "append") == 0)
		{
			append_command(command, entry_head);
		}
		else if(strcmp(command->args_malloc_ptr[0], "pick") == 0)
		{
			pick_command(command, entry_head);
		}
		else if(strcmp(command->args_malloc_ptr[0], "pluck") == 0)
		{
			pluck_command(command, entry_head);
		}
		else if(strcmp(command->args_malloc_ptr[0], "pop") == 0)
		{
			pop_command(command, entry_head);
		}
		else if(strcmp(command->args_malloc_ptr[0], "drop") == 0)
		{
			drop_command(command, snapshot_head);
		}
		else if(strcmp(command->args_malloc_ptr[0], "rollback") == 0)
		{
			rollback_command(command, snapshot_head, entry_head);
		}
		else if(strcmp(command->args_malloc_ptr[0], "checkout") == 0)
		{
			checkout_command(command, snapshot_head, entry_head);
		}
		else if(strcmp(command->args_malloc_ptr[0], "snapshot") == 0)
		{
			snapshot_command(snapshot_head, entry_head, &latest_snapshotID);
		}
		else if(strcmp(command->args_malloc_ptr[0], "min") == 0)
		{
			min_command(command, entry_head);
		}
		else if(strcmp(command->args_malloc_ptr[0], "max") == 0)
		{
			max_command(command, entry_head);
		}
		else if(strcmp(command->args_malloc_ptr[0], "sum") == 0)
		{
			sum_command(command, entry_head);
		}
		else if(strcmp(command->args_malloc_ptr[0], "len") == 0)
		{
			len_command(command, entry_head);
		}
		else if(strcmp(command->args_malloc_ptr[0], "rev") == 0)
		{
			rev_command(command, entry_head);
		}
		else if(strcmp(command->args_malloc_ptr[0], "uniq") == 0)
		{
			uniq_command(command, entry_head);
		}
		else if(strcmp(command->args_malloc_ptr[0], "sort") == 0)
		{
			sort_command(command, entry_head);
		}
		printf("\n> ");
		free_command(command);
	}
		bye_command(snapshot_head, entry_head);
	return 0;
}