1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
|
#include <sys/dirent.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#define open __normal_open
#define fcntl __normal_fcntl
#include <fcntl.h>
#include <unistd.h>
#undef _POSIX_PTHREADS
#include <syscall.h>
#include <errno.h>
#include "dirstream.h"
#undef close
#undef open
#undef fcntl
#undef stat
#ifdef __SVR4_I386_ABI_L1__
#define close __libc_close
#define open __libc_open
#define fcntl __libc_fcntl
#else
static inline
_syscall1(int,close,int,fd)
static inline
_syscall2(int,open,const char *,name,int,flags)
static inline
_syscall3(int,fcntl,int,fd,int,cmd,long,args)
#endif
#ifdef __ELF__
#pragma weak opendir = __libc_opendir
#endif
/*
* opendir just makes an open() call - it return NULL if it fails
* (open sets errno), otherwise it returns a DIR * pointer.
*/
DIR *
__libc_opendir(const char * name)
{
int fd;
struct stat statbuf;
struct dirent *buf;
DIR *ptr;
if (stat(name,&statbuf)) return NULL;
if (!S_ISDIR(statbuf.st_mode)) {
errno = ENOTDIR;
return NULL;
}
if ((fd = open(name,O_RDONLY)) < 0)
return NULL;
/* According to POSIX, directory streams should be closed when
* exec. From "Anna Pluzhnikov" <besp@midway.uchicago.edu>.
*/
if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0)
return NULL;
if (!(ptr=malloc(sizeof(*ptr)))) {
close(fd);
errno = ENOMEM;
return NULL;
}
#if 0
struct utsname uts;
int version;
if (uname (&uts))
{
return NULL;
}
#define MULTI_READDIR_VERSION "1.2"
/* We check out the kernel version here. */
version = strncmp (uts.release, MULTI_READDIR_VERSION,
sizeof (MULTI_READDIR_VERSION));
if (version < 0)
{
ptr->dd_version = SINGLE_READDIR;
}
else
{
if (version == 0)
ptr->dd_version = MULTI_READDIR;
else
ptr->dd_version = NEW_READDIR;
}
#endif
ptr->dd_max = statbuf.st_blksize;
if (ptr->dd_max < 512)
ptr->dd_max = 512;
if (!(buf=malloc(ptr->dd_max))) {
close(fd);
free(ptr);
errno = ENOMEM;
return NULL;
}
ptr->dd_fd = fd;
ptr->dd_nextoff = ptr->dd_nextloc = ptr->dd_size = 0;
ptr->dd_buf = buf;
ptr->dd_getdents = unknown;
return ptr;
}
|