libc: Change dirfd() into a function (needed per POSIX).
authorSascha Wildner <saw@online.de>
Sat, 24 Jan 2015 13:15:08 +0000 (14:15 +0100)
committerSascha Wildner <saw@online.de>
Sat, 24 Jan 2015 13:15:08 +0000 (14:15 +0100)
At the same time, make struct _dirdesc private to libc. If access
to dd_fd is needed, dirfd() has to be used. Inside libc, the former
dirfd() macro is preserved as _dirfd().

Also, in struct _dirdesc, change the lock from "void *" to
"struct pthread_mutex *". This allows us to eliminate some casts
in readdir() and friends.

Our documentation already describes dirfd() as a function.

Based-on: FreeBSD's similar work

12 files changed:
include/dirent.h
lib/libc/gen/Makefile.inc
lib/libc/gen/Symbol.map
lib/libc/gen/closedir.c
lib/libc/gen/dirfd.c [copied from lib/libc/gen/rewinddir.c with 53% similarity]
lib/libc/gen/gen_private.h [copied from lib/libc/gen/seekdir.c with 60% similarity]
lib/libc/gen/opendir.c
lib/libc/gen/readdir.c
lib/libc/gen/rewinddir.c
lib/libc/gen/scandir.c
lib/libc/gen/seekdir.c
lib/libc/gen/telldir.c

index 67b1b9c..fc308f0 100644 (file)
@@ -50,21 +50,8 @@ typedef void *       DIR;
 /* definitions for library routines operating on directories. */
 #define        DIRBLKSIZ       1024
 
-/* structure describing an open directory. */
-typedef struct _dirdesc {
-       int     dd_fd;          /* file descriptor associated with directory */
-       long    dd_loc;         /* offset in current buffer */
-       long    dd_size;        /* amount of data returned by getdirentries */
-       char    *dd_buf;        /* data buffer */
-       int     dd_len;         /* size of data buffer */
-       long    dd_lastseek;    /* last seek index */
-       long    dd_rewind;      /* magic cookie for rewinding */
-       int     dd_flags;       /* flags for readdir */
-       void    *dd_lock;       /* hack to avoid include <pthread.h> */
-       off_t   dd_seek;        /* new magic cookie returned by getdirentries */
-} DIR;
-
-#define        dirfd(dirp)     ((dirp)->dd_fd)
+struct _dirdesc;
+typedef struct _dirdesc        DIR;
 
 /* flags for opendir2 */
 #define        DTF_HIDEW       0x0001  /* hide whiteout entries */
@@ -90,6 +77,7 @@ void   rewinddir(DIR *);
 int     closedir(DIR *);
 #if __POSIX_VISIBLE >= 200809 || __XSI_VISIBLE >= 700 || !defined(_POSIX_SOURCE)
 int     alphasort(const struct dirent **, const struct dirent **);
+int     dirfd(DIR *);
 int     scandir(const char *, struct dirent ***,
            int (*)(const struct dirent *),
            int (*)(const struct dirent **, const struct dirent **));
index b40c13a..49a2d0b 100644 (file)
@@ -11,7 +11,7 @@ CMAPS+=       ${.CURDIR}/gen/Symbol.map
 SRCS+=  _once_stub.c _pthread_stubs.c _rand48.c _spinlock_stub.c \
        _thread_init.c alarm.c arc4random.c assert.c basename.c \
        clock.c closedir.c confstr.c \
-       ctermid.c daemon.c devname.c dirname.c disklabel.c disktab.c \
+       ctermid.c daemon.c devname.c dirfd.c dirname.c disklabel.c disktab.c \
        dlfcn.c drand48.c elf_utils.c erand48.c err.c errlst.c exec.c \
        fdevname.c fmtcheck.c fmtmsg.c fnmatch.c fpclassify.c \
        frexp.c fstab.c ftok.c fts.c ftw.c getbootfile.c getbsize.c \
index dcd6152..6f702ec 100644 (file)
@@ -48,6 +48,7 @@ DF402.0 {
     daemon;
     devname;
     devname_r;
+    dirfd;
     dirname;
     dl_iterate_phdr;
     dladdr;
index 40f862e..abfac3c 100644 (file)
@@ -31,7 +31,6 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/lib/libc/gen/closedir.c,v 1.6.2.1 2001/03/05 08:29:56 obrien Exp $
- * $DragonFly: src/lib/libc/gen/closedir.c,v 1.5 2005/04/26 15:04:59 joerg Exp $
  *
  * @(#)closedir.c      8.1 (Berkeley) 6/10/93
  */
@@ -44,6 +43,7 @@
 #include "un-namespace.h"
 
 #include "libc_private.h"
+#include "gen_private.h"
 
 /*
  * close a directory.
@@ -54,7 +54,7 @@ closedir(DIR *dirp)
        int fd;
 
        if (__isthreaded)
-               _pthread_mutex_lock((pthread_mutex_t *)&dirp->dd_lock);
+               _pthread_mutex_lock(&dirp->dd_lock);
        _seekdir(dirp, dirp->dd_rewind);        /* free seekdir storage */
        fd = dirp->dd_fd;
        dirp->dd_fd = -1;
@@ -62,8 +62,8 @@ closedir(DIR *dirp)
        free(dirp->dd_buf);
        _reclaim_telldir(dirp);
        if (__isthreaded) {
-               _pthread_mutex_unlock((pthread_mutex_t *)&dirp->dd_lock);
-               _pthread_mutex_destroy((pthread_mutex_t *)&dirp->dd_lock);
+               _pthread_mutex_unlock(&dirp->dd_lock);
+               _pthread_mutex_destroy(&dirp->dd_lock);
        }
        free(dirp);
        return(_close(fd));
similarity index 53%
copy from lib/libc/gen/rewinddir.c
copy to lib/libc/gen/dirfd.c
index 23e017e..2a993ac 100644 (file)
@@ -1,6 +1,6 @@
 /*-
- * Copyright (c) 1990, 1993
- *     The Regents of the University of California.  All rights reserved.
+ * Copyright (c) 2011 Gleb Kurtsou <gleb@FreeBSD.org>
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libc/gen/rewinddir.c,v 1.2.8.1 2001/03/05 09:52:13 obrien Exp $
- * $DragonFly: src/lib/libc/gen/rewinddir.c,v 1.5 2008/04/22 21:29:42 dillon Exp $
- *
- * @(#)rewinddir.c     8.1 (Berkeley) 6/8/93
+ * $FreeBSD: head/lib/libc/gen/dirfd.c 235649 2012-05-19 14:30:49Z gleb $
  */
 
+#include "namespace.h"
+#include <sys/param.h>
+
 #include <dirent.h>
+#include "un-namespace.h"
 
-void
-rewinddir(DIR *dirp)
+#include "gen_private.h"
+
+int
+dirfd(DIR *dirp)
 {
-       _seekdir(dirp, dirp->dd_rewind);
-       _reclaim_telldir(dirp);
-       dirp->dd_rewind = telldir(dirp);
+
+       return (_dirfd(dirp));
 }
similarity index 60%
copy from lib/libc/gen/seekdir.c
copy to lib/libc/gen/gen_private.h
index 7f947db..933743a 100644 (file)
@@ -1,5 +1,5 @@
-/*
- * Copyright (c) 1983, 1993
+/*-
+ * Copyright (c) 1989, 1993
  *     The Regents of the University of California.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libc/gen/seekdir.c,v 1.2.8.1 2001/03/05 09:52:13 obrien Exp $
- *
- * @(#)seekdir.c       8.1 (Berkeley) 6/4/93
+ * $FreeBSD: head/lib/libc/gen/gen-private.h 268531 2014-07-11 16:16:26Z jhb $
  */
 
-#include "namespace.h"
-#include <sys/param.h>
-#include <dirent.h>
-#include <pthread.h>
-#include "un-namespace.h"
+#ifndef _GEN_PRIVATE_H_
+#define        _GEN_PRIVATE_H_
 
-#include "libc_private.h"
+struct pthread_mutex;
 
 /*
- * Seek to an entry in a directory.
- * _seekdir is in telldir.c so that it can share opaque data structures.
+ * Structure describing an open directory.
+ *
+ * NOTE. Change structure layout with care, at least dd_fd field has to
+ * remain unchanged to guarantee backward compatibility.
  */
-void
-seekdir(DIR *dirp, long loc)
-{
-       if (__isthreaded)
-               _pthread_mutex_lock((pthread_mutex_t *)&dirp->dd_lock);
-       _seekdir(dirp, loc);
-       if (__isthreaded)
-               _pthread_mutex_unlock((pthread_mutex_t *)&dirp->dd_lock);
-}
+struct _dirdesc {
+       int     dd_fd;          /* file descriptor associated with directory */
+       long    dd_loc;         /* offset in current buffer */
+       long    dd_size;        /* amount of data returned by getdirentries */
+       char    *dd_buf;        /* data buffer */
+       int     dd_len;         /* size of data buffer */
+       long    dd_lastseek;    /* last seek index */
+       long    dd_rewind;      /* magic cookie for rewinding */
+       int     dd_flags;       /* flags for readdir */
+       struct pthread_mutex    *dd_lock;       /* lock */
+       off_t   dd_seek;        /* new magic cookie returned by getdirentries */
+};
+
+#define        _dirfd(dirp)    ((dirp)->dd_fd)
+
+#endif /* !_GEN_PRIVATE_H_ */
index 888fd52..557a7ce 100644 (file)
@@ -47,6 +47,7 @@
 #include <unistd.h>
 #include "un-namespace.h"
 
+#include "gen_private.h"
 
 #define DEFAULT_FLAGS (DTF_HIDEW | DTF_NODUP)
 
index abf5e12..e4b69c8 100644 (file)
@@ -31,7 +31,6 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/lib/libc/gen/readdir.c,v 1.5.2.4 2002/02/26 22:53:57 alfred Exp $
- * $DragonFly: src/lib/libc/gen/readdir.c,v 1.10 2008/05/03 22:07:37 dillon Exp $
  *
  * @(#)readdir.c       8.3 (Berkeley) 9/29/94
  */
@@ -46,6 +45,7 @@
 #include "un-namespace.h"
 
 #include "libc_private.h"
+#include "gen_private.h"
 
 /*
  * get next entry in a directory.
@@ -90,10 +90,10 @@ readdir(DIR *dirp)
        struct dirent   *dp;
 
        if (__isthreaded)
-               _pthread_mutex_lock((pthread_mutex_t *)&dirp->dd_lock);
+               _pthread_mutex_lock(&dirp->dd_lock);
        dp = _readdir_unlocked(dirp, 1);
        if (__isthreaded)
-               _pthread_mutex_unlock((pthread_mutex_t *)&dirp->dd_lock);
+               _pthread_mutex_unlock(&dirp->dd_lock);
 
        return (dp);
 }
@@ -107,11 +107,11 @@ readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result)
        saved_errno = errno;
        errno = 0;
        if (__isthreaded)
-               _pthread_mutex_lock((pthread_mutex_t *)&dirp->dd_lock);
+               _pthread_mutex_lock(&dirp->dd_lock);
        if ((dp = _readdir_unlocked(dirp, 1)) != NULL)
                memcpy(entry, dp, _DIRENT_MINSIZ(dp));
        if (__isthreaded)
-               _pthread_mutex_unlock((pthread_mutex_t *)&dirp->dd_lock);
+               _pthread_mutex_unlock(&dirp->dd_lock);
 
        if (errno != 0) {
                if (dp == NULL) {
index 23e017e..53d4d0b 100644 (file)
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/lib/libc/gen/rewinddir.c,v 1.2.8.1 2001/03/05 09:52:13 obrien Exp $
- * $DragonFly: src/lib/libc/gen/rewinddir.c,v 1.5 2008/04/22 21:29:42 dillon Exp $
  *
  * @(#)rewinddir.c     8.1 (Berkeley) 6/8/93
  */
 
 #include <dirent.h>
 
+#include "gen_private.h"
+
 void
 rewinddir(DIR *dirp)
 {
index 534d1f3..f8b5e50 100644 (file)
@@ -51,6 +51,8 @@
 #include <string.h>
 #include "un-namespace.h"
 
+#include "gen_private.h"
+
 int
 scandir(const char *dirname, struct dirent ***namelist,
        int (*select)(const struct dirent *),
index 7f947db..ffdbc46 100644 (file)
@@ -42,6 +42,7 @@
 #include "un-namespace.h"
 
 #include "libc_private.h"
+#include "gen_private.h"
 
 /*
  * Seek to an entry in a directory.
@@ -51,8 +52,8 @@ void
 seekdir(DIR *dirp, long loc)
 {
        if (__isthreaded)
-               _pthread_mutex_lock((pthread_mutex_t *)&dirp->dd_lock);
+               _pthread_mutex_lock(&dirp->dd_lock);
        _seekdir(dirp, loc);
        if (__isthreaded)
-               _pthread_mutex_unlock((pthread_mutex_t *)&dirp->dd_lock);
+               _pthread_mutex_unlock(&dirp->dd_lock);
 }
index 5bf8a78..62835cb 100644 (file)
@@ -31,7 +31,6 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/lib/libc/gen/telldir.c,v 1.4.12.1 2001/03/05 09:39:59 obrien Exp $
- * $DragonFly: src/lib/libc/gen/telldir.c,v 1.7 2008/05/03 22:07:37 dillon Exp $
  *
  * @(#)telldir.c       8.1 (Berkeley) 6/4/93
  */
@@ -45,6 +44,7 @@
 #include "un-namespace.h"
 
 #include "libc_private.h"
+#include "gen_private.h"
 
 /*
  * One of these structures is malloced to describe the current directory
@@ -77,7 +77,7 @@ telldir(DIR *dirp)
        struct ddloc *lp;
 
        if (__isthreaded) {
-               _pthread_mutex_lock((pthread_mutex_t *)&dirp->dd_lock);
+               _pthread_mutex_lock(&dirp->dd_lock);
                _pthread_mutex_lock(&dd_hash_lock);
        }
 
@@ -109,7 +109,7 @@ telldir(DIR *dirp)
 done:
        if (__isthreaded) {
                _pthread_mutex_unlock(&dd_hash_lock);
-               _pthread_mutex_unlock((pthread_mutex_t *)&dirp->dd_lock);
+               _pthread_mutex_unlock(&dirp->dd_lock);
        }
        return (index);
 }