#define FILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
S_IRUSR Permits the file's owner to read it. S_IWUSR Permits the file's owner to write to it. S_IRGRP Permits the file's group to read it. S_IWGRP Permits the file's group to write to it. |
偶把apue.h and apue.cpp 码出来了:
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#define FILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
#define MAXLINE 4096
#define DIR_MODE (FILE_MODE|S_IXUSR|S_IXGRP|S_IXOTH)
typedef void Sigfunc(int);
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
void err_dump(const char* ,...);
void err_msg(const char*, ...);
void err_quit(const char*,...);
void err_exit(const char*,...);
void err_ret(const char*,...);
void err_sys(const char*,...);
void log_msg(const char*,...);
void log_open(const char*,...);
void log_quit(const char*,...);
void log_ret(const char*,...);
void log_sys(const char*,...);
#include "apue.h"
#include <errno.h>
#include <stdarg.h>
void err_doit(int errFlag, int err, const char* fmt, va_list ap){
char buf[MAXLINE];
vsnprintf(buf, MAXLINE, fmt, ap);
if(errFlag){
snprintf(buf+strlen(buf), MAXLINE-strlen(buf),": %s", strerror(err));
}
strcat(buf, "\n");
fflush(stdout);
fputs(buf,stderr);
fflush(NULL);
}
void err_ret(const char* fmt,...){
va_list ap;
va_start(ap, fmt);
err_doit(1,errno,fmt,ap);
va_end(ap);
}
void err_sys(const char* fmt, ...){
va_list ap;
va_start(ap, fmt);
err_doit(1,errno,fmt,ap);
va_end(ap);
exit(1);
}
void err_exit(int error, const char* fmt, ...){
va_list ap;
va_start(ap, fmt);
err_doit(1,errno,fmt,ap);
va_end(ap);
exit(1);
}
void err_dump(const char* fmt, ...){
va_list ap;
va_start(ap, fmt);
err_doit(1,errno,fmt,ap);
va_end(ap);
abort();
exit(1);
}
void err_msg(const char* fmt, ...){
va_list ap;
va_start(ap, fmt);
err_doit(0,0,fmt,ap);
va_end(ap);
}
void err_quit(const char* fmt, ...){
va_list ap;
va_start(ap, fmt);
err_doit(0,0,fmt,ap);
va_end(ap);
exit(1);
}
然后1-5的代码很有意思:
#include "apue.h"
#include <sys/wait.h>
int main(){
char buf[MAXLINE];
pid_t pid;
int status;
printf("%% ");
while(fgets(buf,MAXLINE,stdin)!= NULL){
if(buf[strlen(buf)-1] == '\n'){
buf[strlen(buf)-1] = 0;
}
if((pid = fork()) < 0){
err_sys("fork error");
}
else if(0 == pid){
execlp(buf,buf,(char*)0);
err_ret("could't execute:%s.",buf);
exit(127);
}
if(pid = waitpid(pid,&status,0) < 0){
err_sys("waitpid error.");
}
printf("%%");
}
}
这个函数:
int execlp(const char * file,const char * arg,...,(char *)0);
execlp()会从PATH
环境变量所指的目录中查找符合参数file的文件名,找到后便执行该文件,然后将第二个以后的参数当做该文件的argv[0]、argv[1]……,最后一个参数必须用空
指针(NULL)作结束。如果用常数0来表示一个空
指针,则必须将它强制转换为一个字符指针,否则将它解释为整形参数,如果一个整形数的长度与char * 的长度不同,那么exec函数的
实际参数就将出错。如果
函数调用成功,进程自己的执行代码就会变成加载程序的代码,execlp()后边的代码也就不会执行了.
返回值:
如果执行成功则函数不会返回,执行失败则直接返回-1,失败原因存于errno 中。
创建子进程并在子进程里执行stdin来的命令
父进程会等待子进程结束。