This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.
Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Hi! If the depth level at which {,n}ftw callback decides to return non-zero is bigger than the descriptors argument passed to {,n}ftw, we trigger an assertion in ftw_dir and depending on NDEBUG either don't behave correctly or abort. It is perfectly valid situation though, we just need to free dir contents and return that value. This patch fixes this plus adds a testcase for this (which fails unless this patch is applied). 2000-12-14 Jakub Jelinek <jakub@redhat.com> * io/ftw.c (ftw_dir): If process_entry returned non-zero result and dir.stream is NULL, only free dir.content. * io/ftwtest.c (cb, main): Add --early-exit option to test it. * io/ftwtest-sh: Test with --early-exit. --- libc/io/ftw.c.jj Wed May 3 10:19:51 2000 +++ libc/io/ftw.c Thu Dec 14 13:21:16 2000 @@ -426,18 +426,17 @@ ftw_dir (struct ftw_data *data, struct S int save_err; char *runp = dir.content; - assert (result == 0); + if (result == 0) + while (*runp != '\0') + { + char *endp = strchr (runp, '\0'); - while (*runp != '\0') - { - char *endp = strchr (runp, '\0'); + result = process_entry (data, &dir, runp, endp - runp); + if (result != 0) + break; - result = process_entry (data, &dir, runp, endp - runp); - if (result != 0) - break; - - runp = endp + 1; - } + runp = endp + 1; + } save_err = errno; free (dir.content); --- libc/io/ftwtest.c.jj Fri Sep 19 18:57:36 1997 +++ libc/io/ftwtest.c Thu Dec 14 13:56:26 2000 @@ -10,12 +10,14 @@ int do_depth; int do_chdir; int do_phys; +int do_exit; struct option options[] = { { "depth", no_argument, &do_depth, 1 }, { "chdir", no_argument, &do_chdir, 1 }, { "phys", no_argument, &do_phys, 1 }, + { "early-exit", no_argument, &do_exit, 1 }, { NULL, 0, NULL, 0 } }; @@ -34,6 +36,9 @@ const char *flag2name[] = int cb (const char *name, const struct stat *st, int flag, struct FTW *f) { + if (do_exit && strcmp (name + f->base, "file@2")) + return 0; + printf ("base = \"%.*s\", file = \"%s\", flag = %s", f->base, name, name + f->base, flag2name[flag]); if (do_chdir) @@ -43,7 +48,7 @@ cb (const char *name, const struct stat free (cwd); } printf (", level = %d\n", f->level); - return 0; + return do_exit ? 26 : 0; } int @@ -64,8 +69,13 @@ main (int argc, char *argv[]) if (do_phys) flag |= FTW_PHYS; - r = nftw (optind < argc ? argv[optind] : ".", cb, 3, flag); - if (r) + r = nftw (optind < argc ? argv[optind] : ".", cb, do_exit ? 1 : 3, flag); + if (r < 0) perror ("nftw"); + if (do_exit) + { + puts (r == 26 ? "succeeded" : "failed"); + return r == 26 ? 0 : 1; + } return r; } --- libc/io/ftwtest-sh.jj Thu Jul 27 15:58:52 2000 +++ libc/io/ftwtest-sh Thu Dec 14 13:58:47 2000 @@ -5,10 +5,12 @@ objpfx=$1 # We expect one parameter which is the test program. This must understand # a number options: -# --phys use the FTW_PHYS flag -# --chdir use the FTW_CHDIR and print the current directory in the -# callback -# --depth use the FTW_DEPTH flag +# --phys use the FTW_PHYS flag +# --chdir use the FTW_CHDIR and print the current directory +# in the callback +# --depth use the FTW_DEPTH flag +# --early-exit print file@2 item only and return non-zero from the +# callback when it is seen testprogram=$2 # We cannot test this as root. @@ -133,6 +135,15 @@ base = "$tmp/ftwtest.d/foo/lvl1/", file base = "$tmp/ftwtest.d/foo/lvl1/lvl2/", file = "file@2", flag = FTW_F, cwd = $tmpreal/ftwtest.d/foo/lvl1/lvl2, level = 4 base = "$tmp/ftwtest.d/foo/lvl1/lvl2/", file = "lvl3", flag = FTW_D, cwd = $tmpreal/ftwtest.d/foo/lvl1/lvl2, level = 4 base = "$tmp/ftwtest.d/foo/lvl1/lvl2/lvl3/", file = "file@3", flag = FTW_F, cwd = $tmpreal/ftwtest.d/foo/lvl1/lvl2/lvl3, level = 5 +EOF +rm $testout + +LD_LIBRARY_PATH=$objpfx $ldso $testprogram --early-exit $tmpdir | + sort > $testout + +cat <<EOF | cmp $testout - || exit 1 +base = "$tmp/ftwtest.d/foo/lvl1/lvl2/", file = "file@2", flag = FTW_F, level = 4 +succeeded EOF rm $testout Jakub
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |