在阅读《深入理解计算机操作系统》书的第八章看到这个简单的外壳程序的main,偶尔联想到自己工作中的调试程序,应该和这个实现方式是一样的,可能公司的会用到进程间的通信,但是原型基本都是这样的。具体看代码吗?代码有部分修改,同时我个人也有很多疑问大家求解?先贴代码吧!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#define MAXARGS 128
pid_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/8
9285,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 0
int 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