欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

fcntl函数-文件控制函数

发布时间:2025/3/15 编程问答 34 豆豆
生活随笔 收集整理的这篇文章主要介绍了 fcntl函数-文件控制函数 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

今日命令在vim中使用:vsplit ./include/io.h
是以垂直方式打开io.h文件
同理:split ./include/io.h
是以水平方式打开io.h文件

可以用fcntl 函数改变一个已打开的文件的属性,可以重新设置读、写、追加、非阻塞等标志(这些标志称为File StatusFlag),而不必重新open 文件。

#include <unistd.h> #include <fcntl.h> int fcntl(int fd, int cmd); int fcntl(int fd, int cmd, long arg); int fcntl(int fd, int cmd, struct flock *lock);

这个函数和open 一样,也是用可变参数实现的,可变参数的类型和个数取决于前面的cmd 参数。

针对第2个参数,int cmd fcntl函数有五种功能: • 复制一个现存的描述符(cmd=F_DUPFD) 。 • 获得/设置文件描述符标记(cmd=F_GETFD或F_SETFD) 。 • 获得/设置文件状态标志(cmd=F_GETFL或F_SETFL) 。 • 获得/设置异步I/O有权(cmd=F_GETOWN或F_SETOWN) 。 • 获得/设置记录锁(cmd=F_GETLK,F_SETLK或F_SETLKW)。我们将涉及与进程表项中各文件描述符相关联的文件描述符标志, 以及每个文件表项中的文件状态标志,一~复制文件描述符 • F_DUPFD 复制文件描述符filedes,新文件描述符作为函数值返回。它是尚未打开的各 描述符中大于或等于第三个参数值(取为整型值)中各值的最小值。新描述符与 filedes 共享同 一文件表项。但是,新描述符有它自己的一套文件描述符标志,其 F D _ C L O E X E C 文件描述符标志则被清除。 • F_GETFD 对应于filedes 的文件描述符标志作为函数值返回。当前只定义了一个文件描 述符标志FD_CLOEXEC。 • F_SETFD 对于filedes 设置文件描述符标志。新标志值按第三个参数 (取为整型值)设置。 应当了解很多现存的涉及文件描述符标志的程序并不使用常数 F D _ C L O E X E C,而是将此 标志设置为0(系统默认,在exec时不关闭)或1(在exec时关闭)。二~文件描述符号,套接口 属性相关 • F_GETFL 对应于filedes 的文件状态标志作为函数值返回。在说明 open函数时,已说明 了文件状态标志 不幸的是,三个存取方式标志 (O_RDONLY,O_WRONLY,以及O_RDWR)并不各占1位。(正 如前述,这三种标志的值各是 012,由于历史原因。这三种值互斥 — 一个文件只能有这 三种值之一。 )因此首先必须用屏蔽字 O_ACCMODE相与 取得存取方式位,然后将结果与这三种值 相比较。 • F_SETFL 将文件状态标志设置为第三个参数的值 (取为整型值)。 可以更改的几个标志是: O_APPEND,O_NONBLOCK,O_SYNC和O_ASYNC。fcntl的文件状态标志共有7个,O_RDONLY,O_WRONLY,O_RDWR,O_APPEND,O_NONBLOCK,O_SYNC和O_ASYNC三~信号驱动I/O , 带外数据,设置套接口接受信号的属主 SIGIO,跟信号驱动I/O有关 SIGURG, 和接受带外数据有关 • F_GETOWN 取当前接收SIGIO和SIGURG信号的进程ID或进程组ID。12.6.2节将论述这 两种4.3+BSD异步I/O信号。 • F_SETOWN 设置接收SIGIO和SIGURG信号的进程ID或进程组ID。正的arg指定一个进 程ID,负的arg表示等于arg绝对值的一个进程组ID。 struct flock {short_l_type; /*锁的类型*/short_l_whence; /*偏移量的起始位置:SEEK_SET,SEEK_CUR,SEEK_END*/off_t_l_start; /*加锁的起始偏移*/off_t_l_len; /*上锁字节*/pid_t_l_pid; /*锁的属主进程ID */ }; #include <stdio.h> #include <stdlib.h> #include <string.h>int main() {pid_t pid;//以追加的形式打开文件int fd = fd = open("test.txt", O_TRUNC | O_RDWR | O_APPEND | O_CREAT, 0777);if(fd < 0){perror("open");return -1;}printf("fd = %d\n", fd);fcntl(fd, F_SETFD, 0);//关闭fd的close-on-exec标志write(fd, "hello c program\n", strlen("hello c program!\n"));pid = fork();if(pid < 0){perror("fork");return -1;}if(pid == 0){printf("fd = %d\n", fd);int ret = execl("./main", "./main", (char *)&fd, NULL);if(ret < 0){perror("execl");exit(-1);}exit(0);}wait(NULL);write(fd, "hello c++ program!\n", strlen("hello c++ program!\n"));close(fd);return 0; }

main函数

int main(int argc, char *argv[]) {int fd = (int)(*argv[1]);//描述符printf("fd = %d\n", fd);int ret = write(fd, "hello linux\n", strlen("hello linux\n"));if(ret < 0){perror("write");return -1;}close(fd);return 0; }

用命令F_GETFL和F_SETFL设置文件标志,比如阻塞与非阻塞

#include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h>/**********************使能非阻塞I/O******************** *int flags; *if(flags = fcntl(fd, F_GETFL, 0) < 0) *{ * perror("fcntl"); * return -1; *} *flags |= O_NONBLOCK; *if(fcntl(fd, F_SETFL, flags) < 0) *{ * perror("fcntl"); * return -1; *} *******************************************************//**********************关闭非阻塞I/O****************** flags &= ~O_NONBLOCK; if(fcntl(fd, F_SETFL, flags) < 0) {perror("fcntl");return -1; } *******************************************************/int main() {char buf[10] = {0};int ret;int flags;//使用非阻塞ioif(flags = fcntl(STDIN_FILENO, F_GETFL, 0) < 0){perror("fcntl");return -1;}flags |= O_NONBLOCK;if(fcntl(STDIN_FILENO, F_SETFL, flags) < 0){perror("fcntl");return -1;}while(1){sleep(2);ret = read(STDIN_FILENO, buf, 9);if(ret == 0){perror("read--no");}else{printf("read = %d\n", ret);}write(STDOUT_FILENO, buf, 10);memset(buf, 0, 10);}return 0; } struct flcok{short int l_type; /* 锁定的状态*///这三个参数用于分段对文件加锁,若对整个文件加锁,则:l_whence=SEEK_SET,l_start=0,l_len=0;short int l_whence;/*决定l_start位置*/off_t l_start; /*锁定区域的开头位置*/off_t l_len; /*锁定区域的大小*/pid_t l_pid; /*锁定动作的进程*/};l_type 有三种状态:F_RDLCK 建立一个供读取用的锁定F_WRLCK 建立一个供写入用的锁定F_UNLCK 删除之前建立的锁定l_whence 也有三种方式:SEEK_SET 以文件开头为锁定的起始位置。SEEK_CUR 以目前文件读写位置为锁定的起始位置SEEK_END 以文件结尾为锁定的起始位置。 #include "filelock.h"/* 设置一把读锁 */ int readLock(int fd, short start, short whence, short len) {struct flock lock;lock.l_type = F_RDLCK;lock.l_start = start;lock.l_whence = whence;//SEEK_CUR,SEEK_SET,SEEK_ENDlock.l_len = len;lock.l_pid = getpid(); // 阻塞方式加锁if(fcntl(fd, F_SETLKW, &lock) == 0)return 1;return 0; }/* 设置一把读锁 , 不等待 */ int readLocknw(int fd, short start, short whence, short len) {struct flock lock;lock.l_type = F_RDLCK;lock.l_start = start;lock.l_whence = whence;//SEEK_CUR,SEEK_SET,SEEK_ENDlock.l_len = len;lock.l_pid = getpid(); // 非阻塞方式加锁if(fcntl(fd, F_SETLK, &lock) == 0)return 1;return 0; } /* 设置一把写锁 */ int writeLock(int fd, short start, short whence, short len) {struct flock lock;lock.l_type = F_WRLCK;lock.l_start = start;lock.l_whence = whence;lock.l_len = len;lock.l_pid = getpid();//阻塞方式加锁if(fcntl(fd, F_SETLKW, &lock) == 0)return 1;return 0; }/* 设置一把写锁 */ int writeLocknw(int fd, short start, short whence, short len) {struct flock lock;lock.l_type = F_WRLCK;lock.l_start = start;lock.l_whence = whence;lock.l_len = len;lock.l_pid = getpid();//非阻塞方式加锁if(fcntl(fd, F_SETLK, &lock) == 0)return 1;return 0; }/* 解锁 */ int unlock(int fd, short start, short whence, short len) {struct flock lock;lock.l_type = F_UNLCK;lock.l_start = start;lock.l_whence = whence;lock.l_len = len;lock.l_pid = getpid();if(fcntl(fd, F_SETLKW, &lock) == 0)return 1;return 0; } int main(int argc, char *argv[]) {if (argc != 2){printf("usage: a.out <fd>\n");exit(1);}int val = 0;if ((val = fcntl(atoi(argv[1]), F_GETFL)) < 0){printf("fcntl error for fd %d\n", atoi(argv[1]));exit(1);}switch(val & O_ACCMODE){case O_RDONLY:printf("read only");break;case O_WRONLY:printf("write only");break;case O_RDWR:printf("read write");break;default:printf("invalid access mode\n");exit(1);}if (val & O_APPEND)printf(", append");if (val & O_NONBLOCK)printf(", nonblocking");printf("\n");return 0; } void set_fl(int fd, int flags) /* flags are file status flags to turn on */ {int val;if ( (val = fcntl(fd, F_GETFL, 0)) < 0){printf("fcntl F_GETFL error");exit(1);}val |= flags; /* turn on flags *///重新设置文件状态标志(val为新文件的文件状态标志)if (fcntl(fd, F_SETFL, val) < 0){printf("fcntl F_SETFL error");exit(1);} }void clr_fl(int fd, int flags) {int val;if ((val = fcntl(fd, F_GETFL, 0)) == -1){syslog(LOG_ERR, __FILE__, __LINE__,"fcntl() error : %s", strerror(errno));exit(1);}val &= ~flags; /* turn flags off */if (fcntl(fd, F_SETFL, val) == -1){syslog(LOG_ERR, __FILE__, __LINE__,"fcntl() error : %s", strerror(errno));exit(1);}return; }

总结

以上是生活随笔为你收集整理的fcntl函数-文件控制函数的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。