stat() 提供错误信息
stat() giving wrong information
我正在使用循环打印目录中每个文件的信息,以将 ls shell 函数重新创建为 C 程序。当将来自程序的信息与来自 ls 命令的正确信息进行比较时,来自程序(使用 stat())的结果是非常错误的。
这是我的程序的所有代码:
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char* params[])
{
void printTable(char filepath[], int s, int b);
// If no modifiers, send error
if(argc == 1) {
printf("Error: no directory specified. \n");
exit(1);
return 0;
}
// If only a directory is provided
if(argc ==2) {
printTable(params[1], 0, 0);
} // end of argc == 2
// If there are 4 modifiers
else if(argc == 4) {
}
return 0;
}
void printTable (char filepath[], int s, int b) {
DIR *dp;
struct dirent *dir;
struct stat fileStats;
if((dp = opendir(filepath)) == NULL) {
fprintf(stderr, "Cannot open directory. \n");
exit(1);
}
printf("Processing files in the directory: %s\n", filepath);
printf("inode \t Type \t UID \t GID \t SIZE \t Filename \t Modification date \n");
while((dir = readdir(dp)) != NULL ) {
if(dir->d_ino != 0 && fileStats.st_ino > 0 && stat(dir->d_name, &fileStats) < 0) {
// Print the inode
printf("%d \t ", fileStats.st_ino);
// Print type
if(dir->d_type == DT_BLK)
printf("BLK \t ");
else if(dir->d_type == DT_CHR)
printf("CHR \t ");
else if(dir->d_type == DT_DIR)
printf("DIR \t ");
else if(dir->d_type == DT_FIFO)
printf("FIFO \t ");
else if(dir->d_type == DT_LNK)
printf("LNK \t ");
else if(dir->d_type == DT_SOCK)
printf("SOCK \t ");
else if(dir->d_type == DT_REG)
printf("REG \t ");
else
printf("UNKOWN \t ");
// Print UID
printf("%d \t ", fileStats.st_uid);
// Print GID
printf("%d \t ", fileStats.st_gid);
// Print SIZE
printf("%jd bytes \t ", fileStats.st_size);
// Print file name
printf("%25s \t ", dir->d_name);
// Print date modified
printf("%20s \n", ctime(&fileStats.st_mtime));
}
}
struct tm *lt = localtime(&fileStats.st_mtime);
int diff = difftime(time(NULL), mktime(lt));
printf("%d \n", diff);
closedir(dp);
}
下面是shell命令的结果(该目录与本程序无关):
shell output
这是 运行 程序的结果:
stat(2)
returns 0
成功,但您正在测试是否 stat(dir->d_name, &fileStats) < 0
。因此,只要 stat(2)
未能 实际统计文件,您的代码就会打印一些内容。此外,条件链接的方式,fileStats.st_ino > 0
是一个在第一次迭代中涉及未初始化变量的表达式。
stat(2)
失败的最可能原因是您没有列出当前目录。 dirent
结构中的d_name
成员是目录中的文件名,不是完整路径,而是相对于目录路径的路径。当您将它传递给 stat(2)
时,只有当文件位于进程的当前工作目录 (cwd) 中时,它才会起作用。如果不是,就像您的情况一样,stat(2)
调用将失败。您需要做的是通过将 filepath
和 dir->d_name
与路径分隔符 /
连接起来来构建完整路径:
char fullpath[PATH_MAX];
sprintf(fullpath, "%s/%s", filepath, dir->d_name);
stat(fullpath, &fileStats);
或者,也可以使用 chdir(2)
在循环之前更改工作目录:
char olddir[PATH_MAX];
// Save current working directory
getcwd(olddir, PATH_MAX);
// Change working directory to `filepath`
chdir(filepath);
// Do your loop here
// Restore old working directory
chdir(olddir);
现在 stat(2)
可以正确使用相对路径,即仅文件名。
stat(dir->d_name, &fileStats) < 0
应该是
stat(dir->d_name, &fileStats) == 0
只有在出现错误时才打印内容。
stat
returns:
On success, zero is returned. On error, -1 is returned, and errno is
set appropriately.
如果你的平台对POSIX 2008有足够的支持,你可以使用fstatat()
and dirfd()
功能,效果不错。这至少适用于当前版本的 BSD、macOS、Linux、AIX、HP-UX、Solaris。
此代码与问题中的代码类似,但它不会尝试复制解码文件类型等的方式。
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
int main(int argc, char **argv)
{
for (int i = 1; i < argc; i++)
{
const char *dir = argv[i];
DIR *dp = opendir(dir);
if (dp == 0)
{
fprintf(stderr, "%s: failed to open directory %s: %d %s\n",
argv[0], dir, errno, strerror(errno));
continue;
}
/* dirfd(): POSIX 2008 - OK on BSD, macOS, Linux, AIX, HP-UX, Solaris */
int fd = dirfd(dp);
struct dirent *file;
while ((file = readdir(dp)) != 0)
{
struct stat sb;
/* 0 argument could be AT_SYMLINK_NOFOLLOW */
if (fstatat(fd, file->d_name, &sb, 0) == 0)
{
/* Some of the conversion specifiers may be incorrect for some systems */
/* Inode number, size, time in particular */
printf("%10llu %5d %5d %7o %3d %9lld %10ld %10ld %10ld %s/%s\n",
sb.st_ino, sb.st_uid, sb.st_gid, sb.st_mode, sb.st_nlink, sb.st_size,
sb.st_mtime, sb.st_atime, sb.st_ctime, dir, file->d_name);
}
else
fprintf(stderr, "%s: failed to stat() %s/%s: %d %s\n",
argv[0], dir, file->d_name, errno, strerror(errno));
}
closedir(dp);
}
return 0;
}
请注意,这根本不需要(因此不需要)使用 chdir()
。使用 fstatat()
允许您指定 "interpret the file name relative to the given directory",其中目录由文件描述符标识。
如果有合适的错误报告包(这样程序的名称将自动包含在错误中),我会将循环体打包为一个函数。但是,错误消息中的 argv[0]
引用会带来不便。对于错误报告,我会使用 SOQ (Stack Overflow Questions) repository on GitHub as files stderr.c
and stderr.h
in the src/libsoq 子目录中可用的代码。
示例输出(来自 Mac — 10 位 inode 编号比大多数系统上的要大):
$ at67 bin ~/src/ule
4296808809 501 20 40755 33 1056 1577029162 1583165629 1577029162 bin/.
4296808746 501 20 40755 208 6656 1583164216 1583165629 1583164216 bin/..
4296811200 501 20 100755 1 1266 1515986057 1582224384 1582216636 bin/rfn
4296811205 501 20 100755 1 1266 1515986057 1583164235 1582216636 bin/rfn-c
4305347192 501 20 100755 1 246 1524096284 1582224384 1582216636 bin/soqvg
4297537255 501 20 100755 1 3813 1579639563 1582830967 1582216636 bin/pipe-rot
4296811199 501 20 100755 1 233 1515695843 1582224384 1582216636 bin/sow
4298720660 501 20 100755 1 627 1517875149 1582224384 1582216636 bin/so-getchar
4296811201 501 20 100755 1 218 1515695843 1582224384 1582216636 bin/ddpr
4296811210 501 20 100755 1 1266 1515986057 1582224384 1582216636 bin/rfn-pl
4296808811 501 20 100644 1 490 1510874880 1578595253 1510874880 bin/README.md
4296811204 501 20 100755 1 2278 1515695843 1582224384 1582216636 bin/fixin
4296811203 501 20 100755 1 2835 1576997332 1582224384 1582216636 bin/so-books
4296811196 501 20 100755 1 617 1515695843 1582224388 1582216636 bin/wso
4296811197 501 20 100755 1 85 1515695843 1583165629 1582216636 bin/so
4296808810 501 20 100644 1 92 1510874880 1579561480 1510874880 bin/.gitignore
4296811193 501 20 100755 1 200 1515695843 1582224388 1582216636 bin/posixcmd
4296811206 501 20 100755 1 1266 1515986057 1582224384 1582216636 bin/rfn-h
4451766334 501 20 100755 1 507 1576997332 1582224384 1582216636 bin/so-esql
4297012073 501 20 100755 1 937 1582216633 1583164235 1582216636 bin/sscce
4296811202 501 20 100755 1 522 1515695843 1582224384 1582216636 bin/so-late
4296811209 501 20 100755 1 1266 1515986057 1582224384 1582216636 bin/rfn-sql
4297507309 501 20 100755 1 848 1526264352 1582224384 1582216636 bin/so-stderr
4296811194 501 20 100755 1 206 1515695843 1582224388 1582216636 bin/posixfun
4342190418 501 20 100755 1 1227 1541833786 1582224384 1582216636 bin/so-quotes
4298078558 501 20 100755 1 722 1515695843 1582224384 1582216636 bin/soa
4296811198 501 20 100755 1 92 1515695843 1582224384 1582216636 bin/sops
4356366344 501 20 100755 1 454 1545845134 1582644937 1582216636 bin/so-reformat-c
4296811208 501 20 100755 1 1266 1515986057 1582224384 1582216636 bin/rfn-cpp
4298720661 501 20 100755 1 700 1576997332 1582224384 1582216636 bin/so-c-reserved
4296811207 501 20 100755 1 1266 1515986057 1582656633 1582216636 bin/rfn-sh
4296811195 501 20 100755 1 255 1515695843 1582224388 1582216636 bin/posixhdr
4451855327 501 20 100755 1 780 1577029658 1582224384 1582216636 bin/so-dotarrow
4296916142 501 20 40755 15 480 1574117045 1583165629 1574117045 /Users/jonathanleffler/src/ule/.
4296713088 501 20 40755 97 3104 1575746582 1583165539 1575746582 /Users/jonathanleffler/src/ule/..
4296917945 501 20 100444 1 7 1473056744 1578608259 1510993969 /Users/jonathanleffler/src/ule/ule-test-nnl
4296917947 501 20 100644 1 6148 1418098863 1578608259 1510994007 /Users/jonathanleffler/src/ule/.DS_Store
4296917957 501 20 100755 1 44824 1473056806 1578608437 1513032846 /Users/jonathanleffler/src/ule/ule-v1.4
4296917948 501 20 100444 1 15 1473056679 1578608259 1510993969 /Users/jonathanleffler/src/ule/ule-test-nul
4296917949 501 20 100640 1 43 1418023230 1578608259 1510993969 /Users/jonathanleffler/src/ule/ule-test-mix
4296917951 501 20 100644 1 745 1436058130 1578608259 1510993969 /Users/jonathanleffler/src/ule/ule.notes
4296917952 501 20 100640 1 33 1418023230 1578608259 1510993969 /Users/jonathanleffler/src/ule/ule-test-unx
4296917953 501 20 100640 1 33 1418023230 1578608259 1510993969 /Users/jonathanleffler/src/ule/ule-test-dos
4296917954 501 20 40755 11 352 1541802114 1578608839 1541802114 /Users/jonathanleffler/src/ule/RCS
4441180506 501 20 100444 1 6726 1574116649 1578608259 1574117045 /Users/jonathanleffler/src/ule/ule.c
4296917956 501 20 40755 3 96 1437532230 1578611808 1510994007 /Users/jonathanleffler/src/ule/ule.dSYM
4297282884 501 20 100755 1 60160 1513033250 1582552763 1513033250 /Users/jonathanleffler/src/ule/ule
4296917958 501 20 100640 1 30 1425237329 1578608259 1510993969 /Users/jonathanleffler/src/ule/ule-test-mac
$
如果您的系统没有 dirfd()
但有 fstatat()
,您或许可以使用这些函数来打开和关闭目录。 (上面代码的早期修订版使用了此代码的变体——但配置它很快就会变得混乱,dirfd()
使这一切都变得不必要了。)。您可以使用 dir_open(dir)
代替 dirfd(dp)
,并在 closedir(dp)
之前或之后添加 dir_close(fd)
。
#include <fcntl.h>
#include <unistd.h>
int dir_open(const char *name)
{
return open(name, O_RDONLY | O_DIRECTORY);
}
int dir_close(int fd)
{
return close(fd);
}
如果您的系统有 O_SEARCH
,请使用它代替 O_RDONLY
(O_SEARCH
在 macOS Mojave 10.14.6 上不可用,例如,我在其中进行了测试) .如果您的系统没有 O_DIRECTORY
,请忽略该术语。这些只是使配置变得混乱的一些细节。
总的来说,如果你有 fstatat()
,你很可能也会有 dirfd()
。
我正在使用循环打印目录中每个文件的信息,以将 ls shell 函数重新创建为 C 程序。当将来自程序的信息与来自 ls 命令的正确信息进行比较时,来自程序(使用 stat())的结果是非常错误的。
这是我的程序的所有代码:
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char* params[])
{
void printTable(char filepath[], int s, int b);
// If no modifiers, send error
if(argc == 1) {
printf("Error: no directory specified. \n");
exit(1);
return 0;
}
// If only a directory is provided
if(argc ==2) {
printTable(params[1], 0, 0);
} // end of argc == 2
// If there are 4 modifiers
else if(argc == 4) {
}
return 0;
}
void printTable (char filepath[], int s, int b) {
DIR *dp;
struct dirent *dir;
struct stat fileStats;
if((dp = opendir(filepath)) == NULL) {
fprintf(stderr, "Cannot open directory. \n");
exit(1);
}
printf("Processing files in the directory: %s\n", filepath);
printf("inode \t Type \t UID \t GID \t SIZE \t Filename \t Modification date \n");
while((dir = readdir(dp)) != NULL ) {
if(dir->d_ino != 0 && fileStats.st_ino > 0 && stat(dir->d_name, &fileStats) < 0) {
// Print the inode
printf("%d \t ", fileStats.st_ino);
// Print type
if(dir->d_type == DT_BLK)
printf("BLK \t ");
else if(dir->d_type == DT_CHR)
printf("CHR \t ");
else if(dir->d_type == DT_DIR)
printf("DIR \t ");
else if(dir->d_type == DT_FIFO)
printf("FIFO \t ");
else if(dir->d_type == DT_LNK)
printf("LNK \t ");
else if(dir->d_type == DT_SOCK)
printf("SOCK \t ");
else if(dir->d_type == DT_REG)
printf("REG \t ");
else
printf("UNKOWN \t ");
// Print UID
printf("%d \t ", fileStats.st_uid);
// Print GID
printf("%d \t ", fileStats.st_gid);
// Print SIZE
printf("%jd bytes \t ", fileStats.st_size);
// Print file name
printf("%25s \t ", dir->d_name);
// Print date modified
printf("%20s \n", ctime(&fileStats.st_mtime));
}
}
struct tm *lt = localtime(&fileStats.st_mtime);
int diff = difftime(time(NULL), mktime(lt));
printf("%d \n", diff);
closedir(dp);
}
下面是shell命令的结果(该目录与本程序无关): shell output
这是 运行 程序的结果:
stat(2)
returns 0
成功,但您正在测试是否 stat(dir->d_name, &fileStats) < 0
。因此,只要 stat(2)
未能 实际统计文件,您的代码就会打印一些内容。此外,条件链接的方式,fileStats.st_ino > 0
是一个在第一次迭代中涉及未初始化变量的表达式。
stat(2)
失败的最可能原因是您没有列出当前目录。 dirent
结构中的d_name
成员是目录中的文件名,不是完整路径,而是相对于目录路径的路径。当您将它传递给 stat(2)
时,只有当文件位于进程的当前工作目录 (cwd) 中时,它才会起作用。如果不是,就像您的情况一样,stat(2)
调用将失败。您需要做的是通过将 filepath
和 dir->d_name
与路径分隔符 /
连接起来来构建完整路径:
char fullpath[PATH_MAX];
sprintf(fullpath, "%s/%s", filepath, dir->d_name);
stat(fullpath, &fileStats);
或者,也可以使用 chdir(2)
在循环之前更改工作目录:
char olddir[PATH_MAX];
// Save current working directory
getcwd(olddir, PATH_MAX);
// Change working directory to `filepath`
chdir(filepath);
// Do your loop here
// Restore old working directory
chdir(olddir);
现在 stat(2)
可以正确使用相对路径,即仅文件名。
stat(dir->d_name, &fileStats) < 0
应该是
stat(dir->d_name, &fileStats) == 0
只有在出现错误时才打印内容。
stat
returns:
On success, zero is returned. On error, -1 is returned, and errno is set appropriately.
如果你的平台对POSIX 2008有足够的支持,你可以使用fstatat()
and dirfd()
功能,效果不错。这至少适用于当前版本的 BSD、macOS、Linux、AIX、HP-UX、Solaris。
此代码与问题中的代码类似,但它不会尝试复制解码文件类型等的方式。
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
int main(int argc, char **argv)
{
for (int i = 1; i < argc; i++)
{
const char *dir = argv[i];
DIR *dp = opendir(dir);
if (dp == 0)
{
fprintf(stderr, "%s: failed to open directory %s: %d %s\n",
argv[0], dir, errno, strerror(errno));
continue;
}
/* dirfd(): POSIX 2008 - OK on BSD, macOS, Linux, AIX, HP-UX, Solaris */
int fd = dirfd(dp);
struct dirent *file;
while ((file = readdir(dp)) != 0)
{
struct stat sb;
/* 0 argument could be AT_SYMLINK_NOFOLLOW */
if (fstatat(fd, file->d_name, &sb, 0) == 0)
{
/* Some of the conversion specifiers may be incorrect for some systems */
/* Inode number, size, time in particular */
printf("%10llu %5d %5d %7o %3d %9lld %10ld %10ld %10ld %s/%s\n",
sb.st_ino, sb.st_uid, sb.st_gid, sb.st_mode, sb.st_nlink, sb.st_size,
sb.st_mtime, sb.st_atime, sb.st_ctime, dir, file->d_name);
}
else
fprintf(stderr, "%s: failed to stat() %s/%s: %d %s\n",
argv[0], dir, file->d_name, errno, strerror(errno));
}
closedir(dp);
}
return 0;
}
请注意,这根本不需要(因此不需要)使用 chdir()
。使用 fstatat()
允许您指定 "interpret the file name relative to the given directory",其中目录由文件描述符标识。
如果有合适的错误报告包(这样程序的名称将自动包含在错误中),我会将循环体打包为一个函数。但是,错误消息中的 argv[0]
引用会带来不便。对于错误报告,我会使用 SOQ (Stack Overflow Questions) repository on GitHub as files stderr.c
and stderr.h
in the src/libsoq 子目录中可用的代码。
示例输出(来自 Mac — 10 位 inode 编号比大多数系统上的要大):
$ at67 bin ~/src/ule
4296808809 501 20 40755 33 1056 1577029162 1583165629 1577029162 bin/.
4296808746 501 20 40755 208 6656 1583164216 1583165629 1583164216 bin/..
4296811200 501 20 100755 1 1266 1515986057 1582224384 1582216636 bin/rfn
4296811205 501 20 100755 1 1266 1515986057 1583164235 1582216636 bin/rfn-c
4305347192 501 20 100755 1 246 1524096284 1582224384 1582216636 bin/soqvg
4297537255 501 20 100755 1 3813 1579639563 1582830967 1582216636 bin/pipe-rot
4296811199 501 20 100755 1 233 1515695843 1582224384 1582216636 bin/sow
4298720660 501 20 100755 1 627 1517875149 1582224384 1582216636 bin/so-getchar
4296811201 501 20 100755 1 218 1515695843 1582224384 1582216636 bin/ddpr
4296811210 501 20 100755 1 1266 1515986057 1582224384 1582216636 bin/rfn-pl
4296808811 501 20 100644 1 490 1510874880 1578595253 1510874880 bin/README.md
4296811204 501 20 100755 1 2278 1515695843 1582224384 1582216636 bin/fixin
4296811203 501 20 100755 1 2835 1576997332 1582224384 1582216636 bin/so-books
4296811196 501 20 100755 1 617 1515695843 1582224388 1582216636 bin/wso
4296811197 501 20 100755 1 85 1515695843 1583165629 1582216636 bin/so
4296808810 501 20 100644 1 92 1510874880 1579561480 1510874880 bin/.gitignore
4296811193 501 20 100755 1 200 1515695843 1582224388 1582216636 bin/posixcmd
4296811206 501 20 100755 1 1266 1515986057 1582224384 1582216636 bin/rfn-h
4451766334 501 20 100755 1 507 1576997332 1582224384 1582216636 bin/so-esql
4297012073 501 20 100755 1 937 1582216633 1583164235 1582216636 bin/sscce
4296811202 501 20 100755 1 522 1515695843 1582224384 1582216636 bin/so-late
4296811209 501 20 100755 1 1266 1515986057 1582224384 1582216636 bin/rfn-sql
4297507309 501 20 100755 1 848 1526264352 1582224384 1582216636 bin/so-stderr
4296811194 501 20 100755 1 206 1515695843 1582224388 1582216636 bin/posixfun
4342190418 501 20 100755 1 1227 1541833786 1582224384 1582216636 bin/so-quotes
4298078558 501 20 100755 1 722 1515695843 1582224384 1582216636 bin/soa
4296811198 501 20 100755 1 92 1515695843 1582224384 1582216636 bin/sops
4356366344 501 20 100755 1 454 1545845134 1582644937 1582216636 bin/so-reformat-c
4296811208 501 20 100755 1 1266 1515986057 1582224384 1582216636 bin/rfn-cpp
4298720661 501 20 100755 1 700 1576997332 1582224384 1582216636 bin/so-c-reserved
4296811207 501 20 100755 1 1266 1515986057 1582656633 1582216636 bin/rfn-sh
4296811195 501 20 100755 1 255 1515695843 1582224388 1582216636 bin/posixhdr
4451855327 501 20 100755 1 780 1577029658 1582224384 1582216636 bin/so-dotarrow
4296916142 501 20 40755 15 480 1574117045 1583165629 1574117045 /Users/jonathanleffler/src/ule/.
4296713088 501 20 40755 97 3104 1575746582 1583165539 1575746582 /Users/jonathanleffler/src/ule/..
4296917945 501 20 100444 1 7 1473056744 1578608259 1510993969 /Users/jonathanleffler/src/ule/ule-test-nnl
4296917947 501 20 100644 1 6148 1418098863 1578608259 1510994007 /Users/jonathanleffler/src/ule/.DS_Store
4296917957 501 20 100755 1 44824 1473056806 1578608437 1513032846 /Users/jonathanleffler/src/ule/ule-v1.4
4296917948 501 20 100444 1 15 1473056679 1578608259 1510993969 /Users/jonathanleffler/src/ule/ule-test-nul
4296917949 501 20 100640 1 43 1418023230 1578608259 1510993969 /Users/jonathanleffler/src/ule/ule-test-mix
4296917951 501 20 100644 1 745 1436058130 1578608259 1510993969 /Users/jonathanleffler/src/ule/ule.notes
4296917952 501 20 100640 1 33 1418023230 1578608259 1510993969 /Users/jonathanleffler/src/ule/ule-test-unx
4296917953 501 20 100640 1 33 1418023230 1578608259 1510993969 /Users/jonathanleffler/src/ule/ule-test-dos
4296917954 501 20 40755 11 352 1541802114 1578608839 1541802114 /Users/jonathanleffler/src/ule/RCS
4441180506 501 20 100444 1 6726 1574116649 1578608259 1574117045 /Users/jonathanleffler/src/ule/ule.c
4296917956 501 20 40755 3 96 1437532230 1578611808 1510994007 /Users/jonathanleffler/src/ule/ule.dSYM
4297282884 501 20 100755 1 60160 1513033250 1582552763 1513033250 /Users/jonathanleffler/src/ule/ule
4296917958 501 20 100640 1 30 1425237329 1578608259 1510993969 /Users/jonathanleffler/src/ule/ule-test-mac
$
如果您的系统没有 dirfd()
但有 fstatat()
,您或许可以使用这些函数来打开和关闭目录。 (上面代码的早期修订版使用了此代码的变体——但配置它很快就会变得混乱,dirfd()
使这一切都变得不必要了。)。您可以使用 dir_open(dir)
代替 dirfd(dp)
,并在 closedir(dp)
之前或之后添加 dir_close(fd)
。
#include <fcntl.h>
#include <unistd.h>
int dir_open(const char *name)
{
return open(name, O_RDONLY | O_DIRECTORY);
}
int dir_close(int fd)
{
return close(fd);
}
如果您的系统有 O_SEARCH
,请使用它代替 O_RDONLY
(O_SEARCH
在 macOS Mojave 10.14.6 上不可用,例如,我在其中进行了测试) .如果您的系统没有 O_DIRECTORY
,请忽略该术语。这些只是使配置变得混乱的一些细节。
总的来说,如果你有 fstatat()
,你很可能也会有 dirfd()
。