Fcntl函数
函数用来对以打开的文件描述符进行各种控制操作以改变已打开文件的各种属性
Int fcntl(int fd, int cmd);
Int fcntl(int fd, int cmd, long arg);
Int fcntl(int fd, int cmd, struct flock*lock);
Cmd:
F_DUPFD:此时,fcntl的功能与dup一样,可以复制由fd指向的文件描述符。调用成功返回新的文件描述符,失败返回-1.
F_GETFD:用来获取文件描述符的close-on-exec标志。调用成功返回标志值,若此标志值的最后一位是0,则该标志没有设置,即意味着在执行exec相关函数后文件描述符仍保持打开。否则在执行exec相关函数时将关闭该文件描述符。失败时返回-1.
F_SETFD:设置文件描述符的close-on-exec标志位第三个参数arg的最后一位。成功返回0,失败返回-1.
F_GETFL:获得文件的打开方式。成功返回标志值,失败返回-1.标志值的含义同open系统调用一致。
F_SETFL:设置文件打开的方式为第三个参数arg指定的方式,但是Linux系统只能设置O_APPEND、O_NONBLOCK、O_ASYNC标志。
文件记录锁功能
Struct flock{
Short_l_type; // 锁的类型,共享锁(F_RDLCK,读锁),互斥锁(F_WDLCK,写锁)
Short_l_whence; // 偏移量起始位置:SEEK_CUR,SEEK_SET,SEEK_END
Short_l_start; // Start offset for lock
Short_l_len; // Number of bytes to lock
Short_l_pid; // 锁的属主进程
}
F_SETLK:设置或者释放锁,当l_type取F_RDLCK或F_WDLCK时,在由l_whence、l_start和l_len指定的区域上设置锁;当l_type取F_UNLCK时则释放锁。如果锁被其他进程占用,则返回-1。
F_SETLKW:与F_SETLK类似,当希望设置的锁因为存在其他锁而被阻止时,该命令会等待相冲突的锁被释放。
F_GETLK:如果锁能被设置,该命令并不真的设置锁,而是只修改lock的l_type为F_UNLCK,然后返回。如果存在一个或多个锁与希望设置的锁互相冲突,则fcntl返回其中的一个锁的flock结构。
Linux系统的文件记录锁默认是建议性的而不是强制性的。
F_GETOWN:返回当前接收SIGIO或SIGURG信号的进程ID或进程组,进程组ID以负值返回。
F_SETOWN:设置进程或者进程组接收SIGIO和SIGURG信号,进程组ID以负值指定,进程ID用正值指定。
F_GETSIG:可以再输入输出时,获得发送的信号。
F_SETSIG:设置在输入输出时发送的信号
代码:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(int argc, char **argv)
{
int ret;
int access_mode;
int fd;
if ((fd = open("example",O_CREAT | O_TRUNC| O_RDWR, S_IRWXU))== -1)
{
printf("Errno:open line = %d\n", __LINE__);
}
// 设置文件打开方式
if ((ret = fcntl(fd, F_SETFL, O_APPEND)) < 0)
{
printf("Errno:fcntl line = %d\n", __LINE__);
}
// 获取文件打开方式
if ((ret = fcntl(fd, F_GETFL,0)) < 0)
{
printf("Errno:fcntl line = %d\n", __LINE__);
}
access_mode= ret & O_ACCMODE;
if (access_mode == O_RDONLY)
{
printf("exampleaccedd mode: read only");
} else if (access_mode ==O_WRONLY)
{
printf("exampleaccedd mode: write only");
}
else if(access_mode == O_RDWR)
{
printf("exampleaccedd mode: write + read");
}
if (ret & O_APPEND)
{
printf(", append");
}
if (ret & O_NONBLOCK)
{
printf(", nonblock");
}
if (ret & O_SYNC)
{
printf(", sync");
}
printf("\n");
return 0;
}
程序中的O_ACCMODE是取得文件打开方式的掩码,实际上它的值就是3,做与运算只是为了取得ret的最后两位的值。