国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 操作系統 > 正文

文件I/O之fcntl函數

2024-06-28 13:28:51
字體:
來源:轉載
供稿:網友
文件I/O之fcntl函數

fcntl函數可以改變已打開的文件的性質。

#include <fcntl.h>int fcntl( int filedes, int cmd, ... /* int arg */ );返回值:若成功則依賴于cmd,若出錯則返回-1

在本節的各實例中,第三個參數總是一個整數,與上面所示函數原型中的注釋部分相對應。但是在說明記錄鎖時,第三個參數則是指向一個結構的指針。

fcntl函數有5種功能:

(1)復制一個現有的描述符(cmd = F_DUPFD )。

(2)獲得/設置文件描述符標記(cmd = F_GETFD或F_SETFD)。

(3)獲得/設置文件狀態標志(cmd = F_GETFL或F_SETFL)。

(4)獲得/設置異步I/O所有權(cmd = F_GETOWN或F_SETOWN)。

(5)獲得/設置記錄鎖(cmd = F_GETLK、F_SETLK或F_SETLKW)。

我們先說明這10種cmd值得前7種(后3種,在談記錄鎖時說明)。我們將涉及與進程表項中各文件描述符相關聯的文件描述符標志,以及每個文件表項中的文件狀態標志。

F_DUPFD 復制文件描述符filedes。新文件描述符作為函數值返回。它是尚未打開的各描述符中大于或等于第三個參數值(取為整型值)中各值的最小值。新描述符與filedes共享同一文件表項。但是,新描述符有它自己的一套文件描述符標志,其FD_CLOEXEC文件描述符標志被清除(這表示該描述符在通過一個exec時仍保持有效)。

F_GETFD 對應于filedes的文件描述符標志作為函數值返回。當前只定義了一個文件描述符標志FD_CLOEXEC。

F_SETFD 對于filedes設置文件描述符標志。新標志值按第三個參數(取為整型值)設置。

注:應當了解很多現有的涉及文件描述符標志的程序并不使用常量FD_CLOEXEC,而是將此標志設置為0(系統默認,在exec時不關閉)或1(在exec時關閉)。

F_GETFL 對應于filedes的文件狀態標志作為函數值返回。文件狀態標志如下表3-3:(表3-3中的各個標志,除了三個訪問方式標志(O_RDONLY、O_WRONLY以及O_RDWR)不各占一位,其他標志分別占文件狀態標志的一個bit位)

index

不幸的是,三個訪問方式標志(O_RDONLY、O_WRONLY以及O_RDWR)并不各占1位(由于歷史原因,這三種標志的值分別是0、1和2。這三個訪問方式標志用文件狀態標志的后兩位表示,00:O_RDONLY,01:O_WRONLY,10:O_RDWR。這三種值互斥——一個文件只能有這三種值之一)。因此首先必須用屏蔽字O_ACCMODE(0x0003)取得訪問模式位(文件狀態標志的后兩位),然后將結果與這三種值的任一種做比較。

F_SETFL 將文件狀態標志設置為第三個參數的值(取為整型值)。可以更改的幾個標志是:O_APPEND、O_NONBLOCK、O_SYNC、O_DSYNC、O_RSYNC、O_FSYNC和O_ASYNC。

F_GETOWN 取當前接受SIGIO和SIGURG信號的進程ID或進程組ID。

F_SETOWN 設置接收SIGIO和SIGURG信號的進程ID或進程組ID。正當arg指定一個進程ID,負的arg表示等于arg絕對值的一個進程組ID。

fcntl的返回值與命令有關。如果出錯,所有命令都返回-1,如果成功則返回某個其他值。下列四個命令有特定的返回值:F_DUPFD、F_GETFD、F_GETFL以及F_GETOWN。第一個返回新的文件描述符,接下來兩個返回相應標志,最后一個返回一個正當進程ID或負的進程組ID。

程序清單3-4 對于指定的描述符打印文件標志

[root@localhost apue]# cat PRog3-4.c#include "apue.h"#include <fcntl.h>int main(int argc, char *argv[]){        int val;        if(argc != 2)                err_quit("usage: prog3-4 <descriptor#>");        if((val = fcntl(atoi(argv[1]), F_GETFL, 0)) < 0)                err_sys("fcntl error for fd %d", atoi(argv[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:                        err_dump("unknown access mode");        }        if(val & O_APPEND)                printf(", append");        if(val & O_NONBLOCK)                printf(", nonblocking");#if defined(O_SYNC)        if(val & O_SYNC)                printf(", synchronous writes");#endif#if !defined(_POSIX_C_SOURCE) && defined(O_FSYNC)        if(val & O_FSYNC)                printf(", synchronous writes");#endif        putchar('/n');        exit(0);}

注意,我們使用了功能測試宏_POSIX_C_SOURCE,并且條件編譯了POSIX.1中沒有定義的文件訪問標志。

在修改文件描述符標志或文件狀態標志時必須謹慎,先要取得現有的標志值,然后根據需要修改它,最后設置新標志值。不能只是執行F_SETFD或F_SETFL命令,這樣會關閉以前設置的標志位。

程序清單3-5 對一個文件描述符打開一個或多個文件狀態標志

[root@localhost apue]# cat prog3-5.c#include "apue.h"#include <fcntl.h>void set_fl(int fd, int flags) /* flags are file status flags to turn to */{        int val;        if((val = fcntl(fd, F_GETFL, 0)) < 0)                err_sys("fcntl F_GETFL error");        val |= flags;   /* turn on flags */        if(fcntl(fd, F_SETFL, val) < 0)                err_sys("fcntl F_SETFL error");}

如果將中間的一條語句改為:

val &= ~flags;    /* turn flags off */

就構成另一個函數,我們稱其為clr_fl。

比較fsync和fdatasync與O_SYNC標志,fsync和fdatasync在我們需要時更新文件內容,O_SYNC標志則在我們每次寫至文件時更新文件內容。

fcntl的必要性:我們的程序在一個描述符(標準輸出)上進行操作,但是根本不知道由shell打開的相應的文件名。因為這是shell打開的,于是不能在打開時,按我們的要求設置O_SYNC標志。fcntl則允許僅知道打開文件描述符時可以修改其性質。

本篇博文內容摘自《UNIX環境高級編程》(第二版),僅作個人學習記錄所用。關于本書可參考:http://www.apuebook.com/


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 清徐县| 靖边县| 海宁市| 格尔木市| 商丘市| 顺义区| 乌兰浩特市| 福清市| 同仁县| 湘潭市| 商洛市| 绥化市| 泗洪县| 新蔡县| 修武县| 平邑县| 浦城县| 长丰县| 柳林县| 富蕴县| 彭州市| 金坛市| 新田县| 交城县| 连江县| 济宁市| 客服| 肥东县| 济阳县| 北碚区| 庆城县| 靖远县| 民乐县| 阳西县| 清镇市| 深圳市| 威海市| 和平县| 南江县| 昭苏县| 丰城市|