Contents
  1. 1. 重看APUE
  2. 2. 进程
  3. 3. 总结

重看APUE

最近在折腾一些东西的时候,发现自己的操作系统知识很可怜,于是打算抽点时间学习APUE。其实与其说是重看,和第一次看也没有太多区别,之前上过一次选修但是很可惜当时没有心境沉下来上课,都做项目去了。现在我很想从头到尾认真的看一遍,虽然目前是做到了,但是以后可能时间吃紧,只能挑着看了。
最好的学习方法当然是看与写结合,所以我第一个例程,我看懂原理之后就会尝试自己“写”一遍,实际情况看比你”自以为看懂”地浏览过去效果要好。

进程

这一部分内容是我遇到的第一个觉得比较有意思的程序,今天就写这个吧,下面是一个简单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
#include "apue.h"
int main(void){
char buff[MAXLINE];
pid_t pid;
int status;
printf("%%"); //打印提示符,两个%%
while(fgets(buff,MAXLINE,stdin)!=NULL){ //遇到 EOF会返回NULL,所以可以ctrl+D退出这个shell
if( (pid = fork()) <0 ){ //尝试fork,返回负则表示失败,如果成功则会产生父进程的copy
err_sys("failed to fork");
}else if(pid == 0){ //fork对子进程返回0,以下进入子进程
buff[strlen(buff)-1]=0; //细节,将回车替换为0
execlp(buff, buff, (char *) 0); //execlp会加载指定程序,并覆盖当前进程数据(也就是说没以下两条指令的事了)
err_ret("could not exec %s",buff); //如果进入到这里,则说明加载程序失败了(数据没被erase)
exit(127);
}
//return to the main process, 既然是开启了新进程,自然会立刻返回主进程,我们要设置等待
pid = waitpid(pid, &status , 0); //这个status是子进程的返回状态,这时并没有检查该值
if(pid < 0){
err_sys("wait pid error");
}
printf ("%%");
}
}

运行效果

1
2
3
4
5
6
7
8
chen@vaio:/data/apue.2e/chen$ ./a.out
%ls
a.out apue.h error.c mycat.c mycatstdio.c myls.c mysh.c pid.c
%pwd
/data/apue.2e/chen
%date
2015年 04月 17日 星期五 02:08:15 CST
%

总结

这个程序有两个比较有意思的地方:

  1. fork一次调用两次返回。以命令执行成功为例,第一个else中返回0给子进程,waitpid时父进程使用的是另一返回值,即子进程ID。
  2. execlp会加载指定程序并覆盖当前程序栈,所以可以看到execlp之后并没有判断条件就直接可以报错了
Contents
  1. 1. 重看APUE
  2. 2. 进程
  3. 3. 总结