/* 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; }
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; }