1. fcntl函数
#include<unistd.h>
#include<fcntl.h>
int fcntl(int fd, int cmd, .../*arg*/);
/*
功能:
改变已打开文件的性质:
a) 复制一个现有的文件描述符(cmd=F_DUPFD),类似dup函数(不是dup2)
b) 获取或设置文件描述符标记(cmd=F_GETFD或F_SETFD)
c) 获取或设置文件状态标记(cmd=GETFL或SETFL)
仅能改变O_APPEND、O_ASYNC、O_DIRECT、O_NOATIME、O_NONBLOCK
d) 获取或设置异步I/O所有权(cmd=GETOWN或F_SETOWN)
e) 获取或设置记录锁(cmd=F_GETLK,F_SETLK或F_SETLKW)
参数:
fd:需要操作的文件描述符
cmd:操作方式
arg:针对cmd的值
返回值:
成功:某个其他值
失败:-1
*/
a)复制一个现有的文件描述符示例:
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
#include<fcntl.h>
#define SIZE 128
int test() {
int fd = -1;
int ret = -1;
int newfd = -1;
char buf[SIZE];
// 1.打开文件
fd = open("txt02", O_RDWR | O_CREAT, 0644); // 设置为O_RDWE后续才可以读
if (-1 == fd) {
perror("open");
return 1;
}
printf("fd = %d\n", fd);
// 2. 复制文件描述符
// 第三个参数写0,意思是让系统自动分配一个最小可使用的文件描述符
newfd = fcntl(fd, F_DUPFD, 0);
if (-1 == newfd) {
perror("fcntl");
return 1;
}
printf("newfd = %d\n", newfd);
// 3. 写操作
ret = write(fd, "123", 3);
if (-1 == ret) {
perror("write fd");
return 1;
}
ret = write(newfd, "ABC", 3);
if (-1 == ret) {
perror("write newfd");
return 1;
}
// 4. 读文件
lseek(newfd, 0, SEEK_SET);
memset(buf, 0, SIZE);
ret = read(fd, buf, SIZE);
printf("read: %s\n", buf);
// 5.关闭文件
close(fd);
close(newfd);
}
运行结果:
b)获取、设置文件状态标记示例:
仅能改变O_APPEND、O_ASYNC、O_DIRECT、O_NOATIME、O_NONBLOCK.
fcntl将文件的打开方式改为追加示例:
/* c) fcntl将文件的打开方式改为追加示例*/
int test02() {
int fd = -1;
int ret = -1;
// 1. 打开文件
fd = open("txt03", O_RDONLY | O_CREAT, 0644);
if (-1 == fd) {
perror("open");
return 1;
}
printf("fd = %d\n", fd);
// 2. 获取文件状态标记
ret = fcntl(fd, F_GETFL);
if (-1 == ret) {
perror("fcntl F_GETFL");
return 1;
}
if (ret & O_APPEND) {
printf("文件状态已是O_APPEND\n");
} else {
printf("文件状态不是O_APPEND\n");
}
// 3. 设置文件状态标记
ret = ret | O_APPEND;
ret = fcntl(fd, F_SETFL, ret);
if (-1 == ret) {
perror("fcntl F_SETFL");
return 1;
}
// 4. 获取文件状态标记
ret = fcntl(fd, F_GETFL);
if (-1 == ret) {
perror("fcntl F_GETFL");
return 1;
} else if (ret & O_APPEND) {
printf("fcntl: 设置成功.\n");
}
// 5. 关闭文件
close(fd);
return 0;
}
运行结果: