#include "apue.h" #include <sys/wait.h> int main(void) { char buf[MAXLINE];//from apue.h pid_t pid; int status; printf("%% ");//print prompt while(fgets(buf,MAXLINE,stdin)!=NULL){ if(buf[strlen(buf)-1]=='\n') buf[strlen(buf)-1]=0;//replace newline with null if((pid=fork())<0){ err_sys("fork error"); }else if(pid==0){ execlp(buf,buf,(char *)0); err_ret("couldn't execute: %s",buf); exit(127); } /*parent*/ if((pid=waitpid(pid,&status,0))<0) err_sys("waitpid error"); printf("%% "); } exit(0); }
程序讲解:
(1)fgets函数为标准I/O函数,用于从标准输入读入一行,当键入Ctrl+D时,fgets返回一个null指针,于是循环终止,进程也终止。
(2)execlp函数要求参数以null结束,而不是以换行符结束。所以,此程序用标准C函数strlen计算此字符串的长度,然后用一个null字节替换换行符。
(3)调用fork创建一个新进程。新进程是调用进程的复制品,一般称调用进程为父进程,新创建的进程为子进程。fork函数向父进程返回子进程的进程ID(非负),对子进程则返回0.因为fork创建一个进程,所以说它被调用了一次(由父进程),但返回两次(分别在父进程及子进程中)。
(4)在子进程中,调用execlp函数以执行从标准输入读入的命令。这就用新的程序文件替换了子进程原先执行的程序文件。fork和跟随其后的exec两者的组合是某些操作系统所称的产生一个新进程。
(5)子进程调用execlp执行新程序文件,而父进程希望子进程等待子进程终止,这一要求由调用waitpid函数实现,其参数指定要等待的进程(在此程序里为pid)。
(6)该程序的限制是不能向所执行命令传递参数。