3.3Apue檔案IO——fcntl函式及其使用示例
阿新 • • 發佈:2018-12-21
為什麼要使用fcntl函式
假設我們已經打開了一個檔案,那麼
當我想修改已開啟檔案的屬性
時,就可以利用fcntl函式直接改變已開啟檔案的屬性
,而不用關閉然後重新開啟來設定
。
fcntl函式
原型:
當第二個引數取不同的值時,fcntl有不同的功能:
cmd=F_DUPFD或F_DUPFD_CLOEXEC
:複製
一個已有的描述符,返回新的
檔案描述符
cmd=F_GETFD或F_SETFD
:獲取/設定檔案描述符
標誌
cmd=F_GETFL或F_SETFL
:獲取檔案狀態
標誌(如O_RDONLY、O_WRONLY、O_RDWR等,這三個值互斥
,一個檔案的訪問方式只能取這幾個值之一
,因此需要用遮蔽字O_ACCMODE取得訪問方式位
,然後與這幾個值比較)。設定檔案狀態時將檔案狀態標誌設定為第三個引數的值(可更改的幾個標誌
:O_APPEND
、O_NONBLOCK
等)
cmd=F_GETOWN或F_SETOWN
:獲取/設定非同步IO所有權
:即獲取當前接收SIGIO和SIGURG訊號的程序ID或程序組ID。設定接收SIGIO和SIGURG訊號的程序ID或程序組ID
cmd=F_GETLCK或F_SETLK或F_SETLKW
:獲取/設定記錄鎖
fcntl使用示例
示例1:獲取檔案hello的狀態標誌
/// for read()
#include <unistd.h>
/// for open()
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
/// for exit()
#include <stdlib.h>
#define BUFFERSIZE 1024
int main(int argc, char *argv[]) {
int ret;
int fd = atoi(argv[1]);
if ((ret = fcntl(fd, F_GETFL)) < 0) {
perror("fcntl() error!" );
exit(1);
}
switch (ret & O_ACCMODE) {
case O_RDONLY:
puts("O_RDONLY");break;
case O_WRONLY:
puts("O_WRONLY");break;
case O_RDWR:
puts("O_RDWR");break;
default:
break;
}
if(ret & O_APPEND)
puts("O_APPEND");
if(ret & O_NONBLOCK)
puts("O_NONBLOCK");
if(ret & O_TRUNC)
puts("O_TRUNC");
return 0;
}
示例2:修改狀態標誌的正確方式
首先要獲得現在的標誌值,然後按照期望修改它,最後才是設定新的標誌值
。
如果只是執行F_SETFD或F_SETFL,這樣會關閉以前的標誌位
示例中的ret |= flags
用於設定flags標誌
如果是ret &= ~flags
則用於取消flags標誌
void set_fl(int fd, int flgs) {
int ret;
if ((ret = fcntl(fd, F_GETFL)) < 0)
perror("fcntl() error!");
ret |= flags; /// turn on flags
if (fcntl(fd, F_SETFL, ret) < 0)
perror("fcntl() error!");
}