New: ftw doesn't work like documented (may be a documentation bug)
A message that is not in the archive (sent off-list or not yet received): [email protected]
A message that is not in the archive (sent off-list or not yet received): 20100403201146.28880.qmail-9JcytcrH/[email protected]
See below a bug reported against the glibc. Since the glibc maintainer dodged that one, I assume the bug indeed is in the documentation of ftw(3). My manpages are the 3.24-1 Debian package.
IMHO the patch is:
-fpath is the pathname of the entry relative to dirpath.
+fpath is the pathname of the entry relative to the current working directory.
POSIX is very vague about what "fpath" should be btw.
Quoted 36 lines · madcoder at debian dot org
The man page states:
int ftw(const char *dirpath,
int (*fn) (const char *fpath, const struct stat *sb,
int typeflag),
int nopenfd);[...]
fpath is the pathname of the entry relative to dirpath.
Though it appears that it is the pathname of the entry relative to the current working directory.
FWIW this may be a documentation bug since the similar fts interface clearly states that the similar
fts_accpathis relative to the current working directory.Signature · 17 lines
Summary: ftw doesn't work like documented (may be a documentation bug) Product: glibc Version: unspecified Status: NEW Severity: normal Priority: P2 Component: libc AssignedTo: drepper at redhat dot com ReportedBy: madcoder at debian dot org CC: glibc-bugs at sources dot redhat dot com http://sourceware.org/bugzilla/show_bug.cgi?id=11459 ------- You are receiving this mail because: ------- You reported the bug, or are watching the reporter.
Quoted 16 lines · drepper at redhat dot com
------- Additional Comments From drepper at redhat dot com 2010-04-03 20:11 ------- The man pages do not come with glibc and are in no way authoritative. You have to report this elsewhere.
Signature · 10 lines
What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED Resolution| |INVALID http://sourceware.org/bugzilla/show_bug.cgi?id=11459 ------- You are receiving this mail because: ------- You reported the bug, or are watching the reporter.
Signature · 7 lines
·O· Pierre Habouzit ··O [email protected] OOO http://www.madism.org -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
A message that is not in the archive (sent off-list or not yet received): [email protected]
Hello Pierre,
Quoted 3 lines · Pierre Habouzit
See below a bug reported against the glibc. Since the glibc maintainer dodged that one, I assume the bug indeed is in the documentation of ftw(3). My manpages are the 3.24-1 Debian package.
Yes. The man page is clearly incorrect. Thanks for reporting this.
Quoted 6 lines
IMHO the patch is:
-fpath is the pathname of the entry relative to dirpath.
+fpath is the pathname of the entry relative to the current working directory.POSIX is very vague about what "fpath" should be btw.
(Agreed. It could be more precise.)
I believe the correct text should be this:
fpath is the pathname of the entry, and is
expressed either as a pathname relative to the calling process's current working directory at the time of the call to ftw(), if dirpath was expressed as a relative pathname, or as an absolute pathname, if dirpath was expressed as an absolute pathname.
I have updated the man page accordingly, but would welcome review/checking of this text.
Cheers,
Michael
Quoted 62 lines · madcoder at debian dot org
Quoted 36 lines
The man page states:
int ftw(const char *dirpath,
int (*fn) (const char *fpath, const struct stat *sb, int typeflag),
int nopenfd);[...]
fpath is the pathname of the entry relative to dirpath.
Though it appears that it is the pathname of the entry relative to the current working directory.
FWIW this may be a documentation bug since the similar fts interface clearly states that the similar
fts_accpathis relative to the current working directory.--
Summary: ftw doesn't work like documented (may be a documentation bug)
Product: glibc
Version: unspecified
Status: NEW
Severity: normal
Priority: P2
Component: libc
AssignedTo: drepper at redhat dot com
ReportedBy: madcoder at debian dot org
CC: glibc-bugs at sources dot redhat dot comhttp://sourceware.org/bugzilla/show_bug.cgi?id=11459
------- You are receiving this mail because: ------- You reported the bug, or are watching the reporter.
Quoted 12 lines · drepper at redhat dot com
------- Additional Comments From drepper at redhat dot com 2010-04-03 20:11 ------- The man pages do not come with glibc and are in no way authoritative. You have to report this elsewhere.
--
What |Removed |Added
----------------------------------------------------------------------------
Status|NEW |RESOLVED Resolution| |INVALIDQuoted 4 lines
http://sourceware.org/bugzilla/show_bug.cgi?id=11459
------- You are receiving this mail because: ------- You reported the bug, or are watching the reporter.
--
·O· Pierre Habouzit
··O [email protected] OOO http://www.madism.org
Signature · 7 lines
Michael Kerrisk Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/ Author of "The Linux Programming Interface" http://blog.man7.org/ -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
A message that is not in the archive (sent off-list or not yet received): AANLkTim05fJpMXD1owEON-70WwxDUkxIvYIgkn7EfBEf-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org
Quoted 27 lines · Michael Kerrisk
Hello Pierre,
Quoted 3 lines · Pierre Habouzit
See below a bug reported against the glibc. Since the glibc maintainer dodged that one, I assume the bug indeed is in the documentation of ftw(3). My manpages are the 3.24-1 Debian package.
Yes. The man page is clearly incorrect. Thanks for reporting this.
Quoted 6 lines
IMHO the patch is:
-fpath is the pathname of the entry relative to dirpath.
+fpath is the pathname of the entry relative to the current working directory.POSIX is very vague about what "fpath" should be btw.
(Agreed. It could be more precise.)
I believe the correct text should be this:
fpath is the pathname of the entry, and is
expressed either as a pathname relative to the calling process's current working directory at the time of the call toftw(), if dirpath was expressed as a relative pathname, or as an absolute pathname, if dirpath was expressed as an absolute pathname.
Quoted 2 lines
I have updated the man page accordingly, but would welcome review/checking of this text.
Afaict, it's not correct: ftw may perform chdir() calls, so the pathname is relative to the current working directory at the time fn is called.
I'd rather phrase it that way (minus probable english mistakes):
fpath is the pathname of the entry, and is either a relative pathname to the current working directory of the application when fn is called, or as an absolute pathname.
Signature · 7 lines
·O· Pierre Habouzit ··O [email protected] OOO http://www.madism.org -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
A message that is not in the archive (sent off-list or not yet received): [email protected]
Hi Pierre,
Quoted 31 lines · Pierre Habouzit
Quoted 27 lines · Michael Kerrisk
Hello Pierre,
Quoted 3 lines · Pierre Habouzit
See below a bug reported against the glibc. Since the glibc maintainer dodged that one, I assume the bug indeed is in the documentation of ftw(3). My manpages are the 3.24-1 Debian package.
Yes. The man page is clearly incorrect. Thanks for reporting this.
Quoted 6 lines
IMHO the patch is:
-fpath is the pathname of the entry relative to dirpath.
+fpath is the pathname of the entry relative to the current working directory.POSIX is very vague about what "fpath" should be btw.
(Agreed. It could be more precise.)
I believe the correct text should be this:
fpath is the pathname of the entry, and is expressed either as a pathname relative to the calling process's current working directory at the time of the call to
ftw(), if dirpath was expressed as a relative pathname, or as an absolute pathname, if dirpath was expressed as an absolute pathname.Quoted 2 lines
I have updated the man page accordingly, but would welcome review/checking of this text.
Quoted 8 lines
Afaict, it's not correct: ftw may perform
chdir()calls, so the pathname is relative to the current working directory at the timefnis called.I'd rather phrase it that way (minus probable english mistakes):
fpath is the pathname of the entry, and is either a relative pathname to the current working directory of the application when
fnis called, or as an absolute pathname.
Thanks for taking a look at this. However, I *think* your analysis is wrong, and my proposed changes is right. But, still I'd like some further confirmation. Please take a look at the the program below, and the output produced when it runs.
$ cat t.c #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 intdisplayFileInfo(const char *pathname, const struct stat *sbuf, int type)
{
printf("%c ", (type == FTW_D) ? 'd' : (type == FTW_DNR) ? 'D' :
(type == FTW_F) ? 'f' : (type == FTW_SL) ? 's' :
(type == FTW_NS) ? 'N' : '?');
if (type != FTW_NS)
printf("%7ld %7lld ", (long) sbuf->st_ino,
(long long) sbuf->st_size);
else
printf(" ");
printf("%s\n", pathname);
/* Let's mess with the curent directory during the ftw() call,
to see what value is passed to 'pathname' in successive calls
to displayFileInfo() */
chdir("..");
system("pwd");
return 0; /* to tell ftw() to continue */
}intmain(int argc, char *argv[])
{
if (ftw((argc < 2) ? "." : argv[1], displayFileInfo, 10) == -1) {
perror("ftw");
exit(EXIT_FAILURE);
} /* if */
exit(EXIT_SUCCESS);
}
$ cd dir1
$ find ../dir2
../dir2
../dir2/sub
../dir2/sub/b
../dir2/sub/a
../dir2/bbb
$ ../a.out ../dir2/
d 9863613 4096 ../dir2
/home/mtk/tlpi/dirs_links
d 1236107 4096 ../dir2/sub
/home/mtk/tlpi
f 9176008 0 ../dir2/sub/b
/home/mtk
f 9176007 0 ../dir2/sub/a
/home
f 7635615 38 ../dir2/bbb
/See how the CWD changes, but the pathname is always expressed with respect to "dir1"? Do you agree with my text now, or do you still see some problem?
Thanks,
Michael
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
A message that is not in the archive (sent off-list or not yet received): AANLkTinhGzNB_dabQcan3c1nQuGwkaTIBAVZuRO2dJty-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org
Quoted 39 lines · Michael Kerrisk
Hi Pierre,
Quoted 36 lines · Pierre Habouzit
Quoted 27 lines · Michael Kerrisk
Hello Pierre,
Quoted 3 lines · Pierre Habouzit
See below a bug reported against the glibc. Since the glibc maintainer dodged that one, I assume the bug indeed is in the documentation of ftw(3). My manpages are the 3.24-1 Debian package.
Yes. The man page is clearly incorrect. Thanks for reporting this.
Quoted 6 lines
IMHO the patch is:
-fpath is the pathname of the entry relative to dirpath.
+fpath is the pathname of the entry relative to the current working directory.POSIX is very vague about what "fpath" should be btw.
(Agreed. It could be more precise.)
I believe the correct text should be this:
fpath is the pathname of the entry, and is expressed either as a pathname relative to the calling process's current working directory at the time of the call to
ftw(), if dirpath was expressed as a relative pathname, or as an absolute pathname, if dirpath was expressed as an absolute pathname.Quoted 2 lines
I have updated the man page accordingly, but would welcome review/checking of this text.
Afaict, it's not correct: ftw may perform
chdir()calls, so the pathname is relative to the current working directory at the timefnis called.I'd rather phrase it that way (minus probable english mistakes):
Quoted 8 lines
Quoted 3 lines
fpath is the pathname of the entry, and is either a relative pathname to the current working directory of the application when
fnis called, or as an absolute pathname.Thanks for taking a look at this. However, I *think* your analysis is wrong, and my proposed changes is right. But, still I'd like some further confirmation. Please take a look at the the program below, and the output produced when it runs.
Yeah, that's because you're doing chdir()s during ftw, which is undefined behaviour as documented in the manpage already IIRC.
The point is, ftw() /may/ decide to do chdir() by itself sometimes, and then the path is relative to the current working directory as set by ftw().
I'm pretty sure it's what POSIX authorizes ftw() to perform chdirs.
And when I look at ftw.c in the glibc, it's also pretty much what happens in the case when you set FTW_CHDIR in the flags: ftw() forces a chdir before the fn() call, and makes the path relative to this cwd.
It happens that the glibc doesn't seem to perform any kind of chdir() in the other cases (IOW when FTW_CHDIR isn't set), but I'm pretty sure POSIX allows ftw() to do so.
Signature · 7 lines
·O· Pierre Habouzit ··O [email protected] OOO http://www.madism.org -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
A message that is not in the archive (sent off-list or not yet received): [email protected]
Hi Pierre,
Thanks for following up on this. I still think the current man page text is correct. See below.
Quoted 44 lines · Pierre Habouzit
Quoted 43 lines · Michael Kerrisk
Hi Pierre,
Quoted 39 lines · Pierre Habouzit
Quoted 27 lines · Michael Kerrisk
Hello Pierre,
Quoted 3 lines · Pierre Habouzit
See below a bug reported against the glibc. Since the glibc maintainer dodged that one, I assume the bug indeed is in the documentation of ftw(3). My manpages are the 3.24-1 Debian package.
Yes. The man page is clearly incorrect. Thanks for reporting this.
Quoted 6 lines
IMHO the patch is:
-fpath is the pathname of the entry relative to dirpath.
+fpath is the pathname of the entry relative to the current working directory.POSIX is very vague about what "fpath" should be btw.
(Agreed. It could be more precise.)
I believe the correct text should be this:
fpath is the pathname of the entry, and is expressed either as a pathname relative to the calling process's current working directory at the time of the call to
ftw(), if dirpath was expressed as a relative pathname, or as an absolute pathname, if dirpath was expressed as an absolute pathname.Quoted 2 lines
I have updated the man page accordingly, but would welcome review/checking of this text.
Afaict, it's not correct: ftw may perform
chdir()calls, so the pathname is relative to the current working directory at the timefnis called.I'd rather phrase it that way (minus probable english mistakes):
fpath is the pathname of the entry, and is either a relative pathname to the current working directory of the application when
fnis called, or as an absolute pathname.
Quoted 7 lines
Quoted 4 lines
Thanks for taking a look at this. However, I *think* your analysis is wrong, and my proposed changes is right. But, still I'd like some further confirmation. Please take a look at the the program below, and the output produced when it runs.
Yeah, that's because you're doing chdir()s during ftw, which is undefined behaviour as documented in the manpage already IIRC.
True. That is documented in the POSIX page, but not currently in man-pages. I've fixed that now. Thanks.
Quoted 3 lines
The point is,
ftw()/may/ decide to dochdir()by itself sometimes, and then the path is relative to the current working directory as set byftw().
I'm not sure why you think it may decide to do this. If this was unpredictable, then it would create difficulties for the application, as far as I can tell, since it would take quite some effort to correctly interpret the pathname supplied to 'fn'. And POSIX seems fairly clear on the point (at least for nftw()):
FTW_CHDIR
If set, nftw() shall change the current working directory to each directory as it reports files in that directory. If clear, nftw() shall not change the current working directory.
Quoted 1 line
I'm pretty sure it's what POSIX authorizes
ftw()to perform chdirs.
See above.
Quoted 3 lines
And when I look at
ftw.cin the glibc, it's also pretty much what happens in the case when you setFTW_CHDIRin the flags:ftw()forces a chdir before thefn()call, and makes the path relative to this cwd.
Yes to the first part, but as far as I can see, still no to the last part ("and makes the path relative to this cwd" ). See below.
Quoted 3 lines
It happens that the glibc doesn't seem to perform any kind of
chdir()in the other cases (IOW whenFTW_CHDIRisn't set), but I'm pretty sure POSIX allowsftw()to do so.
I don't see anywhere that POSIX authorizes that, and it wouldn't seem sensible to do so. See above.
Here's a variation on my earlier test program that uses nftw() instead. If "c" is provided in the second command line argument, it uses "FTW_CHDIR". Looking at the results, do you agree with my analysis?
$ cat n.c #define _GNU_SOURCE #define _XOPEN_SOURCE 500 #include <ftw.h> #include <stdio.h> #include <stdlib.h> #include <string.h>
static int
displayFileInfo(const char *fpath, const struct stat *sb,
int tflag, struct FTW *ftwbuf)
{
printf("%-3s %2d %7lld %-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, (long long) sb->st_size,
fpath, ftwbuf->base, fpath + ftwbuf->base);#ifdef DO_CHDIR
/* Let's mess with the curent directory during the ftw() call,
to see what value is passed to 'pathname' in successive calls to displayFileInfo() */
chdir("..");
#endif
system("pwd");
return 0; /* To tell nftw() to continue */
}
intmain(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 (argc > 2 && strchr(argv[2], 'c') != NULL)
flags |= FTW_CHDIR;
if (nftw((argc < 2) ? "." : argv[1], displayFileInfo, 20, flags) == -1) {
perror("nftw");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}$ cc -o n n.c $ cd dir1 /home/mtk/tlpi/dl/dir1 $ find ../dir2 ../dir2 ../dir2/sub ../dir2/sub/d ../dir2/sub/b ../dir2/sub/c ../dir2/sub/a ../dir2/bbb $ ../n ../dir2 c d 0 4096 ../dir2 3 dir2 /home/mtk/tlpi/dirs_links d 1 4096 ../dir2/sub 8 sub /home/mtk/tlpi/dirs_links/dir2 f 2 0 ../dir2/sub/d 12 d /home/mtk/tlpi/dirs_links/dir2/sub f 2 0 ../dir2/sub/b 12 b /home/mtk/tlpi/dirs_links/dir2/sub f 2 0 ../dir2/sub/c 12 c /home/mtk/tlpi/dirs_links/dir2/sub f 2 0 ../dir2/sub/a 12 a /home/mtk/tlpi/dirs_links/dir2/sub f 1 38 ../dir2/bbb 8 bbb /home/mtk/tlpi/dirs_links/dir2 $ ../n ../dir2 d 0 4096 ../dir2 3 dir2 /home/mtk/tlpi/dl/dir1 d 1 4096 ../dir2/sub 8 sub /home/mtk/tlpi/dl/dir1 f 2 0 ../dir2/sub/d 12 d /home/mtk/tlpi/dl/dir1 f 2 0 ../dir2/sub/b 12 b /home/mtk/tlpi/dl/dir1 f 2 0 ../dir2/sub/c 12 c /home/mtk/tlpi/dl/dir1 f 2 0 ../dir2/sub/a 12 a /home/mtk/tlpi/dl/dir1 f 1 38 ../dir2/bbb 8 bbb /home/mtk/tlpi/dl/dir1
Thanks,
Michael
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
A message that is not in the archive (sent off-list or not yet received): AANLkTikWG4U2wWS6ccM98Mg32WNrVCu5QCmz46hQ7lCC-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org
I think it makes sense indeed.
Quoted 196 lines · Michael Kerrisk
Hi Pierre,
Thanks for following up on this. I still think the current man page text is correct. See below.
Quoted 44 lines · Pierre Habouzit
Quoted 43 lines · Michael Kerrisk
Hi Pierre,
Quoted 39 lines · Pierre Habouzit
Quoted 27 lines · Michael Kerrisk
Hello Pierre,
Quoted 3 lines · Pierre Habouzit
See below a bug reported against the glibc. Since the glibc maintainer dodged that one, I assume the bug indeed is in the documentation of ftw(3). My manpages are the 3.24-1 Debian package.
Yes. The man page is clearly incorrect. Thanks for reporting this.
Quoted 6 lines
IMHO the patch is:
-fpath is the pathname of the entry relative to dirpath.
+fpath is the pathname of the entry relative to the current working directory.POSIX is very vague about what "fpath" should be btw.
(Agreed. It could be more precise.)
I believe the correct text should be this:
fpath is the pathname of the entry, and is expressed either as a pathname relative to the calling process's current working directory at the time of the call to
ftw(), if dirpath was expressed as a relative pathname, or as an absolute pathname, if dirpath was expressed as an absolute pathname..Quoted 2 lines
I have updated the man page accordingly, but would welcome review/checking of this text.
Afaict, it's not correct: ftw may perform
chdir()calls, so the pathname is relative to the current working directory at the timefnis called.I'd rather phrase it that way (minus probable english mistakes):
fpath is the pathname of the entry, and is either a relative pathname to the current working directory of the application when
fnis called, or as an absolute pathname.Quoted 7 lines
Quoted 4 lines
Thanks for taking a look at this. However, I *think* your analysis is wrong, and my proposed changes is right. But, still I'd like some further confirmation. Please take a look at the the program below, and the output produced when it runs.
Yeah, that's because you're doing chdir()s during ftw, which is undefined behaviour as documented in the manpage already IIRC.
True. That is documented in the POSIX page, but not currently in man-pages. I've fixed that now. Thanks.
Quoted 3 lines
The point is,
ftw()/may/ decide to dochdir()by itself sometimes, and then the path is relative to the current working directory as set byftw().I'm not sure why you think it may decide to do this. If this was unpredictable, then it would create difficulties for the application, as far as I can tell, since it would take quite some effort to correctly interpret the pathname supplied to 'fn'. And POSIX seems fairly clear on the point (at least for
nftw()):
FTW_CHDIR
If set,nftw()shall change the current working directory to each directory as it reports files in that directory. If clear,nftw()shall not change the current working directory.Quoted 1 line
I'm pretty sure it's what POSIX authorizes
ftw()to perform chdirs.See above.
Quoted 3 lines
And when I look at
ftw.cin the glibc, it's also pretty much what happens in the case when you setFTW_CHDIRin the flags:ftw()forces a chdir before thefn()call, and makes the path relative to this cwd.Yes to the first part, but as far as I can see, still no to the last part ("and makes the path relative to this cwd" ). See below.
Quoted 3 lines
It happens that the glibc doesn't seem to perform any kind of
chdir()in the other cases (IOW whenFTW_CHDIRisn't set), but I'm pretty sure POSIX allowsftw()to do so.I don't see anywhere that POSIX authorizes that, and it wouldn't seem sensible to do so. See above.
Here's a variation on my earlier test program that uses
nftw()instead. If "c" is provided in the second command line argument, it uses "FTW_CHDIR". Looking at the results, do you agree with my analysis?$ cat n.c #define _GNU_SOURCE #define _XOPEN_SOURCE 500 #include <ftw.h> #include <stdio.h> #include <stdlib.h> #include <string.h>static int
displayFileInfo(const char *fpath, const struct stat *sb,
int tflag, struct FTW *ftwbuf){ printf("%-3s %2d %7lld %-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, (long long) sb->st_size, fpath, ftwbuf->base, fpath + ftwbuf->base);#ifdef
DO_CHDIR
/* Let's mess with the curent directory during theftw()call,
to see what value is passed to 'pathname' in successive calls todisplayFileInfo()*/
chdir("..");
#endif
system("pwd");
return 0; /* To tellnftw()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 (argc > 2 && strchr(argv[2], 'c') != NULL) flags |= FTW_CHDIR; if (nftw((argc < 2) ? "." : argv[1], displayFileInfo, 20, flags) == -1) { perror("nftw"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); }$ cc -o n n.c $ cd dir1 /home/mtk/tlpi/dl/dir1 $ find ../dir2 .../dir2 .../dir2/sub .../dir2/sub/d .../dir2/sub/b .../dir2/sub/c .../dir2/sub/a .../dir2/bbb $ ../n ../dir2 c d 0 4096 ../dir2 3 dir2 /home/mtk/tlpi/dirs_links d 1 4096 ../dir2/sub 8 sub /home/mtk/tlpi/dirs_links/dir2 f 2 0 ../dir2/sub/d 12 d /home/mtk/tlpi/dirs_links/dir2/sub f 2 0 ../dir2/sub/b 12 b /home/mtk/tlpi/dirs_links/dir2/sub f 2 0 ../dir2/sub/c 12 c /home/mtk/tlpi/dirs_links/dir2/sub f 2 0 ../dir2/sub/a 12 a /home/mtk/tlpi/dirs_links/dir2/sub f 1 38 ../dir2/bbb 8 bbb /home/mtk/tlpi/dirs_links/dir2 $ ../n ../dir2 d 0 4096 ../dir2 3 dir2 /home/mtk/tlpi/dl/dir1 d 1 4096 ../dir2/sub 8 sub /home/mtk/tlpi/dl/dir1 f 2 0 ../dir2/sub/d 12 d /home/mtk/tlpi/dl/dir1 f 2 0 ../dir2/sub/b 12 b /home/mtk/tlpi/dl/dir1 f 2 0 ../dir2/sub/c 12 c /home/mtk/tlpi/dl/dir1 f 2 0 ../dir2/sub/a 12 a /home/mtk/tlpi/dl/dir1 f 1 38 ../dir2/bbb 8 bbb /home/mtk/tlpi/dl/dir1Thanks,
Michael
Signature · 7 lines
·O· Pierre Habouzit ··O [email protected] OOO http://www.madism.org -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 1 line · Pierre Habouzit
I think it makes sense indeed.
Thanks Pierre. It's always good to have someone else confirm.
Cheers,
Michael
Quoted 203 lines · Michael Kerrisk
Quoted 193 lines
Hi Pierre,
Thanks for following up on this. I still think the current man page text is correct. See below.
Quoted 44 lines · Pierre Habouzit
Quoted 43 lines · Michael Kerrisk
Hi Pierre,
Quoted 39 lines · Pierre Habouzit
Quoted 27 lines · Michael Kerrisk
Hello Pierre,
Quoted 3 lines · Pierre Habouzit
See below a bug reported against the glibc. Since the glibc maintainer dodged that one, I assume the bug indeed is in the documentation of ftw(3). My manpages are the 3.24-1 Debian package.
Yes. The man page is clearly incorrect. Thanks for reporting this.
Quoted 6 lines
IMHO the patch is:
-fpath is the pathname of the entry relative to dirpath.
+fpath is the pathname of the entry relative to the current working directory.POSIX is very vague about what "fpath" should be btw.
(Agreed. It could be more precise.)
I believe the correct text should be this:
fpath is the pathname of the entry, and is expressed either as a pathname relative to the calling process's current working directory at the time of the call to
ftw(), if dirpath was expressed as a relative pathname, or as an absolute pathname, if dirpath was expressed as an absolute pathname..Quoted 2 lines
I have updated the man page accordingly, but would welcome review/checking of this text.
Afaict, it's not correct: ftw may perform
chdir()calls, so the pathname is relative to the current working directory at the timefnis called.I'd rather phrase it that way (minus probable english mistakes):
fpath is the pathname of the entry, and is either a relative pathname to the current working directory of the application when
fnis called, or as an absolute pathname.Quoted 7 lines
Quoted 4 lines
Thanks for taking a look at this. However, I *think* your analysis is wrong, and my proposed changes is right. But, still I'd like some further confirmation. Please take a look at the the program below, and the output produced when it runs.
Yeah, that's because you're doing chdir()s during ftw, which is undefined behaviour as documented in the manpage already IIRC.
True. That is documented in the POSIX page, but not currently in man-pages. I've fixed that now. Thanks.
Quoted 3 lines
The point is,
ftw()/may/ decide to dochdir()by itself sometimes, and then the path is relative to the current working directory as set byftw().I'm not sure why you think it may decide to do this. If this was unpredictable, then it would create difficulties for the application, as far as I can tell, since it would take quite some effort to correctly interpret the pathname supplied to 'fn'. And POSIX seems fairly clear on the point (at least for
nftw()):FTW_CHDIR
If set,nftw()shall change the current working directory to each directory as it reports files in that directory. If clear,nftw()shall not change the current working directory.Quoted 1 line
I'm pretty sure it's what POSIX authorizes
ftw()to perform chdirs.See above.
Quoted 3 lines
And when I look at
ftw.cin the glibc, it's also pretty much what happens in the case when you setFTW_CHDIRin the flags:ftw()forces a chdir before thefn()call, and makes the path relative to this cwd.Yes to the first part, but as far as I can see, still no to the last part ("and makes the path relative to this cwd" ). See below.
Quoted 3 lines
It happens that the glibc doesn't seem to perform any kind of
chdir()in the other cases (IOW whenFTW_CHDIRisn't set), but I'm pretty sure POSIX allowsftw()to do so.I don't see anywhere that POSIX authorizes that, and it wouldn't seem sensible to do so. See above.
Here's a variation on my earlier test program that uses
nftw()instead. If "c" is provided in the second command line argument, it uses "FTW_CHDIR". Looking at the results, do you agree with my analysis?$ cat n.c #define _GNU_SOURCE #define _XOPEN_SOURCE 500 #include <ftw.h> #include <stdio.h> #include <stdlib.h> #include <string.h>static int
displayFileInfo(const char *fpath, const struct stat *sb, int tflag, struct FTW *ftwbuf)
{
printf("%-3s %2d %7lld %-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, (long long)sb->st_size,
fpath,ftwbuf->base, fpath +ftwbuf->base); #ifdefDO_CHDIR
/* Let's mess with the curent directory during theftw()call, to see what value is passed to 'pathname' in successive calls todisplayFileInfo()*/
chdir("..");
#endif
system("pwd");
return 0; /* To tellnftw()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 (argc > 2 &&strchr(argv[2], 'c')!= NULL)
flags |=FTW_CHDIR;if (
nftw((argc < 2) ? "." : argv[1], displayFileInfo, 20, flags)== -1) {perror("nftw");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}$ cc -o n n.c $ cd dir1 /home/mtk/tlpi/dl/dir1 $ find ../dir2 .../dir2 .../dir2/sub .../dir2/sub/d .../dir2/sub/b .../dir2/sub/c .../dir2/sub/a .../dir2/bbb $ ../n ../dir2 c d 0 4096 ../dir2 3 dir2 /home/mtk/tlpi/dirs_links d 1 4096 ../dir2/sub 8 sub /home/mtk/tlpi/dirs_links/dir2 f 2 0 ../dir2/sub/d 12 d /home/mtk/tlpi/dirs_links/dir2/sub f 2 0 ../dir2/sub/b 12 b /home/mtk/tlpi/dirs_links/dir2/sub f 2 0 ../dir2/sub/c 12 c /home/mtk/tlpi/dirs_links/dir2/sub f 2 0 ../dir2/sub/a 12 a /home/mtk/tlpi/dirs_links/dir2/sub f 1 38 ../dir2/bbb 8 bbb /home/mtk/tlpi/dirs_links/dir2 $ ../n ../dir2 d 0 4096 ../dir2 3 dir2 /home/mtk/tlpi/dl/dir1 d 1 4096 ../dir2/sub 8 sub /home/mtk/tlpi/dl/dir1 f 2 0 ../dir2/sub/d 12 d /home/mtk/tlpi/dl/dir1 f 2 0 ../dir2/sub/b 12 b /home/mtk/tlpi/dl/dir1 f 2 0 ../dir2/sub/c 12 c /home/mtk/tlpi/dl/dir1 f 2 0 ../dir2/sub/a 12 a /home/mtk/tlpi/dl/dir1 f 1 38 ../dir2/bbb 8 bbb /home/mtk/tlpi/dl/dir1Quoted 3 lines
Thanks,
Michael
--
·O· Pierre Habouzit
··O [email protected] OOO http://www.madism.org
Signature · 7 lines
Michael Kerrisk Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/ Author of "The Linux Programming Interface" http://blog.man7.org/ -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html