zoukankan      html  css  js  c++  java
  • 二十九、Linux 进程与信号——minishell(2)

    编程内容:

      1.完成  echo env export 命令

      2.完成前后台进程

      3.完成重定向

    完整代码如下:

    29.1 主函数、通用头文件和Makefile

    29.1.1 主函数

      mshell_main.c

    1 #include <stdio.h>
    2 #include <stdlib.h>
    3 #include "mshell_handler.h"
    4 
    5 int main(int argc, char *argv[])
    6 {
    7     mshell_Handler();
    8 }

    29.1.2 通用文件

      mshell_common.h

     1 #ifndef __MSHELL_COMMON_H__
     2 #define __MSHELL_COMMON_H__
     3 
     4 #include <stdio.h>
     5 #include <stdlib.h>
     6 
     7 typedef enum {
     8     MSHELL_ERROR_NONE        = 0,
     9     MSHELL_ERROR_PARAM            ,
    10     MSHELL_ERROR_MALLOC            ,
    11     MSHELL_ERROR_CALLOC            ,
    12     MSHELL_ERROR_PROG_CREATE,
    13     MSHELL_ERROR_PROG_DESTROY,
    14     MSHELL_ERROR_JOB_CREATE,
    15     MSHELL_ERROR_JOB_DESTROY,
    16     MSHELL_ERROR_JOB_PROGADD,
    17     MSHELL_ERROR_CMD_NONECMD,
    18     MSHELL_ERROR_REDIRECION_PARAM,
    19     MSHELL_ERROR_REDIRECTION_CREATE,
    20     MSHELL_ERROR_REDIRECTION_PARSE
    21 }mshell_error_t;
    22 
    23 extern int mshell_args_Total(char **args);
    24 extern void mshell_args_Free(char **args);
    25 #endif

      mshell_common.c

     1 #include "mshell_common.h"
     2 
     3 
     4 /** 统计命令行参数的个数 */
     5 int mshell_args_Total(char **args)
     6 {
     7     int i = 0;
     8     char *start = args[0];
     9 
    10     while(NULL != start) {
    11         i++;
    12         start = args[i];
    13     }
    14 
    15     return i;
    16 }
    17 
    18 void mshell_args_Free(char **args)
    19 {
    20     if(NULL == args){
    21         return ;
    22     }
    23 
    24     int i;
    25     int len = sizeof(args);
    26     for(i = 0; i < len; i++) {
    27         free(args[i]);
    28     }
    29 #if 0
    30     while(NULL != args[i]){
    31         free(args[i]);
    32         i++;
    33     }
    34 #endif
    35     free(args);
    36 }

    29.1.3 Makefile

     1 #PROJECT_ROOT = $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
     2 PROJECT_ROOT = $(shell pwd)
     3 SRC_DIR = $(PROJECT_ROOT)/src
     4 INCLUDE_DIR = $(PROJECT_ROOT)/include
     5 OBJ_DIR = $(PROJECT_ROOT)/obj
     6 BIN_DIR = $(PROJECT_ROOT)/bin
     7 
     8 
     9 # 找出 src 目录下的所有 .c 文件
    10 C_SRCS = $(wildcard $(SRC_DIR)/*.c)
    11 # 将所有的 src 下的 .c 文件替换为 .o 文件
    12 C_OBJS = $(patsubst %c, %o, $(C_SRCS))
    13 TARGET = mshell
    14 SHARE_LIB = libmshell.a
    15 
    16 C_SRC_MAIN = mshell_main.c
    17 
    18 CC = gcc
    19 CCFLAGS += fPIC
    20 LDFLAGS += -shared -fPIC
    21 ASFLAGS +=
    22 ARFLAGS = -crs
    23 LIBS_FLAGS = -L$(BIN_DIR)
    24 
    25 RM = rm -rf
    26  
    27 CFLAGS += -Wall -g -I$(INCLUDE_DIR)
    28 INCDIR += -I$(INCLUDE_DIR)
    29 
    30 
    31 
    32 .PHONY: all clean test
    33 
    34 all: $(TARGET)
    35     cp $(SHARE_LIB) $(BIN_DIR)
    36     cp $(SRC_DIR)/*.o $(OBJ_DIR)/
    37     $(RM) $(SHARE_LIB) $(SRC_DIR)/*.o
    38 
    39 $(TARGET): $(SHARE_LIB)
    40     $(CC) $(C_SRC_MAIN) -o $(TARGET) $(CFLAGS) $(INCDIR) $(LIBS_FLAGS) -lmshell
    41 
    42 $(SHARE_LIB): $(C_OBJS)
    43     $(AR) $(ARFLAGS) $(SHARE_LIB) $(C_OBJS)
    44     cp $(SHARE_LIB) $(BIN_DIR)
    45 
    46 $(C_OBJS) : %.o:%.c
    47     $(CC) -c $(CFLAGS) $(INCDIR) -o $@ $<
    48 
    49 clean:
    50     $(RM) mshell 
    51     $(RM) $(SHARE_LIB) 
    52     $(RM) $(OBJ_DIR)/$(OBJS)/*.o 
    53     $(RM) $(SRC_DIR)/*.o

    29.2 handler

      mshell_handler.c

      1 #include "mshell_handler.h"
      2 
      3 static mshell_error_t mshell_cmd_Parsed(mshell_job_t *job, char *line, mshell_process_Flag_t *process_flag)
      4 {
      5     /** Create args secondary pointer stored in program */
      6     char **args_tmp = (char **)malloc(MSHELL_ARGS_SIZE * sizeof(char *));
      7     if(NULL == args_tmp) {
      8         return MSHELL_ERROR_MALLOC;
      9     }
     10 
     11     /** Split the command line */
     12     char *cmd = strtok(line, " ");
     13 
     14     /** The first parameter is the command itself */
     15     args_tmp[0] = (char *)calloc(strlen(cmd + 1), sizeof(char));
     16     if(NULL == args_tmp[0]) {
     17         return MSHELL_ERROR_MALLOC;
     18     }
     19     strcpy(args_tmp[0], cmd);
     20 
     21     /** Start with the second parameter */
     22     int i = 1;
     23     char *cmd_param;
     24     mshell_redirection_t *redirections[MSHELL_REDIRECTION_NUMBER];
     25     int redirection_num = 0;
     26 
     27     while(NULL != (cmd_param = strtok(NULL, " "))) {
     28 
     29         /** 对命令行进行解析,判断是否为后台进程 */
     30         int process_ret;
     31         *process_flag = mshell_process_BackParse(cmd_param, &process_ret);
     32         if(0 == process_ret) {
     33             continue;
     34         }
     35 
     36         /** 分析重定向 */
     37         mshell_error_t redirection_ret;
     38         redirections[redirection_num] =
     39                 mshell_redirection_Parse(redirections, redirection_num, cmd_param, &redirection_ret);
     40         if(NULL != redirections[redirection_num] && MSHELL_ERROR_NONE == redirection_ret){
     41             redirection_num++;
     42             continue;
     43         }
     44         else if (NULL == redirections[redirection_num] && MSHELL_ERROR_REDIRECION_PARAM == redirection_ret) {
     45             printf("need param
    ");
     46             continue;
     47         }
     48         else if(NULL == redirections[redirection_num] && MSHELL_ERROR_REDIRECTION_CREATE == redirection_ret)
     49         {
     50             perror("error create redirection");
     51             return MSHELL_ERROR_REDIRECTION_CREATE;
     52         }
     53 
     54         /** 分析命令 */
     55         args_tmp[i] = (char *)calloc(strlen(cmd_param + 1), sizeof(char));
     56         if(NULL == args_tmp[i]) {
     57             return MSHELL_ERROR_MALLOC;
     58         }
     59         strcpy(args_tmp[i], cmd_param);
     60         i++;
     61     }
     62     args_tmp[i] = NULL;
     63 
     64     /** Store all command line parameters in program and free args_tmp*/
     65     mshell_prog_t *prog = mshell_prog_Create(args_tmp);
     66     if(NULL == prog) {
     67         return MSHELL_ERROR_PROG_CREATE;
     68     }
     69     mshell_args_Free(args_tmp);
     70 
     71     /** Add redirection to job and free redirections*/
     72     for(i = 0; i < redirection_num; i++){
     73         mshell_prog_RedirectionAdd(prog, redirections[i]);
     74     }
     75     mshell_redirections_Free(redirections, redirection_num);
     76 
     77     /** Add program to the job*/
     78     if(MSHELL_ERROR_NONE != mshell_job_AddProg(job, prog)) {
     79         return MSHELL_ERROR_JOB_PROGADD;
     80     }
     81 
     82 #if 0
     83     /** free args_tmp */
     84     mshell_args_Free(args_tmp);
     85 #endif
     86     return 0;
     87 }
     88 
     89 static void mshell_cmd_ExcuProcess(mshell_job_t job, int order, mshell_process_Flag_t process_flag)
     90 {
     91     pid_t pid;
     92     if((pid = fork()) < 0) {
     93         perror("fork error");
     94     }
     95     else if(pid == 0) {
     96         /** child process */
     97         if(order == 0) {
     98             /** order = 0, 则为 minishell 当中启动的第一个子进程,设置其为组长进程 */
     99             job.pgid = mshell_process_GroupGet(getpid(), getpid());
    100         }
    101         else {
    102             /** order > 0, 则为启动的第二个进程,将其设置进程组的成员进程 */
    103             job.pgid = mshell_process_GroupGet(getpid(), job.pgid);
    104         }
    105         mshell_process_GroupSet(process_flag, getpid());
    106         /** 对便准输入、标准输出和追加进行重定向 */
    107         mshell_prog_RedirectionExcu(job.progs[order]);
    108 
    109         /** 调用 exec 函数执行系统中的其他命令 */
    110         if(MSHELL_ERROR_CMD_NONECMD == mshell_Cmd_ExcuOther(job.progs[order].args))
    111             exit(1);
    112     }
    113     else {
    114         /** parent process */
    115         if(order == 0) {
    116             job.pgid = mshell_process_GroupGet(pid, pid);
    117         }
    118         else {
    119             job.pgid = mshell_process_GroupGet(pid, job.pgid);
    120         }
    121         mshell_process_GroupSet(process_flag, job.pgid);
    122 
    123         mshell_process_Wait(process_flag, job.pgid);
    124 
    125 #if 0
    126         /** 等待指定的子进程结束, 阻塞版本,支持作业控制 */
    127         if(waitpid(pid, NULL, WUNTRACED) < 0) {
    128             perror("waitpid error");
    129         }
    130 #endif
    131     }
    132 
    133 }
    134 
    135 static mshell_error_t mshell_cmd_Excu(mshell_job_t *job, mshell_process_Flag_t process_flag)
    136 {
    137     int ret = MSHELL_ERROR_NONE;
    138     int i;
    139     for(i = 0; i < job->progs_num; i++)
    140     {
    141         ret = mshell_Cmd_ExcuFun(job->progs[i].args);
    142         if(MSHELL_ERROR_NONE == ret || MSHELL_ERROR_PARAM == ret) {
    143             return MSHELL_ERROR_NONE;
    144         }
    145 
    146         /** 执行其他命令 */
    147         mshell_cmd_ExcuProcess(*job, i, process_flag);
    148 #if 0
    149         pid_t pid;
    150         if((pid = fork()) < 0) {
    151             perror("fork error");
    152         }
    153         else if(pid == 0) {
    154             /** child process */
    155             /** 调用 exec 函数执行系统中的其他命令 */
    156             if(MSHELL_ERROR_CMD_NONECMD == mshell_Cmd_ExcuOther(job->progs[i].args))
    157                 exit(1);
    158         }
    159         else {
    160             /** parent process */
    161             /** 等待指定的子进程结束, 阻塞版本,支持作业控制 */
    162             if(waitpid(pid, NULL, WUNTRACED) < 0) {
    163                 perror("waitpid error");
    164             }
    165         }
    166 #endif
    167     }
    168 
    169     return 0;
    170 }
    171 
    172 mshell_error_t mshell_Handler()
    173 {
    174     /**创建一个进程组,将 minishell 进程设置为进程组的组长 */
    175     setpgid(getpid(), getpid());
    176 
    177     char buffer[MSHELL_COMMAND_LEN];
    178     memset(buffer, 0, MSHELL_COMMAND_LEN);
    179 
    180     ssize_t size = strlen(MSHELL_PROMPT) * sizeof(char);
    181     write(STDOUT_FILENO, MSHELL_PROMPT, size);
    182 
    183     mshell_process_Flag_t process_flag;    ///< 设置前台和后台进程的标志
    184     ssize_t len;
    185     while(1) {
    186 
    187         len = read(STDIN_FILENO, buffer, MSHELL_COMMAND_LEN); ///< 从命令行读取内容到 buffer
    188         buffer[len - 1] = 0;
    189         if(strlen(buffer) > 0){
    190             mshell_job_t *job = mshell_job_Create(buffer);
    191             if(NULL == job) {
    192                 return MSHELL_ERROR_JOB_CREATE;
    193             }
    194 
    195             mshell_cmd_Parsed(job, buffer, &process_flag);
    196             mshell_cmd_Excu(job, process_flag);
    197             //mshell_job_Destroy(job);
    198         }
    199 
    200         write(STDOUT_FILENO, MSHELL_PROMPT, size);
    201         memset(buffer, 0, MSHELL_COMMAND_LEN);
    202     }
    203 }
    View Code

      mshell_handler.h

     1 #ifndef __MSHELL_HANDLER_H__
     2 #define __MSHELL_HANDLER_H__
     3 
     4 
     5 #include "mshell_common.h"
     6 #include "mshell_process.h"
     7 #include "mshell_cmd_fun.h"
     8 #include "mshell_program.h"
     9 #include "mshell_job.h"
    10 #include <stdio.h>
    11 #include <stdlib.h>
    12 #include <malloc.h>
    13 #include <unistd.h>
    14 #include <string.h>
    15 #include <memory.h>
    16 #include <sys/wait.h>
    17 
    18 #define MSHELL_PROMPT    "mshell =>"
    19 #define MSHELL_COMMAND_LEN     256
    20 #define MSHELL_ARGS_SIZE    100
    21 
    22 mshell_error_t mshell_Handler();
    23 
    24 #endif
    View Code

    29.3 作业

       mshell_job.h

     1 #ifndef __MSHELL_JOB_H__
     2 #define __MSHELL_JOB_H__
     3 
     4 #include "mshell_common.h"
     5 #include "mshell_program.h"
     6 #include <malloc.h>
     7 #include <stdio.h>
     8 #include <stdlib.h>
     9 #include <string.h>
    10 #include <memory.h>
    11 
    12 /** job struct, A job contains several programs to execute */
    13 typedef struct {
    14     char             *cmd;        ///< String commands to be executed
    15     pid_t            pgid;        ///< 进程组的 ID
    16     int             progs_num;    ///< Number of programs to execute
    17     mshell_prog_t    *progs;        ///< Point to several programs to be executed
    18 }mshell_job_t;
    19 
    20 extern mshell_job_t* mshell_job_Create(char *cmd);
    21 extern void mshell_job_Destroy(mshell_job_t *job);
    22 extern mshell_error_t mshell_job_AddProg(mshell_job_t *job, mshell_prog_t *prog);
    23 #endif
    View Code

      mshell_job.c

     1 #include "mshell_common.h"
     2 #include "mshell_program.h"
     3 #include "mshell_job.h"
     4 
     5 
     6 mshell_job_t* mshell_job_Create(char *cmd)
     7 {
     8     mshell_job_t *job = (mshell_job_t *)malloc(sizeof(mshell_job_t));
     9     if(NULL == job)
    10     {
    11         return NULL;
    12     }
    13 
    14     job->cmd = (char *)malloc(sizeof(char) * strlen(cmd));
    15     if(NULL == job->cmd)
    16     {
    17         return NULL;
    18     }
    19 
    20     strcpy(job->cmd, cmd);
    21     job->progs_num = 0;
    22     job->progs = NULL;
    23 
    24     return job;
    25 }
    26 void mshell_job_Destroy(mshell_job_t *job)
    27 {
    28     if(NULL == job)
    29     {
    30         return ;
    31     }
    32     free(job->progs);
    33     free(job->cmd);
    34     free(job);
    35 }
    36 
    37 mshell_error_t mshell_job_AddProg(mshell_job_t *job, mshell_prog_t *prog)
    38 {
    39     mshell_prog_t *prog_tmp = (mshell_prog_t *)malloc(sizeof(mshell_prog_t) * (job->progs_num + 1));//1 为NULL的初始化
    40     if(NULL == prog_tmp) {
    41         return MSHELL_ERROR_MALLOC;
    42     }
    43 
    44     memcpy(prog_tmp, job->progs, job->progs_num * sizeof(mshell_prog_t));
    45     prog_tmp[job->progs_num++] = *prog;
    46     free(job->progs);
    47     job->progs = prog_tmp;
    48 
    49     return MSHELL_ERROR_NONE;
    50 }
    View Code

    29.4 程序

      mshell_program.h

     1 #ifndef __MSHELL_PROGRAM_H__
     2 #define __MSHELL_PROGRAM_H__
     3 
     4 #include "mshell_common.h"
     5 #include "mshell_redirection.h"
     6 #include <malloc.h>
     7 #include <stdio.h>
     8 #include <stdlib.h>
     9 #include <string.h>
    10 #include <memory.h>
    11 
    12 /** program struct */
    13 typedef struct {
    14     /**
    15      * Command-line parameters obtained from the terminal
    16      * Char*argv[] parameter corresponding to the main function
    17      */
    18     char                     **args;
    19     pid_t                     pid;                ///< 进程 ID
    20     int                     redirection_num;    ///< 重定向的数量
    21     mshell_redirection_t     *redirecitons;        ///< 重定向结构体数组
    22 }mshell_prog_t;
    23 
    24 extern mshell_prog_t* mshell_prog_Create(char **args);
    25 extern void mshell_prog_Destroy(mshell_prog_t *prog);
    26 extern void mshell_prog_RedirectionAdd(mshell_prog_t *prog, mshell_redirection_t *redirection);
    27 extern void mshell_prog_RedirectionExcu(mshell_prog_t prog);
    28 #endif
    View Code

      mshell_program.c

     1 #include "mshell_program.h"
     2 
     3 /**
     4  * Init program's pointer array
     5  */
     6 static mshell_prog_t * mshell_prog_ArgsInit(mshell_prog_t *prog, char **args, int counter)
     7 {
     8     int i;
     9 
    10     for(i = 0; i < counter; i++) {
    11         int len = strlen(args[i]);
    12         prog->args[i] = (char *)malloc(len);
    13         if(NULL == prog->args[i]){
    14             return NULL;
    15         }
    16 
    17         strcpy(prog->args[i], args[i]);
    18     }
    19     return prog;
    20 }
    21 
    22 mshell_prog_t * mshell_prog_Create(char **args)
    23 {
    24     mshell_prog_t *prog = (mshell_prog_t *)malloc(sizeof(mshell_prog_t));
    25     if(NULL == prog){
    26         return NULL;
    27     }
    28 
    29     /** Init program's redirection */
    30     prog->redirection_num = 0;
    31     prog->redirecitons = NULL;
    32 
    33     /** Init program's pointer array  */
    34     int args_num = mshell_args_Total(args);
    35     prog->args = (char **)calloc(args_num + 1, sizeof(char *));
    36     prog = mshell_prog_ArgsInit(prog, args, args_num);
    37     return prog;
    38 }
    39 
    40 void mshell_prog_Destroy(mshell_prog_t *prog)
    41 {
    42     if(NULL == prog) {
    43         return ;
    44     }
    45 
    46     mshell_args_Free(prog->args);
    47     free(prog->redirecitons);
    48     free(prog);
    49 }
    50 
    51 void mshell_prog_RedirectionAdd(mshell_prog_t *prog, mshell_redirection_t *redirection)
    52 {
    53     mshell_redirection_t *redirections = (mshell_redirection_t *)calloc(prog->redirection_num + 1, sizeof(mshell_redirection_t));
    54     if(NULL == redirections){
    55         return;
    56     }
    57 
    58     if(NULL != prog->redirecitons) {
    59         memcpy(redirections, prog->redirecitons, prog->redirection_num * sizeof(redirections));
    60         free(redirections);
    61     }
    62 
    63     prog->redirecitons = redirections;
    64     memcpy(&prog->redirecitons[prog->redirection_num], redirection, sizeof(mshell_redirection_t));
    65     prog->redirection_num += 1;
    66 }
    67 
    68 void mshell_prog_RedirectionExcu(mshell_prog_t prog)
    69 {
    70     int i;
    71     for(i = 0; i < prog.redirection_num; i++) {
    72         mshell_redirection_Excu(prog.redirecitons[i]);
    73     }
    74 }
    View Code

    29.5 命令

      mshell_cmd_fun.h

     1 #ifndef __MSHELL_CMD_FUN_H__
     2 #define __MSHELL_CMD_FUN_H__
     3 
     4 #include "mshell_common.h"
     5 #include <stdio.h>
     6 #include <stdlib.h>
     7 #include <unistd.h>
     8 #include <string.h>
     9 
    10 #define MSHELL_CMD_CD            "cd"
    11 #define MSHELL_CMD_PWD            "pwd"
    12 #define MSHELL_CMD_EXIT            "exit"
    13 #define MSHELL_CMD_ENV            "env"
    14 #define MSHELL_CMD_ECHO            "echo"
    15 #define MSHELL_CMD_EXPORT        "export"
    16 
    17 typedef void (* mshell_cmd_Fun)(char *args);
    18 typedef struct {
    19     char *cmd;
    20     mshell_cmd_Fun    callback;
    21 }mshell_funs_t;
    22 
    23 mshell_error_t mshell_Cmd_ExcuFun(char **args);
    24 mshell_error_t mshell_Cmd_ExcuOther(char **args);
    25 #endif
    View Code

      mshell_cmd_fun.c

      1 #include "mshell_cmd_fun.h"
      2 
      3 extern char** environ;
      4 
      5 static void mshell_cmd_Cd(char *args)
      6 {
      7     if(chdir(args) < 0) {
      8         perror("cd error");
      9     }
     10 }
     11 
     12 static void mshell_cmd_Pwd(char *args)
     13 {
     14     char buffer[256];
     15     memset(buffer, 0, sizeof(buffer));
     16     if(getcwd(buffer, sizeof(buffer)) == NULL){
     17         perror("pwd error");
     18     }
     19 
     20     printf("%s
    ", buffer);
     21 }
     22 
     23 static void mshell_cmd_Exit(char *args)
     24 {
     25     exit(0);
     26 }
     27 
     28 static void mshell_mcd_Env(char *args)
     29 {
     30     int i = 0;
     31     char *env = NULL;
     32 
     33     while(NULL != (env = environ[i])) {
     34         printf("%s
    ", env);
     35         i++;
     36     }
     37 }
     38 
     39 static void mshell_mcd_Echo(char *args)
     40 {
     41     char *arg_tmp = args;
     42     if(NULL == arg_tmp) {
     43         fprintf(stderr, "echo: invalid argument
    ");
     44         return;
     45     }
     46 
     47     if('$' == arg_tmp[0]) {
     48         char *env_tmp = getenv(arg_tmp + 1);
     49         printf("%s
    ", env_tmp);
     50     }
     51     else {
     52         printf("%s
    ", arg_tmp);
     53     }
     54 }
     55 
     56 static void mshell_mcd_Export(char *args)
     57 {
     58     if(NULL == args) {
     59         fprintf(stderr, "export: invalid argument
    ");
     60         return;
     61     }
     62 
     63     putenv(args);
     64 }
     65 
     66 static mshell_funs_t mshell_table_fun[] = {
     67     /** cmd                    func */
     68     {MSHELL_CMD_CD    ,        mshell_cmd_Cd},
     69     {MSHELL_CMD_PWD ,        mshell_cmd_Pwd},
     70     {MSHELL_CMD_EXIT,        mshell_cmd_Exit},
     71     {MSHELL_CMD_ENV ,        mshell_mcd_Env},
     72     {MSHELL_CMD_ECHO,        mshell_mcd_Echo},
     73     {MSHELL_CMD_EXPORT,        mshell_mcd_Export},
     74 };
     75 
     76 mshell_error_t mshell_Cmd_ExcuFun(char **args)
     77 {
     78     if(NULL == args) {
     79         return MSHELL_ERROR_PARAM;
     80     }
     81     int len = sizeof(mshell_table_fun) / sizeof(mshell_funs_t);
     82     int i;
     83     for(i = 0; i < len; i++) {
     84         if(!strcmp(args[0], mshell_table_fun[i].cmd)){
     85             mshell_table_fun[i].callback(args[1]);
     86             return MSHELL_ERROR_NONE;
     87         }
     88     }
     89 
     90     return MSHELL_ERROR_CMD_NONECMD;
     91 }
     92 
     93 mshell_error_t mshell_Cmd_ExcuOther(char **args)
     94 {
     95     /** excu 函数成功执行不返回,出错会返回 -1 */
     96     if(execvp(args[0], args) < 0) {
     97         perror("execvp error");
     98         /** 这里退出后,让后面的程序继续执行 */
     99         return MSHELL_ERROR_CMD_NONECMD;
    100     }
    101 
    102     return MSHELL_ERROR_NONE;
    103 }
    View Code

    29.6 重定向

      mshell_redirection.h

     1 #ifndef __MSHELL_REDIRECTION_H__
     2 #define __MSHELL_REDIRECTION_H__
     3 
     4 #include "mshell_common.h"
     5 #include <stdio.h>
     6 #include <stdlib.h>
     7 #include <unistd.h>
     8 #include <fcntl.h>
     9 #include <string.h>
    10 
    11 #define MSHELL_REDIRECTION_NUMBER        5
    12 
    13 #define MSHELL_REDIRECTION_READ            "<"
    14 #define MSHELL_REDIRECTION_WRITE        ">"
    15 #define MSHELL_REDIRECTION_APPEND        ">>"
    16 
    17 typedef enum {
    18     mshell_Redirection_Read,
    19     mshell_Redirection_Write,
    20     mshell_Redirection_Append
    21 }mshell_redirection_type_t;
    22 
    23 typedef struct {
    24     mshell_redirection_type_t    type;
    25     int                            fd;
    26 }mshell_redirection_t;
    27 
    28 typedef mshell_redirection_t* (* mshell_redirection_fun)(char *file);
    29 typedef struct {
    30     char                     *type;
    31     mshell_redirection_fun     callback;
    32 }mshell_table_redirection_t;
    33 
    34 typedef void (* mshell_redirection_ExcuFun)(int fd);
    35 typedef struct {
    36     mshell_redirection_type_t    type;
    37     mshell_redirection_ExcuFun    callback;
    38 }mshell_Table_redirectionExcu_t;
    39 
    40 extern mshell_redirection_t *mshell_redirection_Create(int fd, mshell_redirection_type_t type);
    41 extern void mshell_redirection_Destroy(mshell_redirection_t *redirection);
    42 extern mshell_redirection_t *mshell_redirection_Parse(
    43         mshell_redirection_t **redirection,
    44         int num,
    45         char *args,
    46         mshell_error_t *error);
    47 extern void mshell_redirections_Free(mshell_redirection_t **redirections, int num);
    48 extern void mshell_redirection_Excu(mshell_redirection_t redirection);
    49 #endif
    View Code

      mshell_redirection.c

      1 #include "mshell_redirection.h"
      2 
      3 
      4 mshell_redirection_t *mshell_redirection_Create(int fd, mshell_redirection_type_t type)
      5 {
      6     mshell_redirection_t *redirection = (mshell_redirection_t *)calloc(1, sizeof(mshell_redirection_t));
      7     if(NULL == redirection){
      8         return NULL;
      9     }
     10 
     11     redirection->fd = fd;
     12     redirection->type = type;
     13     return redirection;
     14 }
     15 
     16 void mshell_redirection_Destroy(mshell_redirection_t *redirection)
     17 {
     18     if(NULL == redirection) {
     19         return;
     20     }
     21     free(redirection);
     22 }
     23 
     24 static mshell_redirection_t *mshell_redirection_Read(char *file)
     25 {
     26     int fd = open(file, O_RDONLY);
     27     mshell_redirection_t *redirection = mshell_redirection_Create(fd, mshell_Redirection_Read);
     28     return redirection;
     29 }
     30 
     31 static mshell_redirection_t *mshell_redirection_Write(char *file)
     32 {
     33     int fd = open(file, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU | S_IRWXG | S_IRWXO);
     34     mshell_redirection_t *redirection = mshell_redirection_Create(fd, mshell_Redirection_Write);
     35     return redirection;
     36 }
     37 
     38 static mshell_redirection_t *mshell_redirection_Append(char *file)
     39 {
     40     int fd = open(file, O_WRONLY | O_CREAT | O_APPEND, S_IRWXU | S_IRWXG | S_IRWXO);
     41     mshell_redirection_t *redirection = mshell_redirection_Create(fd, mshell_Redirection_Append);
     42     return redirection;
     43 }
     44 
     45 static mshell_table_redirection_t mshell_redirection_table[] = {
     46     /** args                    func */
     47     {MSHELL_REDIRECTION_READ,    mshell_redirection_Read},
     48     {MSHELL_REDIRECTION_WRITE,    mshell_redirection_Write},
     49     {MSHELL_REDIRECTION_APPEND,    mshell_redirection_Append},
     50 };
     51 
     52 mshell_redirection_t *mshell_redirection_Parse(
     53         mshell_redirection_t **redirection,
     54         int num,
     55         char *args,
     56         mshell_error_t *error)
     57 {
     58     int len = sizeof(mshell_redirection_table) / sizeof(mshell_table_redirection_t);
     59     int i;
     60 
     61     for(i = 0; i < len; i++) {
     62         if(!strcmp(args, mshell_redirection_table[i].type)) {
     63             char *file = strtok(NULL, " ");
     64             if(NULL == file) {
     65                 *error = MSHELL_ERROR_REDIRECION_PARAM;
     66                 return NULL;
     67             }
     68             else
     69             {
     70                 redirection[num] = mshell_redirection_table[i].callback(file);
     71                 if(NULL == redirection[num]){
     72                     *error = MSHELL_ERROR_REDIRECTION_CREATE;
     73                     return NULL;
     74                 }
     75                 else {
     76                     *error = MSHELL_ERROR_NONE;
     77                     return redirection[num];
     78                 }
     79             }
     80         }
     81     }
     82 
     83     return NULL;
     84 }
     85 
     86 void mshell_redirections_Free(mshell_redirection_t **redirections, int num)
     87 {
     88     if(NULL == redirections){
     89         return;
     90     }
     91     int i;
     92     for(i = 0; i < num; i++) {
     93         mshell_redirection_Destroy(redirections[i]);
     94     }
     95 
     96 }
     97 
     98 static void mshell_redirection_ExcuRead(int fd)
     99 {
    100     if(dup2(fd, STDIN_FILENO) != STDIN_FILENO) {
    101         perror("dup2");
    102     }
    103 }
    104 
    105 static void mshell_redirection_ExcuWrite(int fd)
    106 {
    107     if(dup2(fd, STDOUT_FILENO) != STDOUT_FILENO) {
    108         perror("dup2");
    109     }
    110 }
    111 
    112 static void mshell_redirection_ExcuAppend(int fd)
    113 {
    114     if(dup2(fd, STDOUT_FILENO) != STDOUT_FILENO) {
    115         perror("dup2");
    116     }
    117 }
    118 
    119 static mshell_Table_redirectionExcu_t mshell_redirection_ExcuTable[] = {
    120     /** type                            func */
    121     {mshell_Redirection_Read,            mshell_redirection_ExcuRead},
    122     {mshell_Redirection_Write,            mshell_redirection_ExcuWrite},
    123     {mshell_Redirection_Append,            mshell_redirection_ExcuAppend},
    124 };
    125 
    126 /** 对标准输入、标准输出和追加进行重定向 */
    127 void mshell_redirection_Excu(mshell_redirection_t redirection)
    128 {
    129     int i;
    130     int len = sizeof(mshell_redirection_ExcuTable) / sizeof(mshell_Table_redirectionExcu_t);
    131     for(i = 0; i < len; i++) {
    132         if(redirection.type == mshell_redirection_ExcuTable[i].type) {
    133             mshell_redirection_ExcuTable[i].callback(redirection.fd);
    134         }
    135     }
    136 }
    View Code

    29.7 进程

      mshell_process.h

     1 #ifndef __MSHELL_PROCESS_H__
     2 #define __MSHELL_PROCESS_H__
     3 
     4 #include "mshell_common.h"
     5 #include <unistd.h>
     6 #include <sys/wait.h>
     7 #include <stdio.h>
     8 #include <stdlib.h>
     9 #include <string.h>
    10 
    11 typedef enum {
    12     MSHELL_PROCESS_FORE = 0,
    13     MSHELL_PROCESS_BACK = 1
    14 }mshell_process_Flag_t;
    15 
    16 /** 解析 & 符号,设置进程组标志为前台或后台进程标指 */
    17 extern mshell_process_Flag_t mshell_process_BackParse(char *args, int *error);
    18 extern pid_t mshell_process_GroupGet(pid_t pid, pid_t group_pid);
    19 extern void mshell_process_GroupSet(mshell_process_Flag_t process_flag, pid_t pid);
    20 extern void mshell_process_Wait(mshell_process_Flag_t process_flag, pid_t pgid);
    21 
    22 #endif /* INCLUDE_MSHELL_PROCESS_H_ */
    View Code

      mshell_process.c

     1 /*
     2  * mshell_process.c
     3  *
     4  *  Created on: 2018年12月26日
     5  *      Author: homework
     6  *  brief:
     7  *      启动的 minishell 本身就是一个进程,在一个进程组当中,
     8  *      在 minishell 中启动的若干个进程中,其中就有一个父进程,也可能还有其他子进程
     9  *      在此基础上,再做一个进程组
    10  *      把 minishell 启动起来后,做为一个进程组,minishell 为组长进程
    11  *      在 minishell 上启动多个进程,将这些进程作为一个进程组
    12  *  1. 把 minishell 单独设置为一个进程组
    13  *  2. 把在 minishell 中启动的进程设置为一个进程组
    14  *      2.1 把在 minishell 中启动的第一个进程作为进程组的组长
    15  *      2.2 后面创建的进程放置进此进程组当中
    16  */
    17 
    18 
    19 #include "mshell_process.h"
    20 
    21 
    22 /** 解析 & 符号,设置进程组标志为前台或后台进程标指 */
    23 mshell_process_Flag_t mshell_process_BackParse(char *args, int *error)
    24 {
    25     mshell_process_Flag_t process_flag = MSHELL_PROCESS_FORE;
    26     if(!strcmp(args, "&")){
    27         process_flag = MSHELL_PROCESS_BACK;
    28         *error = 0;
    29         return process_flag;
    30     }
    31 
    32     *error = -1;
    33     return process_flag;
    34 }
    35 
    36 /** 创建进程组并获取进程组 ID */
    37 pid_t mshell_process_GroupGet(pid_t pid, pid_t group_pid)
    38 {
    39     if(setpgid(pid, group_pid) < 0) {
    40         perror("setpgid error");
    41     }
    42 
    43     return group_pid;
    44 }
    45 
    46 /** 设置前台进程组 */
    47 void mshell_process_GroupSet(mshell_process_Flag_t process_flag, pid_t pid)
    48 {
    49     if(process_flag == MSHELL_PROCESS_FORE) {
    50         tcsetpgrp(0, getpgid(pid));
    51     }
    52 }
    53 
    54 void mshell_process_Wait(mshell_process_Flag_t process_flag, pid_t pgid)
    55 {
    56     if(process_flag == MSHELL_PROCESS_FORE) {
    57         waitpid(-pgid, NULL, WUNTRACED);
    58     }
    59 
    60     if(process_flag == MSHELL_PROCESS_BACK) {
    61         waitpid(-pgid, NULL, WNOHANG);
    62     }
    63 }
    View Code
  • 相关阅读:
    04_web基础(六)之请求转发与重定向
    04_web基础(五)之cookie与session
    04_web基础(四)之servlet详解
    04_web基础(三)之进一步理解web
    04_web基础(二)之web构建
    本地密码提取工具-LAZAGNE
    免杀工具汇总
    流量取证-提取文件
    CA证书安装以及sslh协议转发
    ssh 端口转发
  • 原文地址:https://www.cnblogs.com/kele-dad/p/9201411.html
Copyright © 2011-2022 走看看