目录
fcntl()函数
函数原型
#include <fcntl.h>
int fcntl(int fd, int cmd, ... /* arg */ );
参数
fd
:需要操作的文件描述符。cmd
:控制命令,用于指定对文件描述符执行的操作。arg
:可选参数,与具体命令相关,可能是一个整数值或指针。返回值
- 成功时,根据
cmd
的不同,返回不同的结果。- 失败时,返回
-1
,并设置errno
。
常用cmd命令
获取或设置文件描述符标志
F_GETFD
:获取文件描述符的标志。F_SETFD
:设置文件描述符的标志。- 文件描述符标志目前只有一个:
FD_CLOEXEC
。 FD_CLOEXEC
:
- 文件描述符标志目前只有一个:
- 如果设置了该标志,则当调用
exec
系列函数执行新程序时,文件描述符会被自动关闭。
int flags = fcntl(fd, F_GETFD);
if (flags == -1) {
perror("fcntl F_GETFD");
}
flags |= FD_CLOEXEC;
if (fcntl(fd, F_SETFD, flags) == -1) {
perror("fcntl F_SETFD");
}
获取或设置文件状态标志
F_GETFL
:获取文件状态标志。F_SETFL
:设置文件状态标志。- 文件状态标志包括:
O_NONBLOCK
:非阻塞模式。O_APPEND
:追加模式(写入的数据会追加到文件末尾)。
- 文件状态标志包括:
- 示例(设置非阻塞模式):
int flags = fcntl(fd, F_GETFL);
if (flags == -1) {
perror("fcntl F_GETFL");
}
flags |= O_NONBLOCK;
if (fcntl(fd, F_SETFL, flags) == -1) {
perror("fcntl F_SETFL");
}
文件锁
F_GETLK
:获取文件锁状态。F_SETLK
:设置文件锁(非阻塞模式)。F_SETLKW
:设置文件锁(阻塞模式)。- 文件锁类型:
F_RDLCK
:共享锁(读锁)。F_WRLCK
:独占锁(写锁)。F_UNLCK
:解锁。
- 文件锁类型:
- 示例(设置写锁):
struct flock fl;
fl.l_type = F_WRLCK; // 写锁
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0; // 锁定整个文件
if (fcntl(fd, F_SETLK, &fl) == -1) {
perror("fcntl F_SETLK");
}
stat函数
功能:stat
是一个用于获取文件状态信息的系统调用函数,它能够返回指定文件的各种元数据,比如文件大小、权限、最后修改时间等。
函数原型
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *pathname, struct stat *buf);
int lstat(const char *pathname, struct stat *buf);
int fstat(int fd, struct stat *buf);
stat
:
- 获取文件的元数据。
- 如果路径是符号链接,则获取目标文件的元数据。
lstat
:
- 类似于
stat
,但如果路径是符号链接,它会返回链接本身的元数据。fstat
:
- 获取通过文件描述符表示的文件的元数据。
struct stat
结构体
文件类型与访问权限
st_mode
包含文件的类型和访问权限,可以用宏或位掩码进行解读。
- 文件类型:
S_ISREG(m) // 普通文件
S_ISDIR(m) // 目录
S_ISCHR(m) // 字符设备
S_ISBLK(m) // 块设备
S_ISFIFO(m) // 管道
S_ISLNK(m) // 符号链接
S_ISSOCK(m) // 套接字
- 文件权限:
- 使用位掩码提取权限位,例如:
st_mode & S_IRUSR
:所有者是否有读取权限。st_mode & S_IWGRP
:组是否有写入权限。
- 使用位掩码提取权限位,例如:
文件大小
st_size
:- 文件的总大小(以字节为单位)。
- 如果是普通文件,它表示文件的长度。
- 如果是目录,通常为 0。
示例
#include <stdio.h>
#include <sys/stat.h>
#include <time.h>
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "Usage: %s <file>\n", argv[0]);
return 1;
}
struct stat file_stat;
if (stat(argv[1], &file_stat) == -1) {
perror("stat");
return 1;
}
printf("File: %s\n", argv[1]);
printf("Size: %ld bytes\n", file_stat.st_size);
printf("Type: ");
if (S_ISREG(file_stat.st_mode)) printf("Regular File\n");
else if (S_ISDIR(file_stat.st_mode)) printf("Directory\n");
else if (S_ISCHR(file_stat.st_mode)) printf("Character Device\n");
else if (S_ISBLK(file_stat.st_mode)) printf("Block Device\n");
else if (S_ISFIFO(file_stat.st_mode)) printf("FIFO (Pipe)\n");
else if (S_ISLNK(file_stat.st_mode)) printf("Symbolic Link\n");
else if (S_ISSOCK(file_stat.st_mode)) printf("Socket\n");
printf("Permissions: %o\n", file_stat.st_mode & 0777);
printf("Last modified: %s", ctime(&file_stat.st_mtime));
return 0;
}
access函数
功能:access
是一个用于检查文件访问权限的函数。它通过文件路径检测当前进程是否对该文件具有某种特定的访问权限,例如可读、可写、可执行或文件是否存在。
#include <unistd.h>
int access(const char *pathname, int mode);
示例:检查文件是否存在
#include <stdio.h>
#include <unistd.h>
int main() {
const char *filename = "example.txt";
if (access(filename, F_OK) == 0) {
printf("File '%s' exists.\n", filename);
} else {
perror("File does not exist");
}
return 0;
}