Source-Changes-HG archive

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

[src/trunk]: src/lib/libc/gen - Use O_DIRECTORY to open the file, so that we ...



details:   https://anonhg.NetBSD.org/src/rev/372097369b32
branches:  trunk
changeset: 804161:372097369b32
user:      christos <christos%NetBSD.org@localhost>
date:      Wed Nov 26 16:48:43 2014 +0000

description:
- Use O_DIRECTORY to open the file, so that we don't need to stat() after
  that.
- Move the stat() call to fdopendir() and change it's error handling so that
  it does not hide errors.
- According to POSIX, fdopendir() transfers ownership of the fd only on
  success, so don't close it on failure. XXX: We still make it non-blocking
  on failure, but that's nitpicking.

XXX: pullup-7?

diffstat:

 lib/libc/gen/opendir.c |  36 ++++++++++++++++++++++++------------
 1 files changed, 24 insertions(+), 12 deletions(-)

diffs (84 lines):

diff -r 559d6b9bfc12 -r 372097369b32 lib/libc/gen/opendir.c
--- a/lib/libc/gen/opendir.c    Wed Nov 26 16:05:51 2014 +0000
+++ b/lib/libc/gen/opendir.c    Wed Nov 26 16:48:43 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: opendir.c,v 1.38 2011/10/15 23:00:01 christos Exp $    */
+/*     $NetBSD: opendir.c,v 1.39 2014/11/26 16:48:43 christos Exp $    */
 
 /*
  * Copyright (c) 1983, 1993
@@ -34,7 +34,7 @@
 #if 0
 static char sccsid[] = "@(#)opendir.c  8.7 (Berkeley) 12/10/94";
 #else
-__RCSID("$NetBSD: opendir.c,v 1.38 2011/10/15 23:00:01 christos Exp $");
+__RCSID("$NetBSD: opendir.c,v 1.39 2014/11/26 16:48:43 christos Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -75,17 +75,36 @@
 DIR *
 __opendir2(const char *name, int flags)
 {
+       DIR *dirp;
        int fd;
 
-       if ((fd = open(name, O_RDONLY | O_NONBLOCK | O_CLOEXEC)) == -1)
+       if ((fd = open(name, O_RDONLY|O_DIRECTORY|O_NONBLOCK|O_CLOEXEC)) == -1)
                return NULL;
-       return __opendir_common(fd, name, flags);
+
+       dirp = __opendir_common(fd, name, flags);
+       if (dirp == NULL) {
+               int serrno = errno;
+               (void)close(fd);
+               errno = serrno;
+       }
+       return dirp;
 }
 
 #ifndef __LIBC12_SOURCE__
 DIR *
 _fdopendir(int fd)
 {
+       struct stat sb;
+
+       if (fstat(fd, &sb) == -1)
+               return NULL;
+
+       if (!S_ISDIR(sb.st_mode)) {
+               errno = ENOTDIR;
+               return NULL;
+       }
+
+       /* This is optional according to POSIX, but a good measure */
        if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
                return NULL;
 
@@ -96,16 +115,11 @@
 static DIR *
 __opendir_common(int fd, const char *name, int flags)
 {
-       DIR *dirp = NULL;
+       DIR *dirp;
        int serrno;
-       struct stat sb;
        struct statvfs sfb;
        int error;
 
-       if (fstat(fd, &sb) || !S_ISDIR(sb.st_mode)) {
-               errno = ENOTDIR;
-               goto error;
-       }
        if ((dirp = malloc(sizeof(*dirp))) == NULL)
                goto error;
        dirp->dd_buf = NULL;
@@ -157,8 +171,6 @@
                free(dirp->dd_buf);
        }
        free(dirp);
-       if (fd != -1)
-               (void)close(fd);
        errno = serrno;
        return NULL;
 }



Home | Main Index | Thread Index | Old Index