perrynzhou

专注于系统组件研发

0%

实现简单的shell

  • shell实现代码
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    /*************************************************************************
    > File Name: shell.c
    > Author:perrynzhou
    > Mail:perrynzhou@gmail.com
    > Created Time: Thu 20 Jun 2019 09:15:59 PM CST
    ************************************************************************/

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <glob.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    static const char *delimiter = " \t\n";
    typedef struct
    {
    glob_t gt;
    int (*cmd_cd_fn)(char **argv);
    int (*cmd_exit_fn)(char **argv);
    int (*cmd_help_fn)(char **argv);
    } cmd_t;
    static void prompt()
    {
    fprintf(stdout, "zsh-0.1$ ");
    }
    void parsed_cmd(char *line, cmd_t *cmd)
    {
    char *token;
    int flag = 0;
    while (1)
    {
    token = strsep(&line, delimiter);
    if (token == NULL)
    {
    break;
    }
    if (*token == '\0')
    {
    continue;
    }
    glob(token, GLOB_NOCHECK | GLOB_APPEND * flag, NULL, &cmd->gt);
    flag = 1;
    }
    }
    int main(int argc, char *argv[])
    {
    char *line = NULL;
    size_t line_size = 0;
    cmd_t cmd;
    pid_t pid;
    while (1)
    {
    prompt();
    if (getline(&line, &line_size, stdin) < 0)
    {
    break;
    }
    parsed_cmd(line, &cmd);
    pid = fork();
    switch (pid)
    {
    case -1:
    perror("fork()");
    exit(1);
    case 0:
    execvp(cmd.gt.gl_pathv[0], cmd.gt.gl_pathv);
    exit(0);
    default:
    wait(NULL);
    }
    }
    }