64 bit inode changes

This commit is contained in:
christos 2005-08-19 02:04:54 +00:00
parent 50f8955b6e
commit 3303764533
20 changed files with 2242 additions and 1901 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: dirent.h,v 1.22 2005/02/03 04:39:32 perry Exp $ */
/* $NetBSD: dirent.h,v 1.23 2005/08/19 02:05:59 christos Exp $ */
/*-
* Copyright (c) 1989, 1993
@ -85,22 +85,46 @@ struct _dirdesc {
__BEGIN_DECLS
int closedir(DIR *);
DIR *opendir(const char *);
struct dirent *readdir(DIR *);
int readdir_r(DIR *, struct dirent * __restrict, struct dirent ** __restrict);
void rewinddir(DIR *);
#ifdef __LIBC12_SOURCE__
DIR *opendir(const char *);
struct dirent12 *readdir(DIR *);
int readdir_r(DIR *, struct dirent12 * __restrict,
struct dirent12 ** __restrict);
struct dirent *__readdir30(DIR *);
int __readdir_r30(DIR *, struct dirent * __restrict,
struct dirent ** __restrict);
#else
DIR *opendir(const char *) __RENAME(__opendir30);
DIR *__opendir30(const char *) __RENAME(__opendir30);
struct dirent *readdir(DIR *) __RENAME(__readdir30);
int readdir_r(DIR *, struct dirent * __restrict,
struct dirent ** __restrict) __RENAME(__readdir_r30);
#endif
#if defined(_XOPEN_SOURCE) || defined(_NETBSD_SOURCE)
void seekdir(DIR *, long);
long telldir(const DIR *);
#endif /* defined(_NETBSD_SOURCE) || defined(_XOPEN_SOURCE) */
#if defined(_NETBSD_SOURCE)
DIR *__opendir2(const char *, int);
void __seekdir(DIR *, long);
int scandir(const char *, struct dirent ***,
#ifdef __LIBC12_SOURCE__
DIR *__opendir2(const char *, int);
DIR *__opendir230(const char *, int);
int scandir(const char *, struct dirent12 ***,
int (*)(const struct dirent12 *), int (*)(const void *, const void *));
int __scandir30(const char *, struct dirent ***,
int (*)(const struct dirent *), int (*)(const void *, const void *));
int alphasort(const void *, const void *);
int getdirentries(int, char *, int, long *);
int getdents(int, char *, size_t);
int getdirentries(int, char *, int, long *);
int __getdents30(int, char *, size_t);
#else
DIR *__opendir2(const char *, int) __RENAME(__opendir230);
int scandir(const char *, struct dirent ***,
int (*)(const struct dirent *), int (*)(const void *, const void *))
__RENAME(__scandir30);
int getdents(int, char *, size_t) __RENAME(__getdents30);
#endif
int alphasort(const void *, const void *);
#endif /* defined(_NETBSD_SOURCE) */
__END_DECLS

View File

@ -1,4 +1,4 @@
/* $NetBSD: fts.h,v 1.12 2005/02/03 04:39:32 perry Exp $ */
/* $NetBSD: fts.h,v 1.13 2005/08/19 02:05:59 christos Exp $ */
/*
* Copyright (c) 1989, 1993
@ -34,6 +34,16 @@
#ifndef _FTS_H_
#define _FTS_H_
#ifndef __fts_stat_t
#define __fts_stat_t struct stat
#endif
#ifndef __fts_nlink_t
#define __fts_nlink_t nlink_t
#endif
#ifndef __fts_ino_t
#define __fts_ino_t ino_t
#endif
typedef struct {
struct _ftsent *fts_cur; /* current node */
struct _ftsent *fts_child; /* linked list of children */
@ -74,13 +84,9 @@ typedef struct _ftsent {
u_short fts_pathlen; /* strlen(fts_path) */
u_short fts_namelen; /* strlen(fts_name) */
ino_t fts_ino; /* inode */
__fts_ino_t fts_ino; /* inode */
dev_t fts_dev; /* device */
#ifdef __LIBC12_SOURCE__
u_int16_t fts_nlink; /* link count */
#else
nlink_t fts_nlink; /* link count */
#endif
__fts_nlink_t fts_nlink; /* link count */
#define FTS_ROOTPARENTLEVEL -1
#define FTS_ROOTLEVEL 0
@ -113,11 +119,7 @@ typedef struct _ftsent {
#define FTS_SKIP 4 /* discard node */
u_short fts_instr; /* fts_set() instructions */
#ifdef __LIBC12_SOURCE__
struct stat12 *fts_statp; /* stat(2) information */
#else
struct stat *fts_statp; /* stat(2) information */
#endif
__fts_stat_t *fts_statp; /* stat(2) information */
char fts_name[1]; /* file name */
} FTSENT;
@ -132,13 +134,13 @@ FTS *fts_open(char * const *, int,
FTSENT *fts_read(FTS *);
int fts_set(FTS *, FTSENT *, int);
#else
FTSENT *fts_children(FTS *, int) __RENAME(__fts_children13);
int fts_close(FTS *) __RENAME(__fts_close13);
FTSENT *fts_children(FTS *, int) __RENAME(__fts_children30);
int fts_close(FTS *) __RENAME(__fts_close30);
FTS *fts_open(char * const *, int,
int (*)(const FTSENT **, const FTSENT **))
__RENAME(__fts_open13);
FTSENT *fts_read(FTS *) __RENAME(__fts_read13);
int fts_set(FTS *, FTSENT *, int) __RENAME(__fts_set13);
__RENAME(__fts_open30);
FTSENT *fts_read(FTS *) __RENAME(__fts_read30);
int fts_set(FTS *, FTSENT *, int) __RENAME(__fts_set30);
#endif
__END_DECLS

View File

@ -1,15 +1,15 @@
# $NetBSD: Makefile.inc,v 1.143 2005/04/12 16:27:42 drochner Exp $
# $NetBSD: Makefile.inc,v 1.144 2005/08/19 02:04:54 christos Exp $
# from: @(#)Makefile.inc 8.6 (Berkeley) 5/4/95
# gen sources
.PATH: ${ARCHDIR}/gen ${.CURDIR}/gen
SRCS+= _errno.c alarm.c arc4random.c assert.c basename.c clock.c closedir.c \
closefrom.c confstr.c ctermid.c ctype_.c daemon.c devname.c dirname.c \
disklabel.c err.c errx.c __errlist14.c errlist.c errno.c execl.c \
execle.c execlp.c execv.c execvp.c extattr.c \
fmtcheck.c fmtmsg.c fnmatch.c \
fstab.c ftok.c __fts13.c fts.c getbsize.c getcap.c getcwd.c \
SRCS+= _errno.c alarm.c alphasort.c arc4random.c assert.c basename.c clock.c \
closedir.c closefrom.c confstr.c ctermid.c ctype_.c daemon.c \
devname.c dirname.c disklabel.c err.c errx.c __errlist14.c errlist.c \
errno.c execl.c execle.c execlp.c execv.c execvp.c extattr.c \
fmtcheck.c fmtmsg.c fnmatch.c fstab.c ftok.c __fts13.c __fts30.c \
fts.c getbsize.c getcap.c getcwd.c \
getdevmajor.c getdomainname.c getgrent.c \
getgrouplist.c getgroupmembership.c gethostname.c \
getloadavg.c getlogin.c getmntinfo.c __getmntinfo13.c \
@ -18,9 +18,9 @@ SRCS+= _errno.c alarm.c arc4random.c assert.c basename.c clock.c closedir.c \
getusershell.c __glob13.c glob.c humanize_number.c initgroups.c \
isascii.c isatty.c isctype.c lockf.c nice.c nlist.c nlist_aout.c \
nlist_coff.c nlist_ecoff.c nlist_elf32.c nlist_elf64.c opendir.c \
pause.c popen.c psignal.c pthread_atfork.c pwcache.c pw_scan.c \
raise.c randomid.c readdir.c rewinddir.c \
scandir.c seekdir.c setdomainname.c \
__opendir30.c pause.c popen.c psignal.c pthread_atfork.c pwcache.c \
pw_scan.c raise.c randomid.c readdir.c __readdir30.c rewinddir.c \
scandir.c __scandir30.c seekdir.c setdomainname.c \
sethostname.c setjmperr.c setmode.c setproctitle.c setprogname.c \
shquote.c shquotev.c sighold.c sigignore.c siginterrupt.c \
__siglist14.c siglist.c signal.c __signame14.c signame.c sigrelse.c \

File diff suppressed because it is too large Load Diff

1190
lib/libc/gen/__fts30.c Normal file

File diff suppressed because it is too large Load Diff

326
lib/libc/gen/__opendir30.c Normal file
View File

@ -0,0 +1,326 @@
/* $NetBSD: __opendir30.c,v 1.1 2005/08/19 02:04:54 christos Exp $ */
/*
* Copyright (c) 1983, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 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. 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
* 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
* 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)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)opendir.c 8.7 (Berkeley) 12/10/94";
#else
__RCSID("$NetBSD: __opendir30.c,v 1.1 2005/08/19 02:04:54 christos Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
#include "namespace.h"
#include "reentrant.h"
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <assert.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifdef __weak_alias
__weak_alias(opendir,_opendir)
#endif
#ifdef __LIBC12_SOURCE__
#define dirent dirent12
#endif
/*
* Open a directory.
*/
DIR *
opendir(name)
const char *name;
{
_DIAGASSERT(name != NULL);
return (__opendir2(name, DTF_HIDEW|DTF_NODUP));
}
DIR *
__opendir2(name, flags)
const char *name;
int flags;
{
DIR *dirp = NULL;
int fd;
int serrno;
struct stat sb;
int pagesz;
int incr;
int unionstack, nfsdir;
struct statvfs sfb;
_DIAGASSERT(name != NULL);
if ((fd = open(name, O_RDONLY | O_NONBLOCK)) == -1 ||
fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
goto error;
if (fstat(fd, &sb) || !S_ISDIR(sb.st_mode)) {
errno = ENOTDIR;
goto error;
}
if ((dirp = (DIR *)malloc(sizeof(DIR))) == NULL)
goto error;
dirp->dd_buf = NULL;
/*
* If the machine's page size is an exact multiple of DIRBLKSIZ,
* use a buffer that is cluster boundary aligned.
* Hopefully this can be a big win someday by allowing page trades
* to user space to be done by getdirentries()
*/
if (((pagesz = getpagesize()) % DIRBLKSIZ) == 0)
incr = pagesz;
else
incr = DIRBLKSIZ;
/*
* Determine whether this directory is the top of a union stack.
*/
if (fstatvfs1(fd, &sfb, ST_NOWAIT) < 0)
goto error;
if (flags & DTF_NODUP)
unionstack = !(strncmp(sfb.f_fstypename, MOUNT_UNION,
MFSNAMELEN)) || (sfb.f_flag & MNT_UNION);
else
unionstack = 0;
nfsdir = !(strncmp(sfb.f_fstypename, MOUNT_NFS, MFSNAMELEN));
if (unionstack || nfsdir) {
size_t len;
size_t space;
char *buf, *nbuf;
char *ddptr;
char *ddeptr;
int n;
struct dirent **dpv;
/*
* The strategy here for directories on top of a union stack
* is to read all the directory entries into a buffer, sort
* the buffer, and remove duplicate entries by setting the
* inode number to zero.
*
* For directories on an NFS mounted filesystem, we try
* to get a consistent snapshot by trying until we have
* successfully read all of the directory without errors
* (i.e. 'bad cookie' errors from the server because
* the directory was modified). These errors should not
* happen often, but need to be dealt with.
*/
retry:
len = 0;
space = 0;
buf = 0;
ddptr = 0;
do {
/*
* Always make at least DIRBLKSIZ bytes
* available to getdirentries
*/
if (space < DIRBLKSIZ) {
space += incr;
len += incr;
nbuf = realloc(buf, len);
if (nbuf == NULL) {
dirp->dd_buf = buf;
goto error;
}
buf = nbuf;
ddptr = buf + (len - space);
}
dirp->dd_seek = lseek(fd, (off_t)0, SEEK_CUR);
n = getdents(fd, ddptr, space);
/*
* For NFS: EINVAL means a bad cookie error
* from the server. Keep trying to get a
* consistent view, in this case this means
* starting all over again.
*/
if (n == -1 && errno == EINVAL && nfsdir) {
free(buf);
lseek(fd, (off_t)0, SEEK_SET);
goto retry;
}
if (n > 0) {
ddptr += n;
space -= n;
}
} while (n > 0);
ddeptr = ddptr;
flags |= __DTF_READALL;
/*
* Re-open the directory.
* This has the effect of rewinding back to the
* top of the union stack and is needed by
* programs which plan to fchdir to a descriptor
* which has also been read -- see fts.c.
*/
if (flags & DTF_REWIND) {
(void) close(fd);
if ((fd = open(name, O_RDONLY)) == -1 ||
fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
dirp->dd_buf = buf;
goto error;
}
}
/*
* There is now a buffer full of (possibly) duplicate
* names.
*/
dirp->dd_buf = buf;
/*
* Go round this loop twice...
*
* Scan through the buffer, counting entries.
* On the second pass, save pointers to each one.
* Then sort the pointers and remove duplicate names.
*/
if (!nfsdir) {
for (dpv = 0;;) {
for (n = 0, ddptr = buf; ddptr < ddeptr;) {
struct dirent *dp;
dp = (struct dirent *)(void *)ddptr;
if ((long)dp & _DIRENT_ALIGN(dp))
break;
/*
* d_reclen is unsigned,
* so no need to compare <= 0
*/
if (dp->d_reclen > (ddeptr + 1 - ddptr))
break;
ddptr += dp->d_reclen;
if (dp->d_fileno) {
if (dpv)
dpv[n] = dp;
n++;
}
}
if (dpv) {
struct dirent *xp;
/*
* This sort must be stable.
*/
mergesort(dpv, (size_t)n, sizeof(*dpv),
alphasort);
dpv[n] = NULL;
xp = NULL;
/*
* Scan through the buffer in sort
* order, zapping the inode number
* of any duplicate names.
*/
for (n = 0; dpv[n]; n++) {
struct dirent *dp = dpv[n];
if ((xp == NULL) ||
strcmp(dp->d_name,
xp->d_name))
xp = dp;
else
dp->d_fileno = 0;
if (dp->d_type == DT_WHT &&
(flags & DTF_HIDEW))
dp->d_fileno = 0;
}
free(dpv);
break;
} else {
dpv = malloc((n + 1) *
sizeof(struct dirent *));
if (dpv == NULL)
break;
}
}
}
dirp->dd_len = len;
dirp->dd_size = ddptr - dirp->dd_buf;
} else {
dirp->dd_len = incr;
dirp->dd_buf = malloc((size_t)dirp->dd_len);
if (dirp->dd_buf == NULL)
goto error;
dirp->dd_seek = 0;
flags &= ~DTF_REWIND;
}
dirp->dd_loc = 0;
dirp->dd_fd = fd;
dirp->dd_flags = flags;
/*
* Set up seek point for rewinddir.
*/
#ifdef _REENTRANT
if (__isthreaded) {
if ((dirp->dd_lock = malloc(sizeof(mutex_t))) == NULL)
goto error;
mutex_init((mutex_t *)dirp->dd_lock, NULL);
}
#endif
dirp->dd_rewind = telldir(dirp);
return (dirp);
error:
serrno = errno;
if (dirp && dirp->dd_buf)
free(dirp->dd_buf);
if (dirp)
free(dirp);
if (fd != -1)
(void)close(fd);
errno = serrno;
return NULL;
}

150
lib/libc/gen/__readdir30.c Normal file
View File

@ -0,0 +1,150 @@
/* $NetBSD: __readdir30.c,v 1.1 2005/08/19 02:04:54 christos Exp $ */
/*
* Copyright (c) 1983, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 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. 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
* 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
* 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)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)readdir.c 8.3 (Berkeley) 9/29/94";
#else
__RCSID("$NetBSD: __readdir30.c,v 1.1 2005/08/19 02:04:54 christos Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
#include "namespace.h"
#include "reentrant.h"
#include <sys/param.h>
#include <dirent.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#ifdef __weak_alias
__weak_alias(readdir,_readdir)
__weak_alias(readdir_r,_readdir_r)
#endif
#ifdef __LIBC12_SOURCE__
#define dirent dirent12
#endif
/*
* get next entry in a directory.
*/
static struct dirent *
_readdir_unlocked(DIR *dirp)
{
struct dirent *dp;
for (;;) {
if (dirp->dd_loc >= dirp->dd_size) {
if (dirp->dd_flags & __DTF_READALL)
return (NULL);
dirp->dd_loc = 0;
}
if (dirp->dd_loc == 0 && !(dirp->dd_flags & __DTF_READALL)) {
dirp->dd_seek = lseek(dirp->dd_fd, (off_t)0, SEEK_CUR);
dirp->dd_size = getdents(dirp->dd_fd,
dirp->dd_buf, (size_t)dirp->dd_len);
if (dirp->dd_size <= 0)
return (NULL);
}
dp = (struct dirent *)
(void *)(dirp->dd_buf + (size_t)dirp->dd_loc);
if ((intptr_t)dp & _DIRENT_ALIGN(dp))/* bogus pointer check */
return (NULL);
/* d_reclen is unsigned; no need to compare it <= 0 */
if (dp->d_reclen > dirp->dd_len + 1 - dirp->dd_loc)
return (NULL);
dirp->dd_loc += dp->d_reclen;
if (dp->d_ino == 0)
continue;
if (dp->d_type == DT_WHT && (dirp->dd_flags & DTF_HIDEW))
continue;
return (dp);
}
}
struct dirent *
readdir(dirp)
DIR *dirp;
{
struct dirent *dp;
#ifdef _REENTRANT
if (__isthreaded) {
mutex_lock((mutex_t *)dirp->dd_lock);
dp = _readdir_unlocked(dirp);
mutex_unlock((mutex_t *)dirp->dd_lock);
}
else
#endif
dp = _readdir_unlocked(dirp);
return (dp);
}
int
readdir_r(dirp, entry, result)
DIR *dirp;
struct dirent *entry;
struct dirent **result;
{
struct dirent *dp;
int saved_errno;
saved_errno = errno;
errno = 0;
#ifdef _REENTRANT
if (__isthreaded) {
mutex_lock((mutex_t *)dirp->dd_lock);
if ((dp = _readdir_unlocked(dirp)) != NULL)
memcpy(entry, dp, (size_t)_DIRENT_SIZE(dp));
mutex_unlock((mutex_t *)dirp->dd_lock);
}
else
#endif
if ((dp = _readdir_unlocked(dirp)) != NULL)
memcpy(entry, dp, (size_t)_DIRENT_SIZE(dp));
if (errno != 0) {
if (dp == NULL)
return (errno);
} else
errno = saved_errno;
if (dp != NULL)
*result = entry;
else
*result = NULL;
return (0);
}

141
lib/libc/gen/__scandir30.c Normal file
View File

@ -0,0 +1,141 @@
/* $NetBSD: __scandir30.c,v 1.1 2005/08/19 02:04:54 christos Exp $ */
/*
* Copyright (c) 1983, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 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. 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
* 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
* 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)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)scandir.c 8.3 (Berkeley) 1/2/94";
#else
__RCSID("$NetBSD: __scandir30.c,v 1.1 2005/08/19 02:04:54 christos Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
/*
* Scan the directory dirname calling selectfn to make a list of selected
* directory entries then sort using qsort and compare routine dcomp.
* Returns the number of entries and a pointer to a list of pointers to
* struct dirent (through namelist). Returns -1 if there were any errors.
*/
#include "namespace.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <assert.h>
#include <errno.h>
#include <dirent.h>
#include <stdlib.h>
#include <string.h>
#ifdef __weak_alias
__weak_alias(scandir,_scandir)
#endif
#ifdef __LIBC12_SOURCE__
#define dirent dirent12
#endif
int
scandir(dirname, namelist, selectfn, dcomp)
const char *dirname;
struct dirent ***namelist;
int (*selectfn) __P((const struct dirent *));
int (*dcomp) __P((const void *, const void *));
{
struct dirent *d, *p, **names, **newnames;
size_t nitems, arraysz;
struct stat stb;
DIR *dirp;
_DIAGASSERT(dirname != NULL);
_DIAGASSERT(namelist != NULL);
if ((dirp = opendir(dirname)) == NULL)
return (-1);
if (fstat(dirp->dd_fd, &stb) < 0)
goto bad;
/*
* estimate the array size by taking the size of the directory file
* and dividing it by a multiple of the minimum size entry.
*/
arraysz = (size_t)(stb.st_size / 24);
names = malloc(arraysz * sizeof(struct dirent *));
if (names == NULL)
goto bad;
nitems = 0;
while ((d = readdir(dirp)) != NULL) {
if (selectfn != NULL && !(*selectfn)(d))
continue; /* just selected names */
/*
* Check to make sure the array has space left and
* realloc the maximum size.
*/
if (nitems >= arraysz) {
if (fstat(dirp->dd_fd, &stb) < 0)
goto bad2; /* just might have grown */
arraysz = (size_t)(stb.st_size / 12);
newnames = realloc(names,
arraysz * sizeof(struct dirent *));
if (newnames == NULL)
goto bad2;
names = newnames;
}
/*
* Make a minimum size copy of the data
*/
p = (struct dirent *)malloc((size_t)_DIRENT_SIZE(d));
if (p == NULL)
goto bad2;
p->d_fileno = d->d_fileno;
p->d_reclen = d->d_reclen;
p->d_type = d->d_type;
p->d_namlen = d->d_namlen;
memmove(p->d_name, d->d_name, (size_t)(p->d_namlen + 1));
names[nitems++] = p;
}
closedir(dirp);
if (nitems && dcomp != NULL)
qsort(names, nitems, sizeof(struct dirent *), dcomp);
*namelist = names;
return (nitems);
bad2:
while (nitems-- > 0)
free(names[nitems]);
free(names);
bad:
closedir(dirp);
return (-1);
}

63
lib/libc/gen/alphasort.c Normal file
View File

@ -0,0 +1,63 @@
/* $NetBSD: alphasort.c,v 1.1 2005/08/19 02:04:54 christos Exp $ */
/*
* Copyright (c) 1983, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 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. 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
* 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
* 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)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)scandir.c 8.3 (Berkeley) 1/2/94";
#else
__RCSID("$NetBSD: alphasort.c,v 1.1 2005/08/19 02:04:54 christos Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
#include "namespace.h"
#include <assert.h>
#include <dirent.h>
#include <string.h>
#ifdef __weak_alias
__weak_alias(alphasort,_alphasort)
#endif
/*
* Alphabetic order comparison routine for those who want it.
*/
int
alphasort(const void *d1, const void *d2)
{
_DIAGASSERT(d1 != NULL);
_DIAGASSERT(d2 != NULL);
return (strcmp((*(const struct dirent *const *)d1)->d_name,
(*(const struct dirent *const *)d2)->d_name));
}

View File

@ -1,10 +1,42 @@
/* $NetBSD: fts.c,v 1.23 2003/12/04 23:39:18 keihan Exp $ */
/* $NetBSD: fts.c,v 1.24 2005/08/19 02:04:54 christos Exp $ */
/*
* Written by Jason R. Thorpe <thorpej@NetBSD.org>, October 21, 1997.
* Public domain.
*/
#include "namespace.h"
#include <sys/cdefs.h>
#include <dirent.h>
#define __LIBC12_SOURCE__
#include "__fts13.c"
#define __fts_stat_t struct stat12
#define __fts_nlink_t u_int16_t
#define __fts_ino_t u_int32_t
#ifdef __weak_alias
__weak_alias(fts_children,_fts_children)
__weak_alias(fts_close,_fts_close)
__weak_alias(fts_open,_fts_open)
__weak_alias(fts_read,_fts_read)
__weak_alias(fts_set,_fts_set)
#endif /* __weak_alias */
__warn_references(fts_children,
"warning: reference to compatibility fts_children();"
" include <fts.h> for correct reference")
__warn_references(fts_close,
"warning: reference to compatibility fts_close();"
" include <fts.h> for correct reference")
__warn_references(fts_open,
"warning: reference to compatibility fts_open();"
" include <fts.h> for correct reference")
__warn_references(fts_read,
"warning: reference to compatibility fts_read();"
" include <fts.h> for correct reference")
__warn_references(fts_set,
"warning: reference to compatibility fts_set();"
" include <fts.h> for correct reference")
#include "__fts30.c"

View File

@ -1,322 +1,9 @@
/* $NetBSD: opendir.c,v 1.26 2005/01/19 00:53:33 mycroft Exp $ */
/*
* Copyright (c) 1983, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 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. 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
* 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
* 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)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)opendir.c 8.7 (Berkeley) 12/10/94";
#else
__RCSID("$NetBSD: opendir.c,v 1.26 2005/01/19 00:53:33 mycroft Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
/* $NetBSD: opendir.c,v 1.27 2005/08/19 02:04:54 christos Exp $ */
#include "namespace.h"
#include "reentrant.h"
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <signal.h>
#include <assert.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define __LIBC12_SOURCE__
#ifdef __weak_alias
__weak_alias(opendir,_opendir)
#endif
/*
* Open a directory.
*/
DIR *
opendir(name)
const char *name;
{
_DIAGASSERT(name != NULL);
return (__opendir2(name, DTF_HIDEW|DTF_NODUP));
}
DIR *
__opendir2(name, flags)
const char *name;
int flags;
{
DIR *dirp = NULL;
int fd;
int serrno;
struct stat sb;
int pagesz;
int incr;
int unionstack, nfsdir;
struct statvfs sfb;
_DIAGASSERT(name != NULL);
if ((fd = open(name, O_RDONLY | O_NONBLOCK)) == -1 ||
fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
goto error;
if (fstat(fd, &sb) || !S_ISDIR(sb.st_mode)) {
errno = ENOTDIR;
goto error;
}
if ((dirp = (DIR *)malloc(sizeof(DIR))) == NULL)
goto error;
dirp->dd_buf = NULL;
/*
* If the machine's page size is an exact multiple of DIRBLKSIZ,
* use a buffer that is cluster boundary aligned.
* Hopefully this can be a big win someday by allowing page trades
* to user space to be done by getdirentries()
*/
if (((pagesz = getpagesize()) % DIRBLKSIZ) == 0)
incr = pagesz;
else
incr = DIRBLKSIZ;
/*
* Determine whether this directory is the top of a union stack.
*/
if (fstatvfs1(fd, &sfb, ST_NOWAIT) < 0)
goto error;
if (flags & DTF_NODUP)
unionstack = !(strncmp(sfb.f_fstypename, MOUNT_UNION,
MFSNAMELEN)) || (sfb.f_flag & MNT_UNION);
else
unionstack = 0;
nfsdir = !(strncmp(sfb.f_fstypename, MOUNT_NFS, MFSNAMELEN));
if (unionstack || nfsdir) {
size_t len;
size_t space;
char *buf, *nbuf;
char *ddptr;
char *ddeptr;
int n;
struct dirent **dpv;
/*
* The strategy here for directories on top of a union stack
* is to read all the directory entries into a buffer, sort
* the buffer, and remove duplicate entries by setting the
* inode number to zero.
*
* For directories on an NFS mounted filesystem, we try
* to get a consistent snapshot by trying until we have
* successfully read all of the directory without errors
* (i.e. 'bad cookie' errors from the server because
* the directory was modified). These errors should not
* happen often, but need to be dealt with.
*/
retry:
len = 0;
space = 0;
buf = 0;
ddptr = 0;
do {
/*
* Always make at least DIRBLKSIZ bytes
* available to getdirentries
*/
if (space < DIRBLKSIZ) {
space += incr;
len += incr;
nbuf = realloc(buf, len);
if (nbuf == NULL) {
dirp->dd_buf = buf;
goto error;
}
buf = nbuf;
ddptr = buf + (len - space);
}
dirp->dd_seek = lseek(fd, (off_t)0, SEEK_CUR);
n = getdents(fd, ddptr, space);
/*
* For NFS: EINVAL means a bad cookie error
* from the server. Keep trying to get a
* consistent view, in this case this means
* starting all over again.
*/
if (n == -1 && errno == EINVAL && nfsdir) {
free(buf);
lseek(fd, (off_t)0, SEEK_SET);
goto retry;
}
if (n > 0) {
ddptr += n;
space -= n;
}
} while (n > 0);
ddeptr = ddptr;
flags |= __DTF_READALL;
/*
* Re-open the directory.
* This has the effect of rewinding back to the
* top of the union stack and is needed by
* programs which plan to fchdir to a descriptor
* which has also been read -- see fts.c.
*/
if (flags & DTF_REWIND) {
(void) close(fd);
if ((fd = open(name, O_RDONLY)) == -1 ||
fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
dirp->dd_buf = buf;
goto error;
}
}
/*
* There is now a buffer full of (possibly) duplicate
* names.
*/
dirp->dd_buf = buf;
/*
* Go round this loop twice...
*
* Scan through the buffer, counting entries.
* On the second pass, save pointers to each one.
* Then sort the pointers and remove duplicate names.
*/
if (!nfsdir) {
for (dpv = 0;;) {
for (n = 0, ddptr = buf; ddptr < ddeptr;) {
struct dirent *dp;
dp = (struct dirent *)(void *)ddptr;
if ((long)dp & 03)
break;
/*
* d_reclen is unsigned,
* so no need to compare <= 0
*/
if (dp->d_reclen > (ddeptr + 1 - ddptr))
break;
ddptr += dp->d_reclen;
if (dp->d_fileno) {
if (dpv)
dpv[n] = dp;
n++;
}
}
if (dpv) {
struct dirent *xp;
/*
* This sort must be stable.
*/
mergesort(dpv, (size_t)n, sizeof(*dpv),
alphasort);
dpv[n] = NULL;
xp = NULL;
/*
* Scan through the buffer in sort
* order, zapping the inode number
* of any duplicate names.
*/
for (n = 0; dpv[n]; n++) {
struct dirent *dp = dpv[n];
if ((xp == NULL) ||
strcmp(dp->d_name,
xp->d_name))
xp = dp;
else
dp->d_fileno = 0;
if (dp->d_type == DT_WHT &&
(flags & DTF_HIDEW))
dp->d_fileno = 0;
}
free(dpv);
break;
} else {
dpv = malloc((n + 1) *
sizeof(struct dirent *));
if (dpv == NULL)
break;
}
}
}
dirp->dd_len = len;
dirp->dd_size = ddptr - dirp->dd_buf;
} else {
dirp->dd_len = incr;
dirp->dd_buf = malloc((size_t)dirp->dd_len);
if (dirp->dd_buf == NULL)
goto error;
dirp->dd_seek = 0;
flags &= ~DTF_REWIND;
}
dirp->dd_loc = 0;
dirp->dd_fd = fd;
dirp->dd_flags = flags;
/*
* Set up seek point for rewinddir.
*/
#ifdef _REENTRANT
if (__isthreaded) {
if ((dirp->dd_lock = malloc(sizeof(mutex_t))) == NULL)
goto error;
mutex_init((mutex_t *)dirp->dd_lock, NULL);
}
#endif
dirp->dd_rewind = telldir(dirp);
return (dirp);
error:
serrno = errno;
if (dirp && dirp->dd_buf)
free(dirp->dd_buf);
if (dirp)
free(dirp);
if (fd != -1)
(void)close(fd);
errno = serrno;
return NULL;
}
#include "__opendir30.c"

View File

@ -1,146 +1,5 @@
/* $NetBSD: readdir.c,v 1.18 2003/08/07 16:42:55 agc Exp $ */
/* $NetBSD: readdir.c,v 1.19 2005/08/19 02:04:54 christos Exp $ */
/*
* Copyright (c) 1983, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 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. 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
* 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
* 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)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#define __LIBC12_SOURCE__
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)readdir.c 8.3 (Berkeley) 9/29/94";
#else
__RCSID("$NetBSD: readdir.c,v 1.18 2003/08/07 16:42:55 agc Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
#include "namespace.h"
#include "reentrant.h"
#include <sys/param.h>
#include <dirent.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#ifdef __weak_alias
__weak_alias(readdir,_readdir)
__weak_alias(readdir_r,_readdir_r)
#endif
/*
* get next entry in a directory.
*/
static struct dirent *
_readdir_unlocked(DIR *dirp)
{
struct dirent *dp;
for (;;) {
if (dirp->dd_loc >= dirp->dd_size) {
if (dirp->dd_flags & __DTF_READALL)
return (NULL);
dirp->dd_loc = 0;
}
if (dirp->dd_loc == 0 && !(dirp->dd_flags & __DTF_READALL)) {
dirp->dd_seek = lseek(dirp->dd_fd, (off_t)0, SEEK_CUR);
dirp->dd_size = getdents(dirp->dd_fd,
dirp->dd_buf, (size_t)dirp->dd_len);
if (dirp->dd_size <= 0)
return (NULL);
}
dp = (struct dirent *)
(void *)(dirp->dd_buf + (size_t)dirp->dd_loc);
if ((long)dp & 03) /* bogus pointer check */
return (NULL);
/* d_reclen is unsigned; no need to compare it <= 0 */
if (dp->d_reclen > dirp->dd_len + 1 - dirp->dd_loc)
return (NULL);
dirp->dd_loc += dp->d_reclen;
if (dp->d_ino == 0)
continue;
if (dp->d_type == DT_WHT && (dirp->dd_flags & DTF_HIDEW))
continue;
return (dp);
}
}
struct dirent *
readdir(dirp)
DIR *dirp;
{
struct dirent *dp;
#ifdef _REENTRANT
if (__isthreaded) {
mutex_lock((mutex_t *)dirp->dd_lock);
dp = _readdir_unlocked(dirp);
mutex_unlock((mutex_t *)dirp->dd_lock);
}
else
#endif
dp = _readdir_unlocked(dirp);
return (dp);
}
int
readdir_r(dirp, entry, result)
DIR *dirp;
struct dirent *entry;
struct dirent **result;
{
struct dirent *dp;
int saved_errno;
saved_errno = errno;
errno = 0;
#ifdef _REENTRANT
if (__isthreaded) {
mutex_lock((mutex_t *)dirp->dd_lock);
if ((dp = _readdir_unlocked(dirp)) != NULL)
memcpy(entry, dp, DIRENT_SIZE(dp));
mutex_unlock((mutex_t *)dirp->dd_lock);
}
else
#endif
if ((dp = _readdir_unlocked(dirp)) != NULL)
memcpy(entry, dp, DIRENT_SIZE(dp));
if (errno != 0) {
if (dp == NULL)
return (errno);
} else
errno = saved_errno;
if (dp != NULL)
*result = entry;
else
*result = NULL;
return (0);
}
#include "__readdir30.c"

View File

@ -1,165 +1,6 @@
/* $NetBSD: scandir.c,v 1.23 2005/03/17 10:18:22 kleink Exp $ */
/* $NetBSD: scandir.c,v 1.24 2005/08/19 02:04:54 christos Exp $ */
/*
* Copyright (c) 1983, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 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. 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
* 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
* 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)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)scandir.c 8.3 (Berkeley) 1/2/94";
#else
__RCSID("$NetBSD: scandir.c,v 1.23 2005/03/17 10:18:22 kleink Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
/*
* Scan the directory dirname calling selectfn to make a list of selected
* directory entries then sort using qsort and compare routine dcomp.
* Returns the number of entries and a pointer to a list of pointers to
* struct dirent (through namelist). Returns -1 if there were any errors.
*/
#include "namespace.h"
#include <sys/types.h>
#include <sys/stat.h>
#define __LIBC12_SOURCE__
#include <assert.h>
#include <errno.h>
#include <dirent.h>
#include <stdlib.h>
#include <string.h>
#ifdef __weak_alias
__weak_alias(scandir,_scandir)
__weak_alias(alphasort,_alphasort)
#endif
/*
* The DIRSIZ macro is the minimum record length which will hold the directory
* entry. This requires the amount of space in struct dirent without the
* d_name field, plus enough space for the name and a terminating nul byte
* (dp->d_namlen + 1), rounded up to a 4 byte boundary.
*/
#undef DIRSIZ
#define DIRSIZ(dp) \
((sizeof(struct dirent) - sizeof(dp)->d_name) + \
(((dp)->d_namlen + 1 + 3) &~ 3))
int
scandir(dirname, namelist, selectfn, dcomp)
const char *dirname;
struct dirent ***namelist;
int (*selectfn) __P((const struct dirent *));
int (*dcomp) __P((const void *, const void *));
{
struct dirent *d, *p, **names, **newnames;
size_t nitems, arraysz;
struct stat stb;
DIR *dirp;
_DIAGASSERT(dirname != NULL);
_DIAGASSERT(namelist != NULL);
if ((dirp = opendir(dirname)) == NULL)
return (-1);
if (fstat(dirp->dd_fd, &stb) < 0)
goto bad;
/*
* estimate the array size by taking the size of the directory file
* and dividing it by a multiple of the minimum size entry.
*/
arraysz = (size_t)(stb.st_size / 24);
names = malloc(arraysz * sizeof(struct dirent *));
if (names == NULL)
goto bad;
nitems = 0;
while ((d = readdir(dirp)) != NULL) {
if (selectfn != NULL && !(*selectfn)(d))
continue; /* just selected names */
/*
* Check to make sure the array has space left and
* realloc the maximum size.
*/
if (nitems >= arraysz) {
if (fstat(dirp->dd_fd, &stb) < 0)
goto bad2; /* just might have grown */
arraysz = (size_t)(stb.st_size / 12);
newnames = realloc(names,
arraysz * sizeof(struct dirent *));
if (newnames == NULL)
goto bad2;
names = newnames;
}
/*
* Make a minimum size copy of the data
*/
p = (struct dirent *)malloc(DIRSIZ(d));
if (p == NULL)
goto bad2;
p->d_fileno = d->d_fileno;
p->d_reclen = d->d_reclen;
p->d_type = d->d_type;
p->d_namlen = d->d_namlen;
memmove(p->d_name, d->d_name, (size_t)(p->d_namlen + 1));
names[nitems++] = p;
}
closedir(dirp);
if (nitems && dcomp != NULL)
qsort(names, nitems, sizeof(struct dirent *), dcomp);
*namelist = names;
return (nitems);
bad2:
while (nitems-- > 0)
free(names[nitems]);
free(names);
bad:
closedir(dirp);
return (-1);
}
/*
* Alphabetic order comparison routine for those who want it.
*/
int
alphasort(d1, d2)
const void *d1;
const void *d2;
{
_DIAGASSERT(d1 != NULL);
_DIAGASSERT(d2 != NULL);
return (strcmp((*(const struct dirent *const *)d1)->d_name,
(*(const struct dirent *const *)d2)->d_name));
}
#include "__scandir30.c"

View File

@ -1,4 +1,4 @@
# $NetBSD: shlib_version,v 1.167 2005/08/07 20:32:58 veego Exp $
# $NetBSD: shlib_version,v 1.168 2005/08/19 02:04:54 christos Exp $
# Remember to update distrib/sets/lists/base/shl.* when changing
#
# things we wish to do on next major version bump:
@ -17,4 +17,4 @@
# - libc/net/getnet{ent,namadr}.c, netdb.h: remove __n_pad0
#
major=12
minor=132
minor=133

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile.inc,v 1.158 2005/07/16 17:12:12 christos Exp $
# $NetBSD: Makefile.inc,v 1.159 2005/08/19 02:04:54 christos Exp $
# @(#)Makefile.inc 8.3 (Berkeley) 10/24/94
# sys sources
@ -28,9 +28,10 @@ SRCS+= sigtimedwait.c sigwait.c sigwaitinfo.c statvfs.c
# glue to provide compatibility between GCC 1.X and 2.X and for compat
# with old syscall interfaces.
SRCS+= adjtime.c clock_settime.c ftruncate.c getdirentries.c lseek.c mmap.c \
msync.c ntp_adjtime.c pread.c preadv.c pwrite.c pwritev.c semctl.c \
settimeofday.c sigaltstack.c stat.c statfs.c swapon.c truncate.c
SRCS+= adjtime.c clock_settime.c ftruncate.c getdirentries.c getdents.c \
lseek.c mmap.c msync.c ntp_adjtime.c pread.c preadv.c pwrite.c \
pwritev.c semctl.c settimeofday.c sigaltstack.c stat.c __stat13.c \
statfs.c swapon.c truncate.c
# glue to syscalls that may pass structs or unions, which cannot be
# handled portably and easily by the syscall interface. The glue
@ -54,8 +55,8 @@ ASM= access.S acct.S \
extattr_set_link.S \
fchdir.S fchflags.S fchmod.S fchown.S fchroot.S \
fhopen.S fhstat.S fhstatvfs1.S fktrace.S \
flock.S fpathconf.S __fstat13.S fstatvfs1.S futimes.S \
__getcwd.S getdents.S getfh.S getvfsstat.S getgroups.S getitimer.S \
flock.S fpathconf.S __fstat30.S fstatvfs1.S futimes.S \
__getcwd.S __getdents30.S getfh.S getvfsstat.S getgroups.S getitimer.S \
__getlogin.S getpeername.S getpgid.S getpgrp.S \
getpriority.S getrlimit.S getrusage.S getsid.S getsockname.S \
getsockopt.S gettimeofday.S \
@ -65,7 +66,7 @@ ASM= access.S acct.S \
_ksem_post.S _ksem_trywait.S _ksem_unlink.S _ksem_wait.S \
_ksem_open.S \
lchflags.S lchmod.S lchown.S lfs_bmapv.S lfs_markv.S lfs_segclean.S \
lfs_segwait.S link.S listen.S __lstat13.S lutimes.S \
lfs_segwait.S link.S listen.S __lstat30.S lutimes.S \
_lwp_create.S _lwp_exit.S _lwp_self.S _lwp_wait.S \
_lwp_suspend.S _lwp_continue.S _lwp_wakeup.S \
_lwp_getprivate.S _lwp_setprivate.S \
@ -85,7 +86,7 @@ ASM= access.S acct.S \
setregid.S setreuid.S setrlimit.S setsid.S setsockopt.S \
setuid.S __shmctl13.S shmdt.S shmget.S shutdown.S \
__sigaltstack14.S __sigpending14.S __sigaction_sigtramp.S \
__sigtimedwait.S socket.S socketpair.S __stat13.S statvfs1.S \
__sigtimedwait.S socket.S socketpair.S __stat30.S statvfs1.S \
swapctl.S symlink.S __sysctl.S \
timer_create.S timer_delete.S timer_gettime.S timer_getoverrun.S \
timer_settime.S \

115
lib/libc/sys/__stat13.c Normal file
View File

@ -0,0 +1,115 @@
/* $NetBSD: __stat13.c,v 1.1 2005/08/19 02:04:54 christos Exp $ */
/*
* Copyright (c) 1997 Frank van der Linden
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 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 for the NetBSD Project
* by Frank van der Linden
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: __stat13.c,v 1.1 2005/08/19 02:04:54 christos Exp $");
#endif /* LIBC_SCCS and not lint */
#define __LIBC12_SOURCE__
#include <sys/types.h>
#include <sys/stat.h>
__warn_references(__stat13,
"warning: reference to compatibility __stat13(); include <sys/stat.h> to generate correct reference")
__warn_references(__fstat13,
"warning: reference to compatibility __fstat13(); include <sys/stat.h> to generate correct reference")
__warn_references(__lstat13,
"warning: reference to compatibility __lstat13(); include <sys/stat.h> to generate correct reference")
/*
* Convert from a new to an old stat structure.
*/
static void cvtstat(struct stat13 *, const struct stat *);
static void
cvtstat(struct stat13 *ost, const struct stat *st)
{
ost->st_dev = st->st_dev;
ost->st_ino = (uint32_t)st->st_ino;
ost->st_mode = st->st_mode;
ost->st_nlink = st->st_nlink;
ost->st_uid = st->st_uid;
ost->st_gid = st->st_gid;
ost->st_rdev = st->st_rdev;
ost->st_atimespec = st->st_atimespec;
ost->st_mtimespec = st->st_mtimespec;
ost->st_ctimespec = st->st_ctimespec;
ost->st_birthtimespec = st->st_birthtimespec;
ost->st_size = st->st_size;
ost->st_blocks = st->st_blocks;
ost->st_blksize = st->st_blksize;
ost->st_flags = st->st_flags;
ost->st_gen = st->st_gen;
}
int
__stat13(const char *file, struct stat13 *ost)
{
struct stat nst;
int ret;
if ((ret = __stat30(file, &nst)) == -1)
return ret;
cvtstat(ost, &nst);
return ret;
}
int
__fstat13(int f, struct stat13 *ost)
{
struct stat nst;
int ret;
if ((ret = __fstat30(f, &nst)) == -1)
return ret;
cvtstat(ost, &nst);
return ret;
}
int
__lstat13(const char *file, struct stat13 *ost)
{
struct stat nst;
int ret;
if ((ret = __lstat30(file, &nst)) == -1)
return ret;
cvtstat(ost, &nst);
return ret;
}

View File

@ -1,4 +1,4 @@
.\" $NetBSD: getdents.2,v 1.15 2004/05/13 10:20:58 wiz Exp $
.\" $NetBSD: getdents.2,v 1.16 2005/08/19 02:04:54 christos Exp $
.\"
.\" Copyright (c) 1989, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@ -29,7 +29,7 @@
.\"
.\" @(#)getdirentries.2 8.1 (Berkeley) 6/9/93
.\"
.Dd June 9, 1993
.Dd August 15, 2005
.Dt GETDENTS 2
.Os
.Sh NAME
@ -65,7 +65,7 @@ The data in the buffer is a series of
.Em dirent
structures each containing the following entries:
.Bd -literal -offset indent
u_int32_t d_fileno;
ino_t d_fileno;
u_int16_t d_reclen;
u_int8_t d_type;
u_int8_t d_namlen;

87
lib/libc/sys/getdents.c Normal file
View File

@ -0,0 +1,87 @@
/* $NetBSD: getdents.c,v 1.1 2005/08/19 02:04:54 christos Exp $ */
/*-
* Copyright (c) 2005 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Christos Zoulas.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 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 NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: getdents.c,v 1.1 2005/08/19 02:04:54 christos Exp $");
#endif /* LIBC_SCCS and not lint */
#define __LIBC12_SOURCE__
#include "namespace.h"
#include <sys/types.h>
#include <dirent.h>
#include <string.h>
/*
* libc12 compatible getdents routine.
*/
int
getdents(int fd, char *buf, size_t nbytes)
{
struct dirent *ndp, *nndp, *endp;
struct dirent12 *odp;
int rv;
if ((rv = __getdents30(fd, buf, nbytes)) == -1)
return rv;
odp = (struct dirent12 *)(void *)buf;
ndp = (struct dirent *)(void *)buf;
endp = (struct dirent *)(void *)&buf[rv];
/*
* In-place conversion. This works because odp
* is smaller than ndp, but it has to be done
* in the right sequence.
*/
for (; ndp < endp; ndp = nndp) {
nndp = _DIRENT_NEXT(ndp);
odp->d_ino = (u_int32_t)ndp->d_ino;
if (ndp->d_namlen >= sizeof(odp->d_name))
odp->d_namlen = sizeof(odp->d_name) - 1;
else
odp->d_namlen = (u_int8_t)ndp->d_namlen;
odp->d_type = ndp->d_type;
(void)memcpy(odp->d_name, ndp->d_name, (size_t)odp->d_namlen);
odp->d_name[odp->d_namlen] = '\0';
odp->d_reclen = _DIRENT_SIZE(odp);
odp = _DIRENT_NEXT(odp);
}
return ((char *)(void *)odp) - buf;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: getdirentries.c,v 1.4 2005/06/12 05:21:28 lukem Exp $ */
/* $NetBSD: getdirentries.c,v 1.5 2005/08/19 02:04:54 christos Exp $ */
/*
* Copyright (c) 1997 Frank van der Linden
@ -34,9 +34,10 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: getdirentries.c,v 1.4 2005/06/12 05:21:28 lukem Exp $");
__RCSID("$NetBSD: getdirentries.c,v 1.5 2005/08/19 02:04:54 christos Exp $");
#endif /* LIBC_SCCS and not lint */
#define __LIBC12_SOURCE__
#include "namespace.h"
#include <sys/types.h>
#include <dirent.h>

View File

@ -1,4 +1,4 @@
/* $NetBSD: stat.c,v 1.4 2005/06/12 05:21:28 lukem Exp $ */
/* $NetBSD: stat.c,v 1.5 2005/08/19 02:04:54 christos Exp $ */
/*
* Copyright (c) 1997 Frank van der Linden
@ -33,7 +33,7 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: stat.c,v 1.4 2005/06/12 05:21:28 lukem Exp $");
__RCSID("$NetBSD: stat.c,v 1.5 2005/08/19 02:04:54 christos Exp $");
#endif /* LIBC_SCCS and not lint */
#define __LIBC12_SOURCE__
@ -63,7 +63,7 @@ cvtstat(st, ost)
{
ost->st_dev = st->st_dev;
ost->st_ino = st->st_ino;
ost->st_ino = (u_int32_t)st->st_ino;
ost->st_mode = st->st_mode;
if (st->st_nlink >= (1 << 15))
ost->st_nlink = (1 << 15) - 1;
@ -90,7 +90,7 @@ stat(file, ost)
struct stat nst;
int ret;
if ((ret = __stat13(file, &nst)) < 0)
if ((ret = __stat30(file, &nst)) < 0)
return ret;
cvtstat(&nst, ost);
return ret;
@ -104,7 +104,7 @@ fstat(f, ost)
struct stat nst;
int ret;
if ((ret = __fstat13(f, &nst)) < 0)
if ((ret = __fstat30(f, &nst)) < 0)
return ret;
cvtstat(&nst, ost);
return ret;
@ -118,7 +118,7 @@ lstat(file, ost)
struct stat nst;
int ret;
if ((ret = __lstat13(file, &nst)) < 0)
if ((ret = __lstat30(file, &nst)) < 0)
return ret;
cvtstat(&nst, ost);
return ret;