This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

nftw does not return ENOENT for non-existing path


Hi,

We are currently porting Babeltrace 2 to cygwin and experiencing a subtle
difference regarding the behaviour of nftw().

On a Gnu/Linux system (Ubuntu 18.04), using the example from the man page of
nftw(see nftw.c), passing a non-existent directory will result in a failure of the nftw()
call and errno set to ENOENT.

    joraj@/tmp[]$ gcc -o nftw nftw.c
    joraj@/tmp[]$ ./nftw /this/path/does/not/exist
    nftw: No such file or directory

On cygwin64 (see cygcheck.out), the same program will result in a success of the
nftw() call and no errno set. Still, the non-existent path is flagged as FTW_NS.

    jenkins@ci-node-win64-01 ~ $ gcc -o nftw.exe nftw.c
    jenkins@ci-node-win64-01 ~ $ ./nftw.exe /this/path/does/not/exist/
    ns   0       0   /this/path/does/not/exist/               26

We use nftw() to perform discovery of potential Babeltrace 2 plugins, hence we
do not return error on FTW_NS ans simply skip it. We expected nftw to simply fail if
the base path provided did not exist.

We do plan to simply stat() the path beforehand but we wanted to report this
difference of behaviour just in case.

Also, POSIX 2018 [1] mentions the following:
    The nftw() function shall fail if:
    ...
    [ENOENT]
        A component of path does not name an existing file or path is an empty string.

[1] https://pubs.opengroup.org/onlinepubs/9699919799/functions/nftw.html

Thanks

-- 
Jonathan Rajotte-Julien
EfficiOS
#define _XOPEN_SOURCE 500
#include <ftw.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

static int
display_info(const char *fpath, const struct stat *sb,
             int tflag, struct FTW *ftwbuf)
{
    printf("%-3s %2d %7jd   %-40s %d %s\n",
        (tflag == FTW_D) ?   "d"   : (tflag == FTW_DNR) ? "dnr" :
        (tflag == FTW_DP) ?  "dp"  : (tflag == FTW_F) ?   "f" :
        (tflag == FTW_NS) ?  "ns"  : (tflag == FTW_SL) ?  "sl" :
        (tflag == FTW_SLN) ? "sln" : "???",
        ftwbuf->level, (intmax_t) sb->st_size,
        fpath, ftwbuf->base, fpath + ftwbuf->base);
    return 0;           /* To tell nftw() to continue */
}

int
main(int argc, char *argv[])
{
    int flags = 0;

   if (argc > 2 && strchr(argv[2], 'd') != NULL)
        flags |= FTW_DEPTH;
    if (argc > 2 && strchr(argv[2], 'p') != NULL)
        flags |= FTW_PHYS;

   if (nftw((argc < 2) ? "." : argv[1], display_info, 20, flags)
            == -1) {
        perror("nftw");
        exit(EXIT_FAILURE);
    }
    exit(EXIT_SUCCESS);
}

Attachment: cygcheck.out
Description: Text document

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]