stat() error 'No such file or directory' when file name is returned by readdir() stat() error 'No such file or directory' when file name is returned by readdir() unix unix

stat() error 'No such file or directory' when file name is returned by readdir()


dirp->d_name is the name of the file in the directory: for example, "udpclient.c". The full name of the file is thus "/home/eipe/c/udpclient.c" - but your current working directory is /home/eipe, so stat() is trying to access "/home/eipe/udpclient.c", which doesn't exist.

You can either change your working directory to argv[1] using chdir(), or you can prepend argv[1] to each filename before you call stat().


Note that POSIX 2008 introduces fstatat() and related functions (system calls), all distinguished by the at suffix to a familiar function name. It also defines dirfd() to get the file descriptor associated with a directory stream.

The *at() functions take one (or two in the case of renameat()) open file descriptors that refer to a directory. This means that another way of coding this, on a system that supports fstatat() would be:

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);}

Using fstatat() and related functions allows you to use relative pathnames without using chdir() (which is dangerous; it is hard to get back to where you started without using fchdir()), or concatenating names as shown in the main accepted answer. For portability, it is probably still advisable to use concatenation anyway — but I was able to test this on Mac OS X (10.10.1) and Linux (Ubuntu 14.04), using the code below.

Developed into a complete program (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;}

Sample run:

$ test-fstatat ~/bin/JLSS-Dist/RCS ../../../src/sqltools/idsmonDirectory:           /Users/jonathanleffler/bin/JLSS-Dist/RCSFile 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,vFile name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/jlssdist.jdc,vFile name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/old.msd.sh,vFile name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/chksumtool.pl,vFile name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/msd2nmd.pl,vFile name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/mknmd.sh,vFile name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/publictimestamp.sh,vFile name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/new.mknmd.sh,vFile name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/PRODCODE,vFile name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/prodverstamp.sh,vFile name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/md5.create.pl,vFile name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/jdcrelease.sh,vFile name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/JLSS-Dist.mk,vFile name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/PRODUCT,vFile name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/msd.create.sh,vFile name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/distribution.mk,vFile name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/nmd.create.sh,vFile name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/jlss.sh,vFile name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/VERSION,vFile name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/cvtjdc.sh,vFile name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/redonmd.sh,vFile name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/updmsd.sh,vFile name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/setnmd.sh,vFile name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/list2msd.pl,vFile name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/chkmsdnmd.sh,vFile name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/vercmp.pl,vFile name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/MSD.sh,vFile name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/setjdcversion.sh,vFile name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/sortnmd.sh,vFile name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/gennmd.sh,vFile name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/md5.verify.pl,vFile name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/setbomversion.sh,vFile name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/chkbodlst.sh,vFile name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/updnmd.sh,vFile name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/domsd.sh,vFile name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/md5.chksum.pl,vFile name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/bomrelease.pl,vFile name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/mkmsd.sh,vFile name:           /Users/jonathanleffler/bin/JLSS-Dist/RCS/fixnmd.sh,vDirectory:           ../../../src/sqltools/idsmonFile name:           ../../../src/sqltools/idsmon/.File name:           ../../../src/sqltools/idsmon/..File name:           ../../../src/sqltools/idsmon/idstest.cFile name:           ../../../src/sqltools/idsmon/idslenFile name:           ../../../src/sqltools/idsmon/install-shFile name:           ../../../src/sqltools/idsmon/scatterinfoFile name:           ../../../src/sqltools/idsmon/ltmain.shFile name:           ../../../src/sqltools/idsmon/idsmon.msdFile name:           ../../../src/sqltools/idsmon/idsmon.oFile name:           ../../../src/sqltools/idsmon/configureFile name:           ../../../src/sqltools/idsmon/genscatterFile name:           ../../../src/sqltools/idsmon/configFile name:           ../../../src/sqltools/idsmon/idspacketFile name:           ../../../src/sqltools/idsmon/genconnpacketFile name:           ../../../src/sqltools/idsmon/MakefileFile name:           ../../../src/sqltools/idsmon/config.h.inFile name:           ../../../src/sqltools/idsmon/config.guessFile name:           ../../../src/sqltools/idsmon/depcompFile name:           ../../../src/sqltools/idsmon/sqlihexdump.oFile name:           ../../../src/sqltools/idsmon/missingFile name:           ../../../src/sqltools/idsmon/install.mkFile name:           ../../../src/sqltools/idsmon/sqlihexdumpFile name:           ../../../src/sqltools/idsmon/RCSFile name:           ../../../src/sqltools/idsmon/Makefile.amFile name:           ../../../src/sqltools/idsmon/test.istar.logs.tar.gzFile name:           ../../../src/sqltools/idsmon/idstest.oFile name:           ../../../src/sqltools/idsmon/esqlc.mkFile name:           ../../../src/sqltools/idsmon/config.subFile name:           ../../../src/sqltools/idsmon/idspacket.oFile name:           ../../../src/sqltools/idsmon/compileFile name:           ../../../src/sqltools/idsmon/Old.ReleasesFile name:           ../../../src/sqltools/idsmon/esqlc-nosfx.mkFile name:           ../../../src/sqltools/idsmon/osiris_11File name:           ../../../src/sqltools/idsmon/config.h.in~File name:           ../../../src/sqltools/idsmon/idstestFile name:           ../../../src/sqltools/idsmon/idsmon.cFile name:           ../../../src/sqltools/idsmon/acr.decodeFile name:           ../../../src/sqltools/idsmon/sqlihexdump.dSYMFile name:           ../../../src/sqltools/idsmon/toru.istarFile name:           ../../../src/sqltools/idsmon/dumpdblfltFile name:           ../../../src/sqltools/idsmon/sqlipacket.cFile name:           ../../../src/sqltools/idsmon/toruFile name:           ../../../src/sqltools/idsmon/data.info.tgzFile name:           ../../../src/sqltools/idsmon/idsmon.nmdFile name:           ../../../src/sqltools/idsmon/idsmon.jdcFile name:           ../../../src/sqltools/idsmon/idsmonFile name:           ../../../src/sqltools/idsmon/idsmon.black_19File name:           ../../../src/sqltools/idsmon/Makefile.inFile name:           ../../../src/sqltools/idsmon/aclocal.m4File name:           ../../../src/sqltools/idsmon/sqlihexdump.cFile name:           ../../../src/sqltools/idsmon/dumpdblflt.dSYMFile name:           ../../../src/sqltools/idsmon/dumpdblflt.c$