fcntl函数-文件控制函数
生活随笔
收集整理的這篇文章主要介紹了
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位。(正 如前述,這三種標志的值各是 0、1和2,由于歷史原因。這三種值互斥 — 一個文件只能有這 三種值之一。 )因此首先必須用屏蔽字 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函数-文件控制函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【2016年第6期】基于大数据的移动互联
- 下一篇: 客座编辑:杜小勇(1963‒),中国人民