Chinaunix首页 | 论坛 | 博客
  • 博客访问: 612999
  • 博文数量: 144
  • 博客积分: 5037
  • 博客等级: 大校
  • 技术积分: 1581
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-30 21:49
文章存档

2010年(16)

2009年(128)

分类: LINUX

2009-07-27 18:00:52

 

3.13 fcntl函数
f c n t l函数可以改变已经打开文件的性质。
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
int fcntl(intf i l e d e s, int c m d,.../* inta rg * / ) ;
返回:若成功则依赖于c m d(见下),若出错为- 1
在本节的各实例中,第三个参数总是一个整数,与上面所示函数原型中的注释部分相对应。但
是1 2 . 3节说明记录锁时,第三个参数则是指向一个结构的指针。
f c n t l函数有五种功能:
• 复制一个现存的描述符(c m d=F D U P F D)。
• 获得/设置文件描述符标记(c m d = F G E T F D或F S E T F D)。
• 获得/设置文件状态标志(c m d = F G E T F L或F S E T F L)。
• 获得/设置异步I / O有权(c m d = F G E TO W N或F S E TO W N)。
• 获得/设置记录锁(c m d = F G E T L K , F S E T L K或F S E T L K W)。
我们先说明这十种命令值中的前七种( 1 2 . 3节说明后三种,它们都与记录锁有关)我们将涉
及与进程表项中各文件描述符相关联的文件描述符标志,以及每个文件表项中的文件状态标志,
见图3 - 1。
• F_DUPFD 复制文件描述符f i l e d e s,新文件描述符作为函数值返回。它是尚未打开的各
描述符中大于或等于第三个参数值(取为整型值)中各值的最小值。新描述符与filedes 共享同
一文件表项(见图3 - 3)。但是,新描述符有它自己的一套文件描述符标志,其F D C L O E X E C
文件描述符标志则被清除(这表示该描述符在exec 时仍保持开放,我们将在第8章对此进行
讨论)。
第3章文件I/O 4 7
下载
• F_GETFD 对应于filedes 的文件描述符标志作为函数值返回。当前只定义了一个文件描
述符标志F D C L O E X E C。
• F_SETFD 对于filedes 设置文件描述符标志。新标志值按第三个参数(取为整型值)设置。
应当了解很多现存的涉及文件描述符标志的程序并不使用常数F D C L O E X E C,而是将此
标志设置为0 (系统默认,在e x e c时不关闭)或1 (在e x e c时关闭)。
• F_GETFL 对应于filedes 的文件状态标志作为函数值返回。在说明o p e n函数时,已说明
了文件状态标志。它们列于表3 - 2中。
表3-2 对于f c n t l的文件状态标志
文件状态标志说明
O R D O N L Y 只读打开
O W R O N L Y 只写打开
O R D W R 读/写打开
O A P P E N D 写时都添加至文件尾
O N O N B L O C K 非阻塞方式
O S Y N C 等待写完成
O A S Y N C 异步I / O(仅4 . 3 + B S D)
不幸的是,三个存取方式标志( O R D O N LY, O W R O N LY,以及O R D W R )并不各占1位。(正
如前述,这三种标志的值各是0、1和2,由于历史原因。这三种值互斥—一个文件只能有这
三种值之一。)因此首先必须用屏蔽字O A C C M O D E取得存取方式位,然后将结果与这三种值
相比较。
• F_SETFL 将文件状态标志设置为第三个参数的值(取为整型值)。可以更改的几个标志是:
O A P P E N D,O N O N B L O C K,O S Y N C和O A S Y N C。
• F_GETOWN 取当前接收S I G I O和S I G U R G信号的进程I D或进程组I D。1 2 . 6 . 2节将论述这
两种4 . 3 + B S D异步I / O信号。
• F_SETOWN 设置接收S I G I O和S I G U R G信号的进程I D或进程组I D。正的a rg指定一个进
程I D,负的a rg表示等于a rg绝对值的一个进程组I D。
f c n t l的返回值与命令有关。如果出错,所有命令都返回- 1,如果成功则返回某个其他值。
下列三个命令有特定返回值:F_DUPFD,F_GETFD, F_GETFL以及F G E TO W N。第一个返回新
的文件描述符,第二个返回相应标志,最后一个返回一个正的进程I D或负的进程组I D。
实例
程序3 - 4取指定一个文件描述符的命令行参数,并对于该描述符打印其文件标志说明。
程序3-4 对于指定的描述符打印文件标志
4 8 U N I X环境高级编程
下载
注意,我们使用了功能测试宏_ P O S I X S O U R C E,并且条件编译了P O S I X . 1中没有定义的
文件存取标志。下面显示了从K o r n S h e l l调用该程序时的几种情况:
$ a.out 0 < /dev/tty
read only
$ a.out 1 > temp.foo
$ cat temp.foo
write only
$ a.out 2 2>>temp.foo
write only, append
$ a.out 5 5<>temp.foo
read write
K o r n S h e l l子句5 < > t e m p . f o o表示在文件描述符5上打开文件t e m p . f o o以供读、写。
实例
在修改文件描述符标志或文件状态标志时必须谨慎,先要取得现在的标志值,然后按照希
望修改它,最后设置新标志值。不能只是执行F S E T F D或F S E T F L命令,这样会关闭以前设
置的标志位。
程序3 - 5是一个对于一个文件描述符设置一个或多个文件状态标志的函数。
程序3-5 对一个文件描述符打开一个或多个文件状态标志
第3章文件I/O 4 9
下载
如果将中间的一条语句改为:
val &= ˜flags; /*turn flags off*/

就构成了另一个函数,我们称其为c l r f l,并将在后面某个例子中用到它。此语句使当前文件
状态标志值v a l与f l a g s的反码逻辑与运算。
如果在程序3 - 3的开始处,加上下面一行以调用s e t f l,则打开了同步写标志。
set_fl(STDOUT_FILENO, O_SYNC);
这就造成每次w r i t e都要等待,直至数据已写到磁盘上再返回。在U N I X中,通常w r i t e只是
将数据排入队列,而实际的I / O操作则可能在以后的某个时刻进行。数据库系统很可能需要使用
O S Y N C,这样一来,在系统崩溃情况下,它从w r i t e返回时就知道数据已确实写到了磁盘上。
程序运行时,设置O S Y N C标志会增加时钟时间。为了测试这一点,运行程序3 - 3,它从
磁盘上的一个文件中将1 . 5 M字节复制到另一个文件中。然后,在此程序中设置O S Y N C标志,
使其完成上述同样的工作,将两者的结果进行比较,见表3 - 3。
表3-3 用同步写( O S Y N C )的时间结果
操作用户C P U(秒) 系统C P U(秒) 时钟时间(秒)
取自表3-1 BUFFSIZE=8192的读时间0 . 0 0 . 3 0 . 3
盘文件的正常w r i t e 0 . 0 1 . 0 2 . 3
O S Y N C设置的盘文件w r i t e 0 . 0 1 . 4 1 3 . 4
表3 - 3中的3行都是在B U F F S I Z E为8 1 9 2的情况下测量得到的。表3 - 1中的结果所测量的情况
是读一个磁盘文件,然后写到/ d e v / n u l l,所以没有磁盘输出。表3 - 3中的第2行对应于读一个磁
盘文件,然后写到另一个磁盘文件中。这就是为什么表3 - 3中第1,2行有差别的原因。在写磁
盘文件时,系统时间增加了,其原因是内核需要从进程中复制数据,并将数据排入队列以便由
磁盘驱

阅读(1102) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~