int main(int argc, char **argv, char **env_table) { t_env *env; char *line; if (!(env = (t_env *)malloc(sizeof(t_env)))) return (-1); init_env(env, env_table); write(1, PROMPT, sizeof(PROMPT) - 1); while (get_next_line(1, &env->line) > 0) { if (*env->line) { env->command = get_called_command(env->line); if (!strcmp(env->command, "env")) builtin_env(env); else if (!strcmp(env->command, "setenv")) builtin_setenv(env); else if (!strcmp(env->command, "unsetenv")) builtin_unsetenv(env); else if (!strcmp(env->command, "exit")) builtin_exit(env); else unknown_command(env->command); } write(1, PROMPT, sizeof(PROMPT) - 1); } return (0); }
inline int readline_match_d(s_dynamic_string *dynstr, int *pos, char c) { unsigned int i = 0; if (c == 4) { if (dynstr->len == 0) builtin_exit(); if (*pos < dynstr->len) { dynamic_string_remove(dynstr, (*pos)); printf("%s ", dynstr->str + (*pos)); for (i = 0; i <= strlen(dynstr->str + (*pos)); i++) printf("%c", 8); fflush(NULL); } return (1); } return (0); }
int execute_builtin(cmd_t* cmd, job_list_t* jobs, history_t* hist) { // List jobs. if (strcmp(cmd->args[0], "jobs") == 0) { add_to_history(hist, cmd); return builtin_jobs(jobs); } // List history. if (strcmp(cmd->args[0], "history") == 0) { int exit_code = builtin_history(hist); add_to_history(hist, cmd); return exit_code; } // Exit. if (strcmp(cmd->args[0], "exit") == 0) { return builtin_exit(); } // Change directory. if (strcmp(cmd->args[0], "cd") == 0) { int exit_code = builtin_cd(cmd); if (exit_code == 0) { add_to_history(hist, cmd); } return exit_code; } // Print working directory. if (strcmp(cmd->args[0], "pwd") == 0) { add_to_history(hist, cmd); return builtin_pwd(); } // Bring to foreground. if (strcmp(cmd->args[0], "fg") == 0) { int exit_code = builtin_fg(cmd, jobs); if (exit_code == 0) { add_to_history(hist, cmd); } return exit_code; } // Execute from history. char* endptr = NULL; long num = strtol(cmd->args[0], &endptr, 10); if (*endptr == '\0' && !(num == 0 && errno == EINVAL)) { // Do not save to history to avoid confusion. int exit_code = builtin_exec_from_history(cmd, jobs, hist); freecmd(cmd); return exit_code; } // Command not found. return COMMAND_NOT_FOUND; }
/* * print prompt, read cmd, parse cmd, evaluation cmd */ void prompt() { char *line = NULL; char *argv[MAXARGS]; int argc = 0; memset(argv, 0, sizeof(argv)); line = readline("$ "); if (line == NULL) { builtin_exit(); } size_t len = strlen(line); if (len <= 1) { free(line); return; } add_history(line); if (builtin(line)) { free(line); return; } job_t *job = (job_t *) malloc(sizeof(job_t)); memset(job, 0, sizeof(job_t)); job->line = strdup(line); argc = tokenize(line, argv); pipeline_t *p = spawn_pipeline(argc, argv); if (p != NULL) { job->pid = execute(p); job->bg = p->bg; if (job->pid > 0) { queue_job(job); } else { job_rm(&root, fg); job_free(&job); } } tcsetpgrp(0, s_pgid); pipeline_free(p); free(line); }
void execute(struct parsed_line *p) { int status; extern void execute_one_subcommand(struct parsed_line *p); for (; p; p = p->next) { if (p->conntype == CONN_OR && laststatus == 0) { /* last command succeeded, so don't do this one */ } else if (p->conntype == CONN_AND && laststatus) { /* last command failed, so don't do this one */ } else { /* * "exit" and "cd" are handled specially to avoid the fork(). * Ideally the check should be later to make i/o redirection and * piping work, but we'd have to fudge the forking that way. */ if (p->pl && strcmp(p->pl->argv[0], "exit") == 0) { laststatus = builtin_exit(p->pl->argv); } else if (p->pl && strcmp(p->pl->argv[0], "cd") == 0) { laststatus = builtin_cd(p->pl->argv); } else { fflush(stdout); switch (fork()) { case -1: perror("fork"); laststatus = 127; break; case 0: /* child */ execute_one_subcommand(p); break; default: /* parent */ wait(&status); laststatus = status >> 8; } } } } }