APUE习题8.7

exec在执行前会关闭所有打开的目录流(DIR)

  • 检查文件描述符状态标志,

    1. dirfd(DIR *)得到目录的文件描述符

    2. 重要的fcntl()函数,得到文件描述符状态

    3. 忽略了exec族函数的第一个参数的作用导致调用exec一直成功

      exec的第一个参数一般是可执行文件的文件名,

      The first argument, by convention, should point to the filename associated with the file being executed.

    4. 一定要注意如果使用标准IO,就要想到缓冲的方式,不然会以为是逻辑的错误

// a.c
#include <sys/wait.h>
#include <sys/types.h>
#include <fcntl.h>
#include <dirent.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h> 
#include "apue.h"

int testDir() {
	DIR *dirp;

	if ((dirp = opendir("/home/luchao/Documents/Apue/8")) == NULL)
		err_sys("opendir error");
	int fd = dirfd(dirp);
	int status;
	if ((status = fcntl(fd,F_GETFD)) == -1)
		err_sys("fcntl error");
	// 子进程执行exec时关闭所有打开的文件描述符,
	if (status & FD_CLOEXEC)
		printf("close-on-exec on");
	else 
		printf("close-on-exec close");

	// 关闭 close on exec 标志,也就是在调用exec时,不关闭所有的文件描述符
//	status &= (~FD_CLOEXEC); 
//	if ((status = fcntl(fd,F_SETFD,status)) < 0)
//		err_sys("fcntl2 error");

	return fd;
}

int testFile() {
	int fd;
	if ((fd = open("/home/luchao/Documents/Apue/8/1.in",O_RDWR)) == -1)
		err_sys("open error");
	int status;
	if ((status = fcntl(fd,F_GETFD,0)) == -1)
		err_sys("fcntl error");
	if (status & FD_CLOEXEC)
		printf("close on exec on");
	else 
		printf("close on exec close");
	
	return fd;	
}

int main(int argc,char *argv[]) {
//	int fd = testDir();
	int fd = testFile();
//	setbuf(stdout,NULL);
	pid_t pid;
	char buf[10];
	sprintf(buf,"%d",fd);

	if ((pid = fork()) < 0)
		err_sys("fork error");
	else if (pid == 0) {	
		char *path = "/home/luchao/Documents/Apue/8/b";
		if (execl(path,"b",buf,(char *)0) < 0)
			err_sys("execl error");
	}

	if (waitpid(pid,NULL,0) == -1)
		err_sys("error waitpid");
    exit(0);
}

// b.c
#include "apue.h"
#include <fcntl.h>
#include <stdio.h>

int main(int argc,char *argv[]) {
	int status,fd;
	for (int i=0; i<argc; ++i)
		printf("argv[%d] = %s ",i,argv[i]);
	
	if (argv[1] != NULL)
		sscanf(argv[1],"%d",&fd);
	else 
		fd = -1;
	if ((status = fcntl(fd,F_GETFD,0)) < 0)
		err_sys("fcntl error");
	if (status & FD_CLOEXEC) 
		printf("close on exec on");
	else 
		printf("close on exec close");
    exit(0);
}
  • 测试可以看出目录流的文件描述符设置了close-on-exec位,而普通文件描述符没有设置

一段理解fork的代码

#include <sys/types.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
 
int main(int argc,char *argv[]) {
	int fd;
	if ((fd = open("/home/luchao/Documents/Apue/8/1.in",O_RDWR|O_CREAT,0644)) == -1)
		exit(1);	
    // 调整i< 验证
	for (int i=0; i<4; ++i) {
		fork();
		// 用非缓冲Io看看结果
		write(fd,"x",1);
	}
    exit(0);
}
  1. 用非缓冲看fork的子进程执行情况

fork的进程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值