一个简单的外壳程序的main历程

来源:互联网 发布:对战平台mac版 编辑:程序博客网 时间:2024/06/05 21:05

    在阅读《深入理解计算机操作系统》书的第八章看到这个简单的外壳程序的main,偶尔联想到自己工作中的调试程序,应该和这个实现方式是一样的,可能公司的会用到进程间的通信,但是原型基本都是这样的。具体看代码吗?代码有部分修改,同时我个人也有很多疑问大家求解?先贴代码吧!

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <unistd.h>#define MAXARGS 128pid_t FORK(){    pid_t pid;    if((pid = fork()) < 0){        printf("fork error!\n");    }    return pid;}/*解析命令行*/int parseline(char *buf,char **argv){    char *delim;    int argc;    int bg;    /*将换行符转换成空格方便解析*/    buf[strlen(buf) - 1] = ' ';    /*忽略空格*/    while(*buf && *buf == ' '){        buf++;    }    argc = 0;    while((delim = strchr(buf,' '))){        argv[argc++] = buf;        *delim = '\0';        buf = delim + 1;        while(*buf && *buf == ' '){            buf++;        }    }    argv[argc] = NULL;        /*没有输入执行命令,返回1*/    if(argc == 0){        return 1;    }    /*是否后台运行     *1:后台运行,0: 不是     * */    if(*argv[argc - 1] == '&'){        bg = 1;        argv[--argc] = NULL;    }else{        bg = 0;    }    return bg;}/*判断是退出程序还是忽略执行命令 */int builtin_command(char **argv){    if(!strcmp(argv[0],"quit")){        exit(0);    }    if(!strcmp(argv[0],"&")){//忽略 命令        return 1;    }    return 0;}/*执行命令行 * */void eval(char *cmdline){    char *argv[MAXARGS];    char buf[MAXARGS];    int bg;    pid_t pid;    char * envp[ ]={"PATH=/bin",0};    strncpy(buf,cmdline,MAXARGS);    bg = parseline(buf,argv);       if(argv[0] == NULL){//忽略空行        return;    }    if(!builtin_command(argv)){        if((pid = FORK()) == 0){//子进程运行代码            if(execve(argv[0],argv,envp) < 0){                printf("%s:command not found.\n",argv[0]);                exit(0);            }else{                printf("1111111111111\n");                exit(2);            }        }                /*这个是个疑问???         * 当父进程是后台运行时,子进程退出是不是有系统回收??*/        if(pid > 0 && !bg){            int status;            if(waitpid(pid,&status,0) < 0){                printf("waitfg:waited,errr\n");            }else{                printf("%d,exit!\n",pid);            }        }else{            printf("%d %s",pid,cmdline);        }    }    return;}int main(){    char cmdline[MAXARGS];    while(1){        printf("[jsh_dbug] > ");        //从终端输入        fgets(cmdline,MAXARGS,stdin);        if(feof(stdin)){            exit(0);        }        //执行程序        eval(cmdline);    }}


目前不理解的问题:

1、当程序运行的后台时,创建的子进程退出时的是有操作系统回收的吗?在代码中看到这样的处理机制,当运行程序后,在终端输入命令后,结尾加 & 符号,不同的处理。

[jsh@localhost 8]$ ./a.out [jsh_dbug] > /bin/pwd/home/jsh/mystudy/com/89285,exit![jsh_dbug] > [jsh_dbug] > /bin/pwd &9289 /bin/pwd &[jsh_dbug] > /home/jsh/mystudy/com/8[jsh_dbug] > quit[jsh@localhost 8]$ 

2、这个疑问可能和这个代码没有什么关系,是关于fork函数的疑问,看下面代码吧


  
#include <stdio.h>#include <unistd.h>#include <sys/types.h>#include <stdlib.h>pid_t FORK(){    pid_t pid;    if((pid = fork()) < 0){        printf("fork error!\n");    }    return pid;}#if 0int main(){        printf("d");    if(FORK() == 0){     //   sleep(1);   //     printf("a");          exit(0);    }        // printf("b");       // waitpid(-1,NULL,0);        printf("c");    exit(0);}#endif#if 
int main(){    int status;    pid_t pid;    printf("Hello!\n");    pid = FORK();    if(pid == 0){    printf("%d\n",!pid);    }    if(pid != 0){        if(waitpid(-1,&status,0) >  0){            if(WIFEXITED(status) != 0)                printf("%d\n",WEXITSTATUS(status));        }    }    printf("BYE\n");    exit(2);}#endif

上面代码中有2个mian函数,先执行下面的打印如下:

[jsh@localhost 8]$ ./a.out 
Hello!
1
BYE
2
BYE

当执行上面的代码时

[jsh@localhost 8]$ ./a.out 
dc[jsh@localhost 8]$ d

问题是 在fork 之前分别打印了 d 和hello    第一个hello打印一个,第二d打印2个,为什么?


原创粉丝点击