请注意,POSIX 2008 引入了相关函数(系统调用),所有函数都通过熟悉的函数名称的后缀来fstatat()
区分。at
它还定义dirfd()
了获取与目录流关联的文件描述符。
这些*at()
函数采用一个(或两个在的情况下renameat()
)引用目录的打开文件描述符。这意味着在支持的系统上,另一种编码方式fstatat()
是:
const char *name = argv[i];
DIR *dp = opendir(dirname);
if (dp == NULL)
{
fprintf(stderr, "failed to open directory %s (%d: %s)\n",
name, errno, strerror(errno));
return -1;
}
int dfd = dirfd(dp); /* Very, very unlikely to fail */
struct dirent *dirp;
while ((dirp = readdir(dp)) != NULL)
{
struct stat sb;
if (fstatat(dfd, dirp->d_name, &sb, 0) == -1) {
fprintf(stderr, "fstatat(\"%s/%s\") failed (%d: %s)\n",
name, dirp->d_name, errno, strerror(errno));
}
else
printf("%-20s %s/%s\n", "File name:", name, dirp->d_name);
}
Usingfstatat()
和相关函数允许您使用相对路径名而不使用chdir()
(这是危险的;如果不使用,很难回到您开始的位置fchdir()
),或者连接名称,如主要接受的答案中所示。为了可移植性,无论如何还是建议使用串联——但我能够使用下面的代码在 Mac OS X (10.10.1) 和 Linux (Ubuntu 14.04) 上进行测试。
开发成完整的程序(test-fstatat.c
):
/* SO 0512-5919 */
#define _XOPEN_SOURCE 700 /* POSIX 2008 plus ... */
#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
int main(int argc, char **argv)
{
if (argc < 2)
{
fprintf(stderr, "Usage: %s directory [...]\n", argv[0]);
return -1;
}
for (int i = 1; i < argc; i++)
{
const char *name = argv[i];
DIR *dp = opendir(name);
if (dp == NULL)
{
fprintf(stderr, "failed to open directory %s (%d: %s)\n",
name, errno, strerror(errno));
return -1;
}
int dfd = dirfd(dp); /* Very, very unlikely to fail */
printf("%-20s %s\n", "Directory:", name);
struct dirent *dirp;
while ((dirp = readdir(dp)) != NULL)
{
struct stat sb;
if (fstatat(dfd, dirp->d_name, &sb, 0) == -1) {
fprintf(stderr, "fstatat(\"%s/%s\") failed (%d: %s)\n",
name, dirp->d_name, errno, strerror(errno));
}
else
printf("%-20s %s/%s\n", "File name:", name, dirp->d_name);
}
closedir(dp);
}
return 0;
}
样品运行:
$ test-fstatat ~/bin/JLSS-Dist/RCS ../../../src/sqltools/idsmon
Directory: /Users/jonathanleffler/bin/JLSS-Dist/RCS
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/.
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/..
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/mkbod.sh,v
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/jlssdist.jdc,v
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/old.msd.sh,v
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/chksumtool.pl,v
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/msd2nmd.pl,v
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/mknmd.sh,v
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/publictimestamp.sh,v
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/new.mknmd.sh,v
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/PRODCODE,v
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/prodverstamp.sh,v
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/md5.create.pl,v
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/jdcrelease.sh,v
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/JLSS-Dist.mk,v
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/PRODUCT,v
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/msd.create.sh,v
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/distribution.mk,v
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/nmd.create.sh,v
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/jlss.sh,v
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/VERSION,v
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/cvtjdc.sh,v
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/redonmd.sh,v
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/updmsd.sh,v
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/setnmd.sh,v
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/list2msd.pl,v
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/chkmsdnmd.sh,v
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/vercmp.pl,v
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/MSD.sh,v
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/setjdcversion.sh,v
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/sortnmd.sh,v
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/gennmd.sh,v
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/md5.verify.pl,v
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/setbomversion.sh,v
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/chkbodlst.sh,v
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/updnmd.sh,v
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/domsd.sh,v
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/md5.chksum.pl,v
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/bomrelease.pl,v
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/mkmsd.sh,v
File name: /Users/jonathanleffler/bin/JLSS-Dist/RCS/fixnmd.sh,v
Directory: ../../../src/sqltools/idsmon
File name: ../../../src/sqltools/idsmon/.
File name: ../../../src/sqltools/idsmon/..
File name: ../../../src/sqltools/idsmon/idstest.c
File name: ../../../src/sqltools/idsmon/idslen
File name: ../../../src/sqltools/idsmon/install-sh
File name: ../../../src/sqltools/idsmon/scatterinfo
File name: ../../../src/sqltools/idsmon/ltmain.sh
File name: ../../../src/sqltools/idsmon/idsmon.msd
File name: ../../../src/sqltools/idsmon/idsmon.o
File name: ../../../src/sqltools/idsmon/configure
File name: ../../../src/sqltools/idsmon/genscatter
File name: ../../../src/sqltools/idsmon/config
File name: ../../../src/sqltools/idsmon/idspacket
File name: ../../../src/sqltools/idsmon/genconnpacket
File name: ../../../src/sqltools/idsmon/Makefile
File name: ../../../src/sqltools/idsmon/config.h.in
File name: ../../../src/sqltools/idsmon/config.guess
File name: ../../../src/sqltools/idsmon/depcomp
File name: ../../../src/sqltools/idsmon/sqlihexdump.o
File name: ../../../src/sqltools/idsmon/missing
File name: ../../../src/sqltools/idsmon/install.mk
File name: ../../../src/sqltools/idsmon/sqlihexdump
File name: ../../../src/sqltools/idsmon/RCS
File name: ../../../src/sqltools/idsmon/Makefile.am
File name: ../../../src/sqltools/idsmon/test.istar.logs.tar.gz
File name: ../../../src/sqltools/idsmon/idstest.o
File name: ../../../src/sqltools/idsmon/esqlc.mk
File name: ../../../src/sqltools/idsmon/config.sub
File name: ../../../src/sqltools/idsmon/idspacket.o
File name: ../../../src/sqltools/idsmon/compile
File name: ../../../src/sqltools/idsmon/Old.Releases
File name: ../../../src/sqltools/idsmon/esqlc-nosfx.mk
File name: ../../../src/sqltools/idsmon/osiris_11
File name: ../../../src/sqltools/idsmon/config.h.in~
File name: ../../../src/sqltools/idsmon/idstest
File name: ../../../src/sqltools/idsmon/idsmon.c
File name: ../../../src/sqltools/idsmon/acr.decode
File name: ../../../src/sqltools/idsmon/sqlihexdump.dSYM
File name: ../../../src/sqltools/idsmon/toru.istar
File name: ../../../src/sqltools/idsmon/dumpdblflt
File name: ../../../src/sqltools/idsmon/sqlipacket.c
File name: ../../../src/sqltools/idsmon/toru
File name: ../../../src/sqltools/idsmon/data.info.tgz
File name: ../../../src/sqltools/idsmon/idsmon.nmd
File name: ../../../src/sqltools/idsmon/idsmon.jdc
File name: ../../../src/sqltools/idsmon/idsmon
File name: ../../../src/sqltools/idsmon/idsmon.black_19
File name: ../../../src/sqltools/idsmon/Makefile.in
File name: ../../../src/sqltools/idsmon/aclocal.m4
File name: ../../../src/sqltools/idsmon/sqlihexdump.c
File name: ../../../src/sqltools/idsmon/dumpdblflt.dSYM
File name: ../../../src/sqltools/idsmon/dumpdblflt.c
$