kern/134513: [patch] fts(3) FTS_NOCHDIR misbehavior with empty
directory
Jaakko Heinonen
jh at saunalahti.fi
Wed May 13 17:10:02 UTC 2009
>Number: 134513
>Category: kern
>Synopsis: [patch] fts(3) FTS_NOCHDIR misbehavior with empty directory
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Wed May 13 17:10:01 UTC 2009
>Closed-Date:
>Last-Modified:
>Originator: Jaakko Heinonen
>Release: FreeBSD 7.2-RELEASE / 8.0-CURRENT
>Organization:
>Environment:
FreeBSD 8.0-CURRENT r191987
>Description:
If you give an initial path name for fts_open() with trailing slash fts(3)
will strip the slash in post-order visit although the fts(3) manual page
states that the FTSENT structure will be unchanged from pre-order visit.
This happens only when the directory is empty and FTS_NOCHDIR option is used.
See also PR bin/133907.
>How-To-Repeat:
$ cc -Wall -Wextra -O ftstest.c -o ftstest
(Compile the test program below.)
$ mkdir x
$ ./ftstest x/
level: 0 path: x/ info: 1
level: 0 path: x info: 6
(Notice missing trailing slash in post-order.)
%%%
#include <sys/stat.h>
#include <sys/types.h>
#include <fts.h>
#include <stdio.h>
int
main(int argc, char **argv)
{
FTS *fts;
FTSENT *ftsent;
char *fts_argv[] = {".", NULL};
if (argc == 2)
fts_argv[0] = argv[1];
fts = fts_open(fts_argv, FTS_NOCHDIR | FTS_PHYSICAL, NULL);
while ((ftsent = fts_read(fts)) != NULL) {
printf("level: %ld path: %s info: %d\n",
(long)ftsent->fts_level,
ftsent->fts_path,
ftsent->fts_info);
}
fts_close(fts);
return (0);
}
%%%
>Fix:
--- fts-NOCHDIR-trailing-slash.diff begins here ---
Index: lib/libc/gen/fts.3
===================================================================
--- lib/libc/gen/fts.3 (revision 191911)
+++ lib/libc/gen/fts.3 (working copy)
@@ -195,7 +195,7 @@ which was not specified as a file name t
.Dv FTS_SEEDOT ) .
.It Dv FTS_DP
A directory being visited in post-order.
-The contents of the
+The other fields of the
.Vt FTSENT
structure will be unchanged from when
it was returned in pre-order, i.e., with the
Index: lib/libc/gen/fts.c
===================================================================
--- lib/libc/gen/fts.c (revision 191911)
+++ lib/libc/gen/fts.c (working copy)
@@ -836,11 +836,8 @@ mem1: saved_errno = errno;
* If not changing directories, reset the path back to original
* state.
*/
- if (ISSET(FTS_NOCHDIR)) {
- if (len == sp->fts_pathlen || nitems == 0)
- --cp;
- *cp = '\0';
- }
+ if (ISSET(FTS_NOCHDIR))
+ sp->fts_path[cur->fts_pathlen] = '\0';
/*
* If descended after called from fts_children or after called from
--- fts-NOCHDIR-trailing-slash.diff ends here ---
The patch also clarifies the manual page. fts_info info field has always
different value in post-order. Thus it's not exactly true that the structure
will be unchanged.
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list