一个简单的外壳程序的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
Hello!
1
BYE
2
BYE
当执行上面的代码时
[jsh@localhost 8]$ ./a.out
dc[jsh@localhost 8]$ d
dc[jsh@localhost 8]$ d
问题是 在fork 之前分别打印了 d 和hello 第一个hello打印一个,第二d打印2个,为什么?
- 一个简单的外壳程序的main历程
- 自己写一个简单的unix外壳
- 一个程序的奋斗历程
- 一个程序汪的历程
- IShellIconOverlayIdentifier接口的外壳程序
- 编写一个MPlayer的外壳
- 程序人生 : 一个程序员的奋斗历程
- 程序人生:一个程序员的奋斗历程
- 一个边缘程序猿的坎坷历程
- 编一个程序的辛酸历程
- 一个MFC程序的生命历程
- 一个C&C++程序的生命历程
- Java启动外壳程序的开发
- 简单的一个程序
- 一个简单的程序
- 一个简单的程序
- 我的程序历程
- 一个程序员的历程
- hadoop深入研究:(四)——distcp
- 送给只会PHP的程序员们一些话
- hadoop深入研究:(五)——Archives
- hadoop深入研究:(六)——HDFS数据完整性
- 第八章 例8.1
- 一个简单的外壳程序的main历程
- 在MFC中使用Qt生成的DLL
- hadoop深入研究:(七)——压缩
- Java串口通信
- Linux操作系统下三种配置环境变量的方法
- 高精度整数加法
- hadoop深入研究:(八)——codec
- android eclipse 程序调试及相关快捷键
- Linux内核分析 - 网络[七]:NetFilter