一、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错误。之后输入一个字符解锁之后,其他进程才能访问该文件。