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] |
Other format: | [Raw text] |
Hi! The following testcase shows ftw leaking filedescriptors (one per call) and the attached patch seems to fix it. 2003-11-04 Jakub Jelinek <jakub@redhat.com> * io/ftw.c (ftw_dir): Close dir if callback with FTW_D type returns non-zero. * io/Makefile (tests): Add bug-ftw4. * io/bug-ftw4.c: New test. --- libc/io/Makefile.jj 2003-10-29 00:18:42.000000000 +0100 +++ libc/io/Makefile 2003-11-04 19:40:10.000000000 +0100 @@ -57,7 +57,7 @@ static-only-routines = stat fstat lstat others := pwd test-srcs := ftwtest tests := test-utime test-stat test-stat2 test-lfs tst-getcwd \ - tst-fcntl bug-ftw1 bug-ftw2 bug-ftw3 tst-statvfs + tst-fcntl bug-ftw1 bug-ftw2 bug-ftw3 bug-ftw4 tst-statvfs distribute := ftwtest-sh --- libc/io/ftw.c.jj 2003-06-11 23:48:58.000000000 +0200 +++ libc/io/ftw.c 2003-11-04 19:57:42.000000000 +0100 @@ -476,23 +476,27 @@ ftw_dir (struct ftw_data *data, struct S { result = (*data->func) (data->dirbuf, st, FTW_D, &data->ftw); if (result != 0) - return result; - } - - /* If necessary, change to this directory. */ - if (data->flags & FTW_CHDIR) - { - if (__fchdir (dirfd (dir.stream)) < 0) { - int save_err = errno; + int save_err; +fail: + save_err = errno; __closedir (dir.stream); __set_errno (save_err); if (data->actdir-- == 0) data->actdir = data->maxdir - 1; data->dirstreams[data->actdir] = NULL; + return result; + } + } - return -1; + /* If necessary, change to this directory. */ + if (data->flags & FTW_CHDIR) + { + if (__fchdir (dirfd (dir.stream)) < 0) + { + result = -1; + goto fail; } } --- libc/io/bug-ftw4.c.jj 2003-11-04 19:39:53.000000000 +0100 +++ libc/io/bug-ftw4.c 2003-11-04 19:43:57.000000000 +0100 @@ -0,0 +1,124 @@ +/* Test if ftw function doesn't leak fds. + Copyright (C) 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek <jakub@redhat.com>, 2003. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <fcntl.h> +#include <ftw.h> +#include <stdlib.h> +#include <stdio.h> +#include <sys/stat.h> +#include <unistd.h> + +static int cb_called; + +static int +cb (const char *name, const struct stat64 *st, int type) +{ + return cb_called++ & 1; +} + +int +main (void) +{ + char name[32] = "/tmp/ftwXXXXXX", *p; + int ret, i, result = 0, fd, fd1, fd2; + + if (mkdtemp (name) == NULL) + { + printf ("Couldn't make temporary directory: %m\n"); + exit (EXIT_FAILURE); + } + p = strchr (name, '\0'); + strcpy (p, "/1"); + if (mkdir (name, 0755) < 0) + { + printf ("Couldn't make temporary subdirectory: %m\n"); + exit (EXIT_FAILURE); + } + *p = '\0'; + + ret = ftw64 (name, cb, 20); + if (ret != 1) + { + printf ("ftw64 returned %d instead of 1", ret); + result = 1; + } + + fd = open (name, O_RDONLY); + if (fd < 0) + { + printf ("open failed: %m\n"); + result = 1; + } + fd1 = open (name, O_RDONLY); + if (fd1 < 0) + { + printf ("open failed: %m\n"); + result = 1; + } + else + close (fd1); + if (fd >= 0) + close (fd); + + for (i = 0; i < 128; ++i) + { + ret = ftw64 (name, cb, 20); + if (ret != 1) + { + printf ("ftw64 returned %d instead of 1", ret); + result = 1; + } + } + + fd = open (name, O_RDONLY); + if (fd < 0) + { + printf ("open failed: %m\n"); + result = 1; + } + fd2 = open (name, O_RDONLY); + if (fd2 < 0) + { + printf ("open failed: %m\n"); + result = 1; + } + else + close (fd2); + if (fd >= 0) + close (fd); + + if (fd2 >= fd1 + 128) + { + printf ("ftw64 leaking fds: %d -> %d\n", fd1, fd2); + result = 1; + } + + if (cb_called != 129 * 2) + { + printf ("callback called %d times\n", cb_called); + result = 1; + } + + strcpy (p, "/1"); + rmdir (name); + *p = '\0'; + rmdir (name); + return result; +} Jakub
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |