From 28f540f45bbacd939bfd07f213bcad2bf730b1bf Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Sat, 18 Feb 1995 01:27:10 +0000 Subject: initial import --- dirent/Makefile | 32 +++++++++++ dirent/alphasort.c | 29 ++++++++++ dirent/dirent.h | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++ dirent/list.c | 68 +++++++++++++++++++++++ dirent/scandir.c | 89 ++++++++++++++++++++++++++++++ dirent/tst-seekdir.c | 40 ++++++++++++++ 6 files changed, 407 insertions(+) create mode 100644 dirent/Makefile create mode 100644 dirent/alphasort.c create mode 100644 dirent/dirent.h create mode 100644 dirent/list.c create mode 100644 dirent/scandir.c create mode 100644 dirent/tst-seekdir.c (limited to 'dirent') diff --git a/dirent/Makefile b/dirent/Makefile new file mode 100644 index 0000000000..ed3335ce1b --- /dev/null +++ b/dirent/Makefile @@ -0,0 +1,32 @@ +# Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# +# Sub-makefile for dirent portion of the library. +# +subdir := dirent + +headers := dirent.h dirstream.h +routines := opendir closedir readdir rewinddir \ + seekdir telldir scandir alphasort \ + getdents +distribute := direct.h + +tests := list tst-seekdir + +include ../Rules diff --git a/dirent/alphasort.c b/dirent/alphasort.c new file mode 100644 index 0000000000..a7bdf3820e --- /dev/null +++ b/dirent/alphasort.c @@ -0,0 +1,29 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include +#include +#include + +int +DEFUN(alphasort, (a, b), + CONST PTR a AND CONST PTR b) +{ + return strcmp (((struct dirent *) a)->d_name, + ((struct dirent *) b)->d_name); +} diff --git a/dirent/dirent.h b/dirent/dirent.h new file mode 100644 index 0000000000..b102a4786c --- /dev/null +++ b/dirent/dirent.h @@ -0,0 +1,149 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * POSIX Standard: 5.1.2 Directory Operations + */ + +#ifndef _DIRENT_H + +#define _DIRENT_H 1 +#include + +__BEGIN_DECLS + +#include + + +/* Directory entry structure. + + This structure is laid out identically to the `struct direct' that + represents directory entries in the GNU Hurd and in BSD 4.4 (and + incidentally, on disk in the Berkeley fast file system). The `readdir' + implementations for GNU and BSD know this; you must change them if you + change this structure. */ + +struct dirent + { + __ino_t d_fileno; /* File serial number. */ + unsigned short int d_reclen; /* Length of the whole `struct dirent'. */ + unsigned char d_type; /* File type, possibly unknown. */ + unsigned char d_namlen; /* Length of the file name. */ + + /* Only this member is in the POSIX standard. */ + char d_name[1]; /* File name (actually longer). */ + }; + +#if defined(__USE_BSD) || defined(__USE_MISC) +#define d_ino d_fileno /* Backward compatibility. */ +#endif + +#ifdef __USE_BSD +/* File types for `d_type'. */ +enum + { + DT_UNKNOWN = 0, + DT_FIFO = 1, + DT_CHR = 2, + DT_DIR = 4, + DT_BLK = 6, + DT_REG = 8, + DT_LNK = 10, + DT_SOCK = 12 + }; + +/* Convert between stat structure types and directory types. */ +#define IFTODT(mode) (((mode) & 0170000) >> 12) +#define DTTOIF(dirtype) ((dirtype) << 12) +#endif + + +/* Get the system-dependent definition of `DIR', + the data type of directory stream objects. */ +#include + +/* Open a directory stream on NAME. + Return a DIR stream on the directory, or NULL if it could not be opened. */ +extern DIR *opendir __P ((__const char *__name)); + +/* Close the directory stream DIRP. + Return 0 if successful, -1 if not. */ +extern int closedir __P ((DIR * __dirp)); + +/* Read a directory entry from DIRP. + Return a pointer to a `struct dirent' describing the entry, + or NULL for EOF or error. The storage returned may be overwritten + by a later readdir call on the same DIR stream. */ +extern struct dirent *readdir __P ((DIR * __dirp)); + +/* Rewind DIRP to the beginning of the directory. */ +extern void rewinddir __P ((DIR * __dirp)); + +#if defined(__USE_BSD) || defined(__USE_MISC) + +#ifndef MAXNAMLEN +/* Get the definitions of the POSIX.1 limits. */ +#include + +/* `MAXNAMLEN' is the BSD name for what POSIX calls `NAME_MAX'. */ +#ifdef NAME_MAX +#define MAXNAMLEN NAME_MAX +#else +#define MAXNAMLEN 255 +#endif +#endif + +#include +#define __need_size_t +#include + +/* Seek to position POS on DIRP. */ +extern void seekdir __P ((DIR * __dirp, __off_t __pos)); + +/* Return the current position of DIRP. */ +extern __off_t telldir __P ((DIR * __dirp)); + +/* Scan the directory DIR, calling SELECT on each directory entry. + Entries for which SELECT returns nonzero are individually malloc'd, + sorted using qsort with CMP, and collected in a malloc'd array in + *NAMELIST. Returns the number of entries selected, or -1 on error. */ +extern int scandir __P ((__const char *__dir, + struct dirent ***__namelist, + int (*__select) __P ((struct dirent *)), + int (*__cmp) __P ((__const __ptr_t, + __const __ptr_t)))); + +/* Function to compare two `struct dirent's alphabetically. */ +extern int alphasort __P ((__const __ptr_t, __const __ptr_t)); + + +/* Read directory entries from FD into BUF, reading at most NBYTES. + Reading starts at offset *BASEP, and *BASEP is updated with the new + position after reading. Returns the number of bytes read; zero when at + end of directory; or -1 for errors. */ +extern __ssize_t __getdirentries __P ((int __fd, char *__buf, + size_t __nbytes, __off_t *__basep)); +extern __ssize_t getdirentries __P ((int __fd, char *__buf, + size_t __nbytes, __off_t *__basep)); + + +#endif /* Use BSD or misc. */ + +__END_DECLS + +#endif /* dirent.h */ diff --git a/dirent/list.c b/dirent/list.c new file mode 100644 index 0000000000..606bd42591 --- /dev/null +++ b/dirent/list.c @@ -0,0 +1,68 @@ +/* Copyright (C) 1991, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include +#include +#include +#include +#include +#include + + +void +DEFUN(test, (name), CONST char *name) +{ + DIR *dirp; + struct dirent *entp; + + puts(name); + + dirp = opendir(name); + if (dirp == NULL) + { + perror("opendir"); + return; + } + + errno = 0; + while ((entp = readdir(dirp)) != NULL) + printf("%s\tfile number %lu\n", + entp->d_name, (unsigned long int) entp->d_fileno); + + if (errno) + perror ("readdir"); + + if (closedir(dirp) < 0) + perror("closedir"); +} + +int +DEFUN(main, (argc, argv), int argc AND char **argv) +{ + --argc; + ++argv; + + if (argc == 0) + test("."); + else + while (argc-- > 0) + test(*argv++); + + exit(0); + return(0); +} diff --git a/dirent/scandir.c b/dirent/scandir.c new file mode 100644 index 0000000000..6794eadf0d --- /dev/null +++ b/dirent/scandir.c @@ -0,0 +1,89 @@ +/* Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include +#include +#include + +int +DEFUN(scandir, (dir, namelist, select, cmp), + CONST char *dir AND + struct dirent ***namelist AND + int EXFUN((*select), (struct dirent *)) AND + int EXFUN((*cmp), (CONST PTR, CONST PTR))) +{ + DIR *dp = opendir (dir); + struct dirent **v = NULL; + size_t vsize = 0, i; + struct dirent *d; + int save; + + if (dp == NULL) + return -1; + + save = errno; + errno = 0; + + i = 0; + while ((d = readdir (dp)) != NULL) + if (select == NULL || (*select) (d)) + { + if (i == vsize) + { + struct dirent **new; + if (vsize == 0) + vsize = 10; + else + vsize *= 2; + new = (struct dirent **) realloc (v, vsize * sizeof (*v)); + if (new == NULL) + { + lose: + errno = ENOMEM; + break; + } + v = new; + } + + v[i] = (struct dirent *) malloc (sizeof (**v)); + if (v[i] == NULL) + goto lose; + + *v[i++] = *d; + } + + if (errno != 0) + { + save = errno; + (void) closedir (dp); + while (i > 0) + free (v[--i]); + free (v); + errno = save; + return -1; + } + + (void) closedir (dp); + errno = save; + + /* Sort the list if we have a comparison function to sort with. */ + if (cmp != NULL) + qsort (v, i, sizeof (*v), cmp); + *namelist = v; + return i; +} diff --git a/dirent/tst-seekdir.c b/dirent/tst-seekdir.c new file mode 100644 index 0000000000..fc282468fe --- /dev/null +++ b/dirent/tst-seekdir.c @@ -0,0 +1,40 @@ +#include +#include +#include + +int +main () +{ + + DIR * dirp; + long save3; + int i = 0; + struct dirent *dp; + + dirp = opendir("."); + for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) + { + /* save position 3 (fourth entry) */ + if (i++ == 3) + save3 = telldir(dirp); + + printf("%s\n", dp->d_name); + + /* stop at 400 (just to make sure dirp->__offset and dirp->__size are + scrambled */ + if (i == 400) + break; + } + + /* go back to saved entry */ + seekdir (dirp, save3); + + + /* print remaining files (3-last) */ + for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) + printf("%s\n", dp->d_name); + + + closedir (dirp); + exit(0); +} -- cgit v1.2.3