hbase

heirloom base
git clone git://git.2f30.org/hbase
Log | Files | Refs | README

getdir.c (5320B)


      1 /*
      2  * Copyright (c) 2003 Gunnar Ritter
      3  *
      4  * This software is provided 'as-is', without any express or implied
      5  * warranty. In no event will the authors be held liable for any damages
      6  * arising from the use of this software.
      7  *
      8  * Permission is granted to anyone to use this software for any purpose,
      9  * including commercial applications, and to alter it and redistribute
     10  * it freely, subject to the following restrictions:
     11  *
     12  * 1. The origin of this software must not be misrepresented; you must not
     13  *    claim that you wrote the original software. If you use this software
     14  *    in a product, an acknowledgment in the product documentation would be
     15  *    appreciated but is not required.
     16  *
     17  * 2. Altered source versions must be plainly marked as such, and must not be
     18  *    misrepresented as being the original software.
     19  *
     20  * 3. This notice may not be removed or altered from any source distribution.
     21  */
     22 /*	Sccsid @(#)getdir.c	1.20 (gritter) 5/14/06	*/
     23 
     24 #ifndef	__linux__
     25 /*
     26  * 32-bit Solaris and Open UNIX do not have 64-bit getdents(); but
     27  * having _FILE_OFFSET_BITS=64 will make it use a dirent64 struct
     28  * on Open UNIX -> SEGV.
     29  */
     30 #undef	_FILE_OFFSET_BITS
     31 #endif	/* !__linux__ */
     32 
     33 #include	<sys/types.h>
     34 #include	<sys/stat.h>
     35 #include	<stdlib.h>
     36 #include	<errno.h>
     37 #include	<string.h>
     38 
     39 #if defined (__UCLIBC__)
     40 #include <linux/types.h>
     41 #include <linux/dirent.h>
     42 #define	getdents(a, b, c)	__getdents64(a, b, c)
     43 #define	dirent	dirent64
     44 extern int	getdents(int, struct dirent *, size_t);
     45 #elif defined	(__GLIBC__) || defined (__FreeBSD__) || defined (_AIX) || \
     46 	defined (__NetBSD__) || defined (__OpenBSD__) || \
     47 	defined (__DragonFly__) || defined (__APPLE__)
     48 #include	<dirent.h>
     49 #define	getdents(a, b, c)	getdirentries((a), (char *)(b), (c), &(db->g_offs))
     50 #if defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || \
     51 	defined (__DragonFly__) || defined (__APPLE__)
     52 #undef	d_ino
     53 #endif	/* __FreeBSD__ || __NetBSD__ || __OpenBSD__ || __DragonFly__
     54 	 || __APPLE__ */
     55 #elif defined	(__dietlibc__)
     56 #include	<dirent.h>
     57 #include	<unistd.h>
     58 #else		/* !__GLIBC__, !__dietlibc__ */
     59 #ifdef	__hpux
     60 #define		_KERNEL
     61 #endif	/* __hpux */
     62 #include	<dirent.h>
     63 #ifdef		__hpux
     64 #ifndef	_INO64_T
     65 typedef	unsigned long long	uint64_t;
     66 typedef	uint64_t	ino64_t;
     67 #endif	/* !_INO64_T */
     68 #ifdef	__LP64__
     69 #define	dirent		__dirent64
     70 #else	/* !__LP64__ */
     71 #define	dirent		__dirent32
     72 #endif	/* !__LP64__ */
     73 #define	d_reclen	__d_reclen
     74 #define	d_name		__d_name
     75 #define	d_ino		__d_ino
     76 #endif		/* __hpux */
     77 #endif		/* !__GLIBC__, !__dietlibc__ */
     78 
     79 #include	"getdir.h"
     80 
     81 #define	DIBSIZE	5120
     82 
     83 struct	getdb {
     84 #if !defined (__FreeBSD__) && !defined (__NetBSD__) && !defined (__OpenBSD__) \
     85 		&& !defined (__DragonFly__) && !defined (__APPLE__)
     86 	off_t		g_offs;
     87 #else	/* __FreeBSD__, __NetBSD__, __OpenBSD__, __DragonFly__, __APPLE__ */
     88 	long		g_offs;
     89 #endif	/* __FreeBSD__, __NetBSD__, __OpenBSD__, __DragonFly__, __APPLE__ */
     90 	struct dirent	*g_dirp;
     91 	const char	*g_path;
     92 	struct direc	g_dic;
     93 	union {
     94 		char		g_dirbuf[DIBSIZE+1];
     95 		struct dirent	g_dummy[1];
     96 	} g_u;
     97 	int		g_num;
     98 	int		g_fd;
     99 };
    100 
    101 struct getdb *
    102 getdb_alloc(const char *path, int fd)
    103 {
    104 	struct getdb	*db;
    105 
    106 	if ((db = malloc(sizeof *db)) == NULL)
    107 		return NULL;
    108 	db->g_dirp = NULL;
    109 	db->g_offs = 0;
    110 	db->g_fd = fd;
    111 	db->g_path = path;
    112 	return db;
    113 }
    114 
    115 void
    116 getdb_free(struct getdb *db)
    117 {
    118 	free(db);
    119 }
    120 
    121 struct direc *
    122 getdir(struct getdb *db, int *err)
    123 {
    124 	int	reclen;
    125 
    126 	*err = 0;
    127 	while (db->g_dirp == NULL)
    128 	{
    129 		/*LINTED*/
    130 		db->g_num = getdents(db->g_fd,
    131 				(struct dirent *)db->g_u.g_dirbuf,
    132 				DIBSIZE);
    133 		if (db->g_num <= 0) {
    134 			if (db->g_num < 0)
    135 				*err = errno;
    136 			db->g_offs = 0;
    137 			return NULL;
    138 		}
    139 		/*LINTED*/
    140 		db->g_dirp = (struct dirent *)db->g_u.g_dirbuf;
    141 		while (db->g_dirp &&
    142 #if !defined (__FreeBSD__) && !defined (__NetBSD__) && !defined (__OpenBSD__) \
    143 		&& !defined (__DragonFly__) && !defined (__APPLE__)
    144 				db->g_dirp->d_ino == 0
    145 #else	/* __FreeBSD__, __NetBSD__, __OpenBSD__, __DragonFly__, __APPLE__ */
    146 				(db->g_dirp->d_fileno == 0
    147 #ifdef DT_WHT
    148 				  || db->g_dirp->d_type == DT_WHT
    149 #endif
    150 				  )
    151 #endif	/* __FreeBSD__, __NetBSD__, __OpenBSD__, __DragonFly__, __APPLE__ */
    152 		      )
    153 		{
    154 		next:
    155 #ifndef	__DragonFly__
    156 			reclen = db->g_dirp->d_reclen;
    157 #else
    158 			reclen = _DIRENT_DIRSIZ(db->g_dirp);
    159 #endif
    160 			if ((db->g_num -= reclen) == 0 || reclen == 0)
    161 				db->g_dirp = NULL;
    162 			else
    163 				db->g_dirp =
    164 					/*LINTED*/
    165 					(struct dirent *)((char *)db->g_dirp
    166 						+ reclen);
    167 		}
    168 	}
    169 #if !defined (__FreeBSD__) && !defined (__NetBSD__) && !defined (__OpenBSD__) \
    170 		&& !defined (__DragonFly__) && !defined (__APPLE__)
    171 	if (db->g_dirp->d_ino == 0)
    172 		goto next;
    173 	db->g_dic.d_ino = db->g_dirp->d_ino;
    174 #else	/* __FreeBSD__, __NetBSD__, __OpenBSD__, __DragonFly__, __APPLE__ */
    175 	if (db->g_dirp->d_fileno == 0
    176 #ifdef DT_WHT
    177 	    || db->g_dirp->d_type == DT_WHT
    178 #endif
    179 	    )
    180 	{
    181 		goto next;
    182 	}
    183 	db->g_dic.d_ino = db->g_dirp->d_fileno;
    184 #endif	/* __FreeBSD__, __NetBSD__, __OpenBSD__, __DragonFly__, __APPLE__ */
    185 	db->g_dic.d_name = db->g_dirp->d_name;
    186 #ifndef	__DragonFly__
    187 		reclen = db->g_dirp->d_reclen;
    188 #else
    189 		reclen = _DIRENT_DIRSIZ(db->g_dirp);
    190 #endif
    191 	if ((db->g_num -= reclen) == 0 || reclen == 0)
    192 		db->g_dirp = NULL;
    193 	else
    194 		/*LINTED*/
    195 		db->g_dirp = (struct dirent *)((char *)db->g_dirp + reclen);
    196 	return &(db->g_dic);
    197 }