Linux stat获取文件类型
程序员文章站
2022-05-24 15:29:25
...
一、函数声明
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *pathname, struct stat *statbuf);
int fstat(int fd, struct stat *statbuf);
int lstat(const char *pathname, struct stat *statbuf);
#include <fcntl.h> /* Definition of AT_* constants */
#include <sys/stat.h>
int fstatat(int dirfd, const char *pathname, struct stat *statbuf,
int flags);
二、实例
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
void sys_err(const char *msg) {
perror(msg);
exit(-1);
}
int main(int argc, const char **args)
{
const char *path = args[1];
struct stat st = {0};
int fd;
if (argc < 2) {
exit(-1);
}
fd = open(path, __O_PATH|__O_NOFOLLOW);
if (fd < 0) {
sys_err("open with fail");
}
if (fstat(fd, &st) < 0) {
sys_err("fstat with fail");
}
switch (st.st_mode & S_IFMT)
{
case __S_IFDIR:
printf("directory\n");
break;
case __S_IFCHR:
printf("charactor dev file\n");
break;
case __S_IFBLK:
printf("block dev file\n");
break;
case __S_IFREG:
printf("regular file\n");
break;
case __S_IFIFO:
printf("fifo file\n");
break;
case __S_IFLNK:
printf("sysmbol link file\n");
break;
case __S_IFSOCK:
printf("socket file\n");
break;
default:
break;
}
close(fd);
return 0;
}
我之所以用open然后stat,而不是直接使用lstat。是因为,lstat实际上是有要求的。
open(path, __O_PATH|__O_NOFOLLOW);这样设置是基于,为了获取到了文件描述符是symbol link文件的。而不是其关联的文件的。
If pathname is a symbolic link and the O_NOFOLLOW flag is also specified,
then the call returns a file descriptor referring to the symbolic link
引用自:Ubuntu20.4man 2 open
中对O_PATH的解释。
三、补充
Unix高级环境编程一书中提到。POSIX标准中,还有额外的几种文件类型。
但是我在Ubuntu20.4上查看,/usr/include/x86_64-linux-gnu/bits/stat 文件中所定义的这三个宏会发现。
/* POSIX.1b objects. Note that these macros always evaluate to zero. But
they do it by enforcing the correct use of the macros. */
#define __S_TYPEISMQ(buf) ((buf)->st_mode - (buf)->st_mode)
#define __S_TYPEISSEM(buf) ((buf)->st_mode - (buf)->st_mode)
#define __S_TYPEISSHM(buf) ((buf)->st_mode - (buf)->st_mode)
这些值一直都是0。也就是虽然POSIX标准这么定义,但是现在的ubuntu 20.4这个发行版,并未采用实现该标准。
下一篇: log4j容器初始化探究