a.txt文件内容如下:
hello,world。
编写两个不同的可执行程序,名称分别为a和b。在a程序中调用open函数打开a.txt文件,在b程序不可调用open或者fopen。只允许调用read函数来实现读取a.txt文件(a程序中可以使用fork和execv函数创建子进程)。
makefile
.SUFFIXES: .c .o
CC=gcc
SRCS=a.c
OBJS=$(SRCS:.c=.o)
EXEC=a
all: $(OBJS)
$(CC) -o $(EXEC) $(OBJS)
@echo '-------------ok--------------'
.c.o:
$(CC) -Wall -g -o $@ -c $<
clean:
rm -f $(OBJS)
rm -f core*
a.c
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
printf("a begin\n");
int fd = open("a.txt", O_RDONLY);
if (fd == -1)//打开文件失败
{
printf("error is %s\n", strerror(errno));
return -1;
}
pid_t pid = fork();//fork调用,在内存中克隆一个与自己一样的副本
if (pid < 0)
{
printf("fork failed %s\n", strerror(errno));
return -1;
}
if (pid > 0)//父进程
{
close(fd);//父进程关闭打开的文件描述符fd
}
if (pid == 0)//子进程
{
char s[128];
memset(s, 0, sizeof(s));
sprintf(s, "%d", fd);//将打开a.txt文件后的文件描述符fd格式化为字符串
char *args[] = { "b", s, NULL };
if (execve("b", args, NULL) == -1)//将文件描述符fd作为启动参数传递给b程序
{
printf("execve failed %s\n", strerror(errno));
}
}
printf("a end..\n");
return 0;
}
b.c
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int arg, char *args[])
{
printf("b begin..\n");
if (args[1] == NULL)//b启动的时候,如果没有参数,main函数直接退出
{
printf("Usage: b xxx\n");
return -1;
}
int fd = atoi(args[1]);//将第一个参数从字符串转化为整数,此参数就是文件描述符fd
if (fd == 0)//如果参数为0,函数返回
{
return -1;
}
char buf[1024];
memset(buf, 0, sizeof(buf));
read(fd, buf, sizeof(buf));//读取文件
printf("%s", buf);
close(fd);//关闭文件描述符
printf("b end..\n");
return 0;
}