七、Linux系统编程-文件和IO(五)fcntl函数及常用操作、文件锁

一、fcntl函数及常用操作

(1)、函数声明

#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd, ... /* arg */ );

(2)、功能:操纵文件描述符,改变已打开的文件的属性

  • 复制文件描述符 F_DUPFD(long)
  • 文件描述符标志 F_GETFD(void) F_SETFD(long)
  • 文件状态标志 F_GETFL(void) F_SETFL(long)
  • 文件锁 F_GETLK, F_SETLK,F_SETLKW
示例:
1、复制文件描述符
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>

#define ERR_EXIT(m) \
        do \
        { \
                perror(m); \
                exit(EXIT_FAILURE); \
        }while(0)

int main()
{
        int fd;
        char buf[1024];
        fd = open("aa.txt",O_WRONLY);
        if (fd == -1)
                ERR_EXIT("open error");
        close(1);
        fcntl(fd,F_DUPFD,0);
        dup(fd);
        printf("AAAGG\n");
        return 0;
}
2、设置清除文件状态标志
</pre><pre name="code" class="cpp">#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>

#define ERR_EXIT(m) \
        do \
        { \
                perror(m); \
                exit(EXIT_FAILURE); \
        }while(0)
void set_flag(int fd,int flag);
void cls_flag(int fd,int flag);
int main()
{
        char buf[512];
        read(0,buf,5);
        printf("%s\n",buf);
        set_flag(0,O_NONBLOCK);
        cls_flag(0,O_NONBLOCK);
        read(0,buf,5);
        return 0;
}


void set_flag(int fd, int flag)
{
        int val;
        val = fcntl(fd,F_GETFL,0);
        if (val == -1)
                ERR_EXIT("fcntl get flag error");
        val |= flag;
        if (fcntl(fd,F_SETFL,val) < 0)
                ERR_EXIT("fcntl set flag error");
}

void cls_flag(int fd,int flag)
{
        int val;
        val = fcntl(fd,F_GETFL,0);
        if (val == -1)
                ERR_EXIT("fcntl get flag error");
        val &= ~flag;
        if (fcntl(fd,F_SETFL,val) < 0)
                ERR_EXIT("fcntl set flag error");
}
3、设置清除文件文件锁
文件锁结构:
struct flock {
               ...
               short l_type;    /* Type of lock: F_RDLCK,
                                   F_WRLCK, F_UNLCK */
               short l_whence;  /* How to interpret l_start:
                                   SEEK_SET, SEEK_CUR, SEEK_END */
               off_t l_start;   /* Starting offset for lock */
               off_t l_len;     /* Number of bytes to lock */
               pid_t l_pid;     /* PID of process blocking our lock
                                   (F_GETLK only) */
               ...
};
设置和清除锁示例:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>

#define ERR_EXIT(m) \
        do \
        { \
                perror(m); \
                exit(EXIT_FAILURE); \
        } while(0)

int main(int argc,char* argv[])
{
        int fd;
        if ((fd = open("aa.txt",O_CREAT | O_RDWR | O_TRUNC,0644)) == -1)
                ERR_EXIT("open error");
        struct flock lock;
        memset(&lock,0,sizeof(lock));
        lock.l_type = F_WRLCK;
        lock.l_whence = SEEK_SET;
        lock.l_start = 0;
        lock.l_len = 0;
        if (0 != (fcntl(fd,F_SETLK,&lock)) ) //如果设置F_SETLKW,则会阻塞直到获得锁
                ERR_EXIT("lock error");
        getchar();
        lock.l_type = F_UNLCK;
        if (0 != fcntl(fd,F_SETLK,&lock))
                ERR_EXIT("unlock error");
        write(fd,"AAA",3);
        return 0;
}
设置一个排他锁之后再次执行这个程序就会出现lock error: Resource temporarily unavailable错误。之后输入一个字符解锁之后,其他进程才能访问该文件。
  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值