📄 myshell.c
字号:
#include <stdlib.h>#include <stdio.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <string.h>#include <math.h>#include <ctype.h>#include <errno.h>#include <fcntl.h>#include <sys/stat.h>#include <signal.h>#include "myshell.h"#define RWXRXRX (S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)/* * functions not defined in this file */extern char **getline();/* * initialization goes here */char incorrect_cmd[128] = "Sorry, you just entered incorrect command!";char unsupport_cmd[128] = "Sorry, myshell doesn't support this use!";char *ls_path = "/usr/bin/ls";char *sort_path = "/usr/bin/sort";char *more_path = "/bin/more";char *less_path = "/usr/bin/less";char *vi_path = "/usr/bin/vi";char cmds_array[10][10][10];char (*history_cmds)[10][10] = cmds_array; int history_cmd_index = 0;char **args;int main(int argc, char *argv[]) { /* * mask signals */ struct sigaction sa; sa.sa_handler = SIG_IGN; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; if (sigaction(SIGINT, &sa, NULL) < 0) { my_err_handler("sigint error"); return; } if (sigaction(SIGQUIT, &sa, NULL) < 0) { my_err_handler("sighquit error"); return; } if (sigaction(SIGTSTP, &sa, NULL) < 0) { my_err_handler("sigtstp error"); return; } /* * The main loop always run, only Ctrl+\ can quit it. */ while(1) { fprintf(stdout, "myshell$ "); args = getline(); add_history_cmd(args); /* * parse the commands */ if (args[0] == NULL) { //'\n' only, do nothing } else { if (strncmp(args[0], "exit", 4) == 0) { my_exit(); } else if (strncmp(args[0], "ls", 2) == 0) { my_ls(args); } else if(strncmp(args[0], "sort", 4) == 0) { my_sort(args); } else if(strncmp(args[0], "vi", 2) == 0) { my_vi(args); } else if(strncmp(args[0], "add", 3) == 0) { my_add(args); } else if(strncmp(args[0], "args", 4) == 0) { my_args(args); } else if(strncmp(args[0], "history", 7) == 0) { my_history(args); } else if(strncmp(args[0], "!", 1) == 0) { my_ex_hcmd(args); } else { my_err_handler(unsupport_cmd); } } } return 0;}/* * use to exit myshell * * exit */int my_exit(){ int status; exit(status); return status;}/* * use to list the current directory * with or without options * redirect output also implements here * * ls * ls -l * ls -l > foo * ls -l | more */void my_ls(options) char **options;{ /* ls */ pid_t pid; char *argv[11] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; int arg_index = 0; if ((pid = fork()) < 0) { my_err_handler("fork error"); return; } else if (pid == 0) { argv[arg_index ++] = ls_path; if (*(options + 1) != NULL) { if (strncmp(*(options + 1), "-l", 2) == 0) argv[arg_index ++] = "-l"; else { my_err_handler(unsupport_cmd); return; } if (*(options + 2) == NULL) { //do nothing } else if (*(options + 2)[0] == '>') { /* ls -l > foo */ if (*(options + 3) == NULL) { my_err_handler("no redirected output given!"); return; } else { FILE *fp; if ((fp = freopen(*(options + 3), "w", stdout)) == NULL) { my_err_handler("freopen error"); return; } } } else if (*(options + 2)[0] == '|') { /* ls -l | more */ pid_t pid2; int fd[2]; if (pipe(fd) == -1) { my_err_handler("pipe error"); return; } char *argv2[11] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; int arg_index2 = 0; if (strncmp(*(options + 3), "more", 4) == 0) { argv2[arg_index2 ++] = more_path; } else if (strncmp(*(options + 3), "less", 4) == 0) { argv2[arg_index2 ++] = less_path; } else { my_err_handler(unsupport_cmd); return; } if ((pid2 = fork()) < 0) { my_err_handler("fork error"); return; } else if (pid2 == 0) { close(fd[0]); if (dup2(fd[1], STDOUT_FILENO) != STDOUT_FILENO) { my_err_handler("dup2 error"); return; } close(fd[1]); if (execv(argv[0], argv) < 0) { my_err_handler("execv error"); return; } } else { close(fd[1]); if (wait(NULL) < 0) { my_err_handler("wait error"); return; } if (dup2(fd[0], STDIN_FILENO) != STDIN_FILENO) { my_err_handler("dup2 error"); return; } close(fd[0]); if (execv(argv2[0], argv2) < 0) { my_err_handler("execv error"); return; } } return; //direct return, not execute code below } else { my_err_handler(unsupport_cmd); return; } } if (execv(argv[0], argv) < 0) { my_err_handler("execv error"); return; } } else { if (wait(NULL) != pid) { my_err_handler("wait error"); return; } }}/* * use to sort lines of a file * with redirect input * * sort < foo */void my_sort(options) char **options;{ pid_t pid; char *argv[11] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; int arg_index = 0; if ((pid = fork()) < 0) { my_err_handler("fork error"); return; } else if (pid == 0) { argv[arg_index ++] = sort_path; if (*(options + 1) == NULL) { //do nothing, will read from stdin } else if (*(options + 1)[0] == '<') { if (*(options + 2) == NULL) { my_err_handler("no redirected input given!"); return; } else { FILE *fp; if ((fp = freopen(*(options + 2), "r", stdin)) == NULL) { my_err_handler("freopen error"); return; } } } else { my_err_handler(unsupport_cmd); return; } if (execv(argv[0], argv) < 0) { my_err_handler("execv error"); return; } } else { if (wait(NULL) != pid) { my_err_handler("wait error"); return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -