bug-glibc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

ftw() not correctly handling symlinks


From: Michael Kerrisk
Subject: ftw() not correctly handling symlinks
Date: Wed, 27 Jun 2001 19:48:39 +0200

Gidday,

It appears to me that ftw() isn't handling symbolic links correctly:

When dealing with a symbolic link, ftw() should pass its helper function 
(fn) either FTW_SL or, if stat() failed because of a dangling link, then 
possibly FTW_NS.  From XSH draft 7, ftw(): 

15198 FTW_SL For a symbolic link (but see also FTW_NS below).
15199 FTW_NS For an object other than a symbolic link on which stat( ) 
could not successfully be
15200 executed. If the object is a symbolic link and stat( ) failed, it is 
unspecified whether
15201 ftw( ) passes FTW_SL or FTW_NS to the user-supplied function.

(The above text is the same in SUSv2)

Currently, for a dangling symlink, ftw() passes 'flag' as FTW_NS (which is 
permitted, but wouldn't FTW_SL be preferable, with an lstat() of the 
link?).  

However, if the symlink points to a valid file or directory, then ftw 
passes the flag type corresponding to the file (e.g. FTW_F for a file, or 
FTW_DNR for a directory that cannot be read).  For symlinks to a 
directory, ftw() simply follows the symlink.  The SUS isn't very explicit 
on this point, but in this last case, my reading of it is that the link 
should NOT be followed, and instead the helper function should be called 
with flags specified as FTW_SL.

My simple test program attached at the end of this mail - you'll need to 
make your own test files, directories, and symlinks though.

I detected this problem with glibc 2.1.3, but looking at the source of 
2.2.3, no changes appear to have affected this issue.

Cheers

Michael

*************************

/* ftw_test.c

   Michael Kerrisk, 2001
*/

#include <stdio.h>
#include <stdlib.h>
#include <ftw.h>

/* Function called by ftw(): print type, i-node number, size in bytes,
   and name of each file. */

static int
fn(const char *path, const struct stat *sbuf, int flag)
{
    printf("%-7s ",  (flag == FTW_D) ? "DIR" : 
        (flag == FTW_DNR) ? "DIR-NR" :
        (flag == FTW_F) ? "FILE" : 
        (flag == FTW_SL) ? "SL" : "???");
    if (flag != FTW_NS)
        printf("%7ld %7ld ",  sbuf->st_ino, sbuf->st_size);
    printf("%s\n", path);

    return 0;           /* to tell ftw() to continue */
} /* fn */

int
main(int argc, char *argv[])
{
    ftw((argc < 2) ? "." : argv[1], fn, 10);
    exit(EXIT_SUCCESS);
} /* main */




reply via email to

[Prev in Thread] Current Thread [Next in Thread]