diff options
Diffstat (limited to 'REORG.TODO/dirent')
35 files changed, 2140 insertions, 0 deletions
diff --git a/REORG.TODO/dirent/Makefile b/REORG.TODO/dirent/Makefile new file mode 100644 index 0000000000..1648bf42d2 --- /dev/null +++ b/REORG.TODO/dirent/Makefile @@ -0,0 +1,43 @@ +# Copyright (C) 1991-2017 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 Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with the GNU C Library; if not, see +# <http://www.gnu.org/licenses/>. + +# +# Sub-makefile for dirent portion of the library. +# +subdir := dirent + +include ../Makeconfig + +headers := dirent.h bits/dirent.h +routines := opendir closedir readdir readdir_r rewinddir \ + seekdir telldir scandir alphasort versionsort \ + getdents getdents64 dirfd readdir64 readdir64_r scandir64 \ + alphasort64 versionsort64 fdopendir \ + scandirat scandirat64 \ + scandir-cancel scandir-tail scandir64-tail + +tests := list tst-seekdir opendir-tst1 bug-readdir1 tst-fdopendir \ + tst-fdopendir2 tst-scandir tst-scandir64 + +CFLAGS-scandir.c = $(uses-callbacks) +CFLAGS-scandir64.c = $(uses-callbacks) +CFLAGS-scandir-tail.c = $(uses-callbacks) +CFLAGS-scandir64-tail.c = $(uses-callbacks) + +include ../Rules + +opendir-tst1-ARGS = --test-dir=${common-objpfx}dirent diff --git a/REORG.TODO/dirent/Versions b/REORG.TODO/dirent/Versions new file mode 100644 index 0000000000..d976d373f6 --- /dev/null +++ b/REORG.TODO/dirent/Versions @@ -0,0 +1,50 @@ +libc { + GLIBC_2.0 { + # a* + alphasort; + + # c* + closedir; + + # d* + dirfd; + + # g* + getdirentries; + + # o* + opendir; + + # r* + readdir; readdir_r; rewinddir; + + # s* + scandir; seekdir; + + # t* + telldir; + } + GLIBC_2.1 { + # a* + alphasort64; + + # r* + readdir64; readdir64_r; + + # s* + scandir64; + + # v* + versionsort; versionsort64; + } + GLIBC_2.2 { + # g* + getdirentries64; + } + GLIBC_2.4 { + fdopendir; + } + GLIBC_2.15 { + scandirat; scandirat64; + } +} diff --git a/REORG.TODO/dirent/alphasort.c b/REORG.TODO/dirent/alphasort.c new file mode 100644 index 0000000000..c5bf96a42c --- /dev/null +++ b/REORG.TODO/dirent/alphasort.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1992-2017 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* We need to avoid the header declaration of alphasort64, because + the types don't match alphasort and then the compiler will + complain about the mismatch when we do the alias below. */ +#define alphasort64 __renamed_alphasort64 + +#include <dirent.h> + +#undef alphasort64 + +#include <string.h> + +int +alphasort (const struct dirent **a, const struct dirent **b) +{ + return strcoll ((*a)->d_name, (*b)->d_name); +} + +#ifdef _DIRENT_MATCHES_DIRENT64 +weak_alias (alphasort, alphasort64) +#endif diff --git a/REORG.TODO/dirent/alphasort64.c b/REORG.TODO/dirent/alphasort64.c new file mode 100644 index 0000000000..a979849237 --- /dev/null +++ b/REORG.TODO/dirent/alphasort64.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1992-2017 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <dirent.h> +#include <string.h> + +/* alphasort.c defines alphasort64 as an alias if _DIRENT_MATCHES_DIRENT64. */ +#ifndef _DIRENT_MATCHES_DIRENT64 + +int +alphasort64 (const struct dirent64 **a, const struct dirent64 **b) +{ + return strcoll ((*a)->d_name, (*b)->d_name); +} + +#endif diff --git a/REORG.TODO/dirent/bug-readdir1.c b/REORG.TODO/dirent/bug-readdir1.c new file mode 100644 index 0000000000..4c3521dbb5 --- /dev/null +++ b/REORG.TODO/dirent/bug-readdir1.c @@ -0,0 +1,38 @@ +#include <dirent.h> +#include <errno.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> + + +int +main (void) +{ + DIR *dirp; + struct dirent* ent; + + /* open a dir stream */ + dirp = opendir ("/tmp"); + if (dirp == NULL) + { + if (errno == ENOENT) + exit (0); + + perror ("opendir"); + exit (1); + } + + /* close the directory file descriptor, making it invalid */ + if (close (dirfd (dirp)) != 0) + { + puts ("could not close directory file descriptor"); + /* This is not an error. It is not guaranteed this is possible. */ + return 0; + } + + ent = readdir (dirp); + + return ent != NULL || errno != EBADF; +} diff --git a/REORG.TODO/dirent/closedir.c b/REORG.TODO/dirent/closedir.c new file mode 100644 index 0000000000..00d9333772 --- /dev/null +++ b/REORG.TODO/dirent/closedir.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1991-2017 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <stddef.h> +#include <dirent.h> + + +/* Close the directory stream DIRP. + Return 0 if successful, -1 if not. */ +int +__closedir (DIR *dirp) +{ + __set_errno (ENOSYS); + return -1; +} +weak_alias (__closedir, closedir) + +stub_warning (closedir) diff --git a/REORG.TODO/dirent/dirent.h b/REORG.TODO/dirent/dirent.h new file mode 100644 index 0000000000..a9f80bca82 --- /dev/null +++ b/REORG.TODO/dirent/dirent.h @@ -0,0 +1,404 @@ +/* Copyright (C) 1991-2017 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* + * POSIX Standard: 5.1.2 Directory Operations <dirent.h> + */ + +#ifndef _DIRENT_H +#define _DIRENT_H 1 + +#include <features.h> + +__BEGIN_DECLS + +#include <bits/types.h> + +#ifdef __USE_XOPEN +# ifndef __ino_t_defined +# ifndef __USE_FILE_OFFSET64 +typedef __ino_t ino_t; +# else +typedef __ino64_t ino_t; +# endif +# define __ino_t_defined +# endif +# if defined __USE_LARGEFILE64 && !defined __ino64_t_defined +typedef __ino64_t ino64_t; +# define __ino64_t_defined +# endif +#endif + +/* This file defines `struct dirent'. + + It defines the macro `_DIRENT_HAVE_D_NAMLEN' iff there is a `d_namlen' + member that gives the length of `d_name'. + + It defines the macro `_DIRENT_HAVE_D_RECLEN' iff there is a `d_reclen' + member that gives the size of the entire directory entry. + + It defines the macro `_DIRENT_HAVE_D_OFF' iff there is a `d_off' + member that gives the file offset of the next directory entry. + + It defines the macro `_DIRENT_HAVE_D_TYPE' iff there is a `d_type' + member that gives the type of the file. + */ + +#include <bits/dirent.h> + +#if defined __USE_MISC && !defined d_fileno +# define d_ino d_fileno /* Backward compatibility. */ +#endif + +/* These macros extract size information from a `struct dirent *'. + They may evaluate their argument multiple times, so it must not + have side effects. Each of these may involve a relatively costly + call to `strlen' on some systems, so these values should be cached. + + _D_EXACT_NAMLEN (DP) returns the length of DP->d_name, not including + its terminating null character. + + _D_ALLOC_NAMLEN (DP) returns a size at least (_D_EXACT_NAMLEN (DP) + 1); + that is, the allocation size needed to hold the DP->d_name string. + Use this macro when you don't need the exact length, just an upper bound. + This macro is less likely to require calling `strlen' than _D_EXACT_NAMLEN. + */ + +#ifdef _DIRENT_HAVE_D_NAMLEN +# define _D_EXACT_NAMLEN(d) ((d)->d_namlen) +# define _D_ALLOC_NAMLEN(d) (_D_EXACT_NAMLEN (d) + 1) +#else +# define _D_EXACT_NAMLEN(d) (strlen ((d)->d_name)) +# ifdef _DIRENT_HAVE_D_RECLEN +# define _D_ALLOC_NAMLEN(d) (((char *) (d) + (d)->d_reclen) - &(d)->d_name[0]) +# else +# define _D_ALLOC_NAMLEN(d) (sizeof (d)->d_name > 1 ? sizeof (d)->d_name : \ + _D_EXACT_NAMLEN (d) + 1) +# endif +#endif + + +#ifdef __USE_MISC +/* File types for `d_type'. */ +enum + { + DT_UNKNOWN = 0, +# define DT_UNKNOWN DT_UNKNOWN + DT_FIFO = 1, +# define DT_FIFO DT_FIFO + DT_CHR = 2, +# define DT_CHR DT_CHR + DT_DIR = 4, +# define DT_DIR DT_DIR + DT_BLK = 6, +# define DT_BLK DT_BLK + DT_REG = 8, +# define DT_REG DT_REG + DT_LNK = 10, +# define DT_LNK DT_LNK + DT_SOCK = 12, +# define DT_SOCK DT_SOCK + DT_WHT = 14 +# define DT_WHT DT_WHT + }; + +/* Convert between stat structure types and directory types. */ +# define IFTODT(mode) (((mode) & 0170000) >> 12) +# define DTTOIF(dirtype) ((dirtype) << 12) +#endif + + +/* This is the data type of directory stream objects. + The actual structure is opaque to users. */ +typedef struct __dirstream DIR; + +/* Open a directory stream on NAME. + Return a DIR stream on the directory, or NULL if it could not be opened. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +extern DIR *opendir (const char *__name) __nonnull ((1)); + +#ifdef __USE_XOPEN2K8 +/* Same as opendir, but open the stream on the file descriptor FD. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +extern DIR *fdopendir (int __fd); +#endif + +/* Close the directory stream DIRP. + Return 0 if successful, -1 if not. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +extern int closedir (DIR *__dirp) __nonnull ((1)); + +/* 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. + + If the Large File Support API is selected we have to use the + appropriate interface. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +#ifndef __USE_FILE_OFFSET64 +extern struct dirent *readdir (DIR *__dirp) __nonnull ((1)); +#else +# ifdef __REDIRECT +extern struct dirent *__REDIRECT (readdir, (DIR *__dirp), readdir64) + __nonnull ((1)); +# else +# define readdir readdir64 +# endif +#endif + +#ifdef __USE_LARGEFILE64 +extern struct dirent64 *readdir64 (DIR *__dirp) __nonnull ((1)); +#endif + +#ifdef __USE_POSIX +/* Reentrant version of `readdir'. Return in RESULT a pointer to the + next entry. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +# ifndef __USE_FILE_OFFSET64 +extern int readdir_r (DIR *__restrict __dirp, + struct dirent *__restrict __entry, + struct dirent **__restrict __result) + __nonnull ((1, 2, 3)) __attribute_deprecated__; +# else +# ifdef __REDIRECT +extern int __REDIRECT (readdir_r, + (DIR *__restrict __dirp, + struct dirent *__restrict __entry, + struct dirent **__restrict __result), + readdir64_r) + __nonnull ((1, 2, 3)) __attribute_deprecated__; +# else +# define readdir_r readdir64_r +# endif +# endif + +# ifdef __USE_LARGEFILE64 +extern int readdir64_r (DIR *__restrict __dirp, + struct dirent64 *__restrict __entry, + struct dirent64 **__restrict __result) + __nonnull ((1, 2, 3)) __attribute_deprecated__; +# endif +#endif /* POSIX or misc */ + +/* Rewind DIRP to the beginning of the directory. */ +extern void rewinddir (DIR *__dirp) __THROW __nonnull ((1)); + +#if defined __USE_MISC || defined __USE_XOPEN +# include <bits/types.h> + +/* Seek to position POS on DIRP. */ +extern void seekdir (DIR *__dirp, long int __pos) __THROW __nonnull ((1)); + +/* Return the current position of DIRP. */ +extern long int telldir (DIR *__dirp) __THROW __nonnull ((1)); +#endif + +#ifdef __USE_XOPEN2K8 + +/* Return the file descriptor used by DIRP. */ +extern int dirfd (DIR *__dirp) __THROW __nonnull ((1)); + +# if defined __OPTIMIZE__ && defined _DIR_dirfd +# define dirfd(dirp) _DIR_dirfd (dirp) +# endif + +# ifdef __USE_MISC +# ifndef MAXNAMLEN +/* Get the definitions of the POSIX.1 limits. */ +# include <bits/posix1_lim.h> + +/* `MAXNAMLEN' is the BSD name for what POSIX calls `NAME_MAX'. */ +# ifdef NAME_MAX +# define MAXNAMLEN NAME_MAX +# else +# define MAXNAMLEN 255 +# endif +# endif +# endif + +# define __need_size_t +# include <stddef.h> + +/* Scan the directory DIR, calling SELECTOR 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. + + This function is a cancellation point and therefore not marked with + __THROW. */ +# ifndef __USE_FILE_OFFSET64 +extern int scandir (const char *__restrict __dir, + struct dirent ***__restrict __namelist, + int (*__selector) (const struct dirent *), + int (*__cmp) (const struct dirent **, + const struct dirent **)) + __nonnull ((1, 2)); +# else +# ifdef __REDIRECT +extern int __REDIRECT (scandir, + (const char *__restrict __dir, + struct dirent ***__restrict __namelist, + int (*__selector) (const struct dirent *), + int (*__cmp) (const struct dirent **, + const struct dirent **)), + scandir64) __nonnull ((1, 2)); +# else +# define scandir scandir64 +# endif +# endif + +# if defined __USE_GNU && defined __USE_LARGEFILE64 +/* This function is like `scandir' but it uses the 64bit dirent structure. + Please note that the CMP function must now work with struct dirent64 **. */ +extern int scandir64 (const char *__restrict __dir, + struct dirent64 ***__restrict __namelist, + int (*__selector) (const struct dirent64 *), + int (*__cmp) (const struct dirent64 **, + const struct dirent64 **)) + __nonnull ((1, 2)); +# endif + +# ifdef __USE_GNU +/* Similar to `scandir' but a relative DIR name is interpreted relative + to the directory for which DFD is a descriptor. + + This function is a cancellation point and therefore not marked with + __THROW. */ +# ifndef __USE_FILE_OFFSET64 +extern int scandirat (int __dfd, const char *__restrict __dir, + struct dirent ***__restrict __namelist, + int (*__selector) (const struct dirent *), + int (*__cmp) (const struct dirent **, + const struct dirent **)) + __nonnull ((2, 3)); +# else +# ifdef __REDIRECT +extern int __REDIRECT (scandirat, + (int __dfd, const char *__restrict __dir, + struct dirent ***__restrict __namelist, + int (*__selector) (const struct dirent *), + int (*__cmp) (const struct dirent **, + const struct dirent **)), + scandirat64) __nonnull ((2, 3)); +# else +# define scandirat scandirat64 +# endif +# endif + +/* This function is like `scandir' but it uses the 64bit dirent structure. + Please note that the CMP function must now work with struct dirent64 **. */ +extern int scandirat64 (int __dfd, const char *__restrict __dir, + struct dirent64 ***__restrict __namelist, + int (*__selector) (const struct dirent64 *), + int (*__cmp) (const struct dirent64 **, + const struct dirent64 **)) + __nonnull ((2, 3)); +# endif + +/* Function to compare two `struct dirent's alphabetically. */ +# ifndef __USE_FILE_OFFSET64 +extern int alphasort (const struct dirent **__e1, + const struct dirent **__e2) + __THROW __attribute_pure__ __nonnull ((1, 2)); +# else +# ifdef __REDIRECT +extern int __REDIRECT_NTH (alphasort, + (const struct dirent **__e1, + const struct dirent **__e2), + alphasort64) __attribute_pure__ __nonnull ((1, 2)); +# else +# define alphasort alphasort64 +# endif +# endif + +# if defined __USE_GNU && defined __USE_LARGEFILE64 +extern int alphasort64 (const struct dirent64 **__e1, + const struct dirent64 **__e2) + __THROW __attribute_pure__ __nonnull ((1, 2)); +# endif +#endif /* Use XPG7. */ + + +#ifdef __USE_MISC +/* 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. */ +# ifndef __USE_FILE_OFFSET64 +extern __ssize_t getdirentries (int __fd, char *__restrict __buf, + size_t __nbytes, + __off_t *__restrict __basep) + __THROW __nonnull ((2, 4)); +# else +# ifdef __REDIRECT +extern __ssize_t __REDIRECT_NTH (getdirentries, + (int __fd, char *__restrict __buf, + size_t __nbytes, + __off64_t *__restrict __basep), + getdirentries64) __nonnull ((2, 4)); +# else +# define getdirentries getdirentries64 +# endif +# endif + +# ifdef __USE_LARGEFILE64 +extern __ssize_t getdirentries64 (int __fd, char *__restrict __buf, + size_t __nbytes, + __off64_t *__restrict __basep) + __THROW __nonnull ((2, 4)); +# endif +#endif /* Use misc. */ + +#ifdef __USE_GNU +/* Function to compare two `struct dirent's by name & version. */ +# ifndef __USE_FILE_OFFSET64 +extern int versionsort (const struct dirent **__e1, + const struct dirent **__e2) + __THROW __attribute_pure__ __nonnull ((1, 2)); +# else +# ifdef __REDIRECT +extern int __REDIRECT_NTH (versionsort, + (const struct dirent **__e1, + const struct dirent **__e2), + versionsort64) + __attribute_pure__ __nonnull ((1, 2)); +# else +# define versionsort versionsort64 +# endif +# endif + +# ifdef __USE_LARGEFILE64 +extern int versionsort64 (const struct dirent64 **__e1, + const struct dirent64 **__e2) + __THROW __attribute_pure__ __nonnull ((1, 2)); +# endif +#endif /* Use GNU. */ + +__END_DECLS + +#endif /* dirent.h */ diff --git a/REORG.TODO/dirent/dirfd.c b/REORG.TODO/dirent/dirfd.c new file mode 100644 index 0000000000..7af77adf01 --- /dev/null +++ b/REORG.TODO/dirent/dirfd.c @@ -0,0 +1,30 @@ +/* Return the file descriptor used by a DIR stream. Stub version. + Copyright (C) 1995-2017 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <dirent.h> +#include <dirstream.h> +#include <errno.h> + +int +dirfd (DIR *dirp) +{ + __set_errno (ENOSYS); + return -1; +} + +stub_warning (dirfd) diff --git a/REORG.TODO/dirent/fdopendir.c b/REORG.TODO/dirent/fdopendir.c new file mode 100644 index 0000000000..a3d18657fd --- /dev/null +++ b/REORG.TODO/dirent/fdopendir.c @@ -0,0 +1,33 @@ +/* Open a directory stream from a file descriptor. Stub version. + Copyright (C) 2005-2017 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <stddef.h> +#include <dirent.h> + + +/* Open a directory stream on FD. */ +DIR * +__fdopendir (int fd) +{ + __set_errno (ENOSYS); + return NULL; +} +weak_alias (__fdopendir, fdopendir) + +stub_warning (fdopendir) diff --git a/REORG.TODO/dirent/getdents.c b/REORG.TODO/dirent/getdents.c new file mode 100644 index 0000000000..30e95f776d --- /dev/null +++ b/REORG.TODO/dirent/getdents.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1991-2017 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stddef.h> +#include <errno.h> +#include <sys/types.h> +#include <dirent.h> + +ssize_t +__getdirentries (int fd, char *buf, size_t nbytes, off_t *basep) +{ + __set_errno (ENOSYS); + return -1; +} +weak_alias (__getdirentries, getdirentries) + +stub_warning (getdirentries) diff --git a/REORG.TODO/dirent/getdents64.c b/REORG.TODO/dirent/getdents64.c new file mode 100644 index 0000000000..9528e5313f --- /dev/null +++ b/REORG.TODO/dirent/getdents64.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1991-2017 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stddef.h> +#include <errno.h> +#include <sys/types.h> +#include <dirent.h> + +ssize_t +getdirentries64 (int fd, char *buf, size_t nbytes, off64_t *basep) +{ + __set_errno (ENOSYS); + return -1; +} + +stub_warning (getdirentries64) diff --git a/REORG.TODO/dirent/list.c b/REORG.TODO/dirent/list.c new file mode 100644 index 0000000000..e99b253808 --- /dev/null +++ b/REORG.TODO/dirent/list.c @@ -0,0 +1,75 @@ +/* Copyright (C) 1991-2017 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <dirent.h> + + +static int +test (const char *name) +{ + DIR *dirp; + struct dirent *entp; + int retval = 0; + + puts (name); + + dirp = opendir (name); + if (dirp == NULL) + { + perror ("opendir"); + return 1; + } + + 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"); + retval = 1; + } + + if (closedir (dirp) < 0) + { + perror ("closedir"); + retval = 1; + } + + return retval; +} + +int +main (int argc, char **argv) +{ + int retval = 0; + --argc; + ++argv; + + if (argc == 0) + retval = test ("."); + else + while (argc-- > 0) + retval |= test (*argv++); + + return retval; +} diff --git a/REORG.TODO/dirent/opendir-tst1.c b/REORG.TODO/dirent/opendir-tst1.c new file mode 100644 index 0000000000..6171d617aa --- /dev/null +++ b/REORG.TODO/dirent/opendir-tst1.c @@ -0,0 +1,95 @@ +/* Copyright (C) 1998-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <dirent.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/stat.h> + +/* Name of the FIFO. */ +char tmpname[] = "fifoXXXXXX"; + + +/* Do the real work. */ +static int +real_test (void) +{ + DIR *dirp; + + /* This should not block for an FIFO. */ + dirp = opendir (tmpname); + + /* Successful. */ + if (dirp != NULL) + { + /* Oh, oh, how can this work? */ + fputs ("`opendir' succeeded on a FIFO???\n", stdout); + closedir (dirp); + return 1; + } + + if (errno != ENOTDIR) + { + fprintf (stdout, "`opendir' return error `%s' instead of `%s'\n", + strerror (errno), strerror (ENOTDIR)); + return 1; + } + + return 0; +} + + +static int +do_test (void) +{ + int retval; + + if (mktemp (tmpname) == NULL) + { + perror ("mktemp"); + return 1; + } + + /* Try to generate a FIFO. */ + if (mknod (tmpname, 0600 | S_IFIFO, 0) < 0) + { + perror ("mknod"); + /* We cannot make this an error. */ + return 0; + } + + retval = real_test (); + + remove (tmpname); + + return retval; +} + + +static void +do_cleanup (void) +{ + remove (tmpname); +} +#define CLEANUP_HANDLER do_cleanup + +#include <support/test-driver.c> diff --git a/REORG.TODO/dirent/opendir.c b/REORG.TODO/dirent/opendir.c new file mode 100644 index 0000000000..bbfbc64251 --- /dev/null +++ b/REORG.TODO/dirent/opendir.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1991-2017 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <stddef.h> +#include <dirent.h> +#include <fcntl.h> + + +DIR * +__opendirat (int dfd, const char *name) +{ + __set_errno (ENOSYS); + return NULL; +} + + +/* Open a directory stream on NAME. */ +DIR * +__opendir (const char *name) +{ + return __opendirat (AT_FDCWD, name); +} +weak_alias (__opendir, opendir) + +stub_warning (opendir) diff --git a/REORG.TODO/dirent/readdir.c b/REORG.TODO/dirent/readdir.c new file mode 100644 index 0000000000..07c8e67fb7 --- /dev/null +++ b/REORG.TODO/dirent/readdir.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1991-2017 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <stddef.h> +#include <dirent.h> + +/* Read a directory entry from DIRP. */ +struct dirent * +__readdir (DIR *dirp) +{ + __set_errno (ENOSYS); + return NULL; +} +weak_alias (__readdir, readdir) + +stub_warning (readdir) diff --git a/REORG.TODO/dirent/readdir64.c b/REORG.TODO/dirent/readdir64.c new file mode 100644 index 0000000000..14ec8f37a9 --- /dev/null +++ b/REORG.TODO/dirent/readdir64.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1991-2017 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <stddef.h> +#include <dirent.h> + +/* Read a directory entry from DIRP. */ +struct dirent64 * +__readdir64 (DIR *dirp) +{ + __set_errno (ENOSYS); + return NULL; +} +weak_alias (__readdir64, readdir64) +stub_warning (readdir64) diff --git a/REORG.TODO/dirent/readdir64_r.c b/REORG.TODO/dirent/readdir64_r.c new file mode 100644 index 0000000000..b032bdb061 --- /dev/null +++ b/REORG.TODO/dirent/readdir64_r.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1991-2017 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <stddef.h> +#include <dirent.h> + +/* Read a directory entry from DIRP, store result in ENTRY and return + pointer to result in *RESULT. */ +int +readdir64_r (DIR *dirp, struct dirent64 *entry, struct dirent64 **result) +{ + __set_errno (ENOSYS); + *result = NULL; + return -1; +} +stub_warning (readdir64_r) diff --git a/REORG.TODO/dirent/readdir_r.c b/REORG.TODO/dirent/readdir_r.c new file mode 100644 index 0000000000..c7c02b06ab --- /dev/null +++ b/REORG.TODO/dirent/readdir_r.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1991-2017 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <stddef.h> +#include <dirent.h> + +/* Read a directory entry from DIRP, store result in ENTRY and return + pointer to result in *RESULT. */ +int +__readdir_r (DIR *dirp, struct dirent *entry, struct dirent **result) +{ + __set_errno (ENOSYS); + *result = NULL; + return ENOSYS; +} +weak_alias (__readdir_r, readdir_r) + +stub_warning (readdir_r) diff --git a/REORG.TODO/dirent/rewinddir.c b/REORG.TODO/dirent/rewinddir.c new file mode 100644 index 0000000000..73c59e589d --- /dev/null +++ b/REORG.TODO/dirent/rewinddir.c @@ -0,0 +1,34 @@ +/* Copyright (C) 1991-2017 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <stddef.h> +#include <dirent.h> + + +/* Rewind DIRP to the beginning of the directory. */ +void +__rewinddir (DIR *dirp) +{ + __set_errno (ENOSYS); + /* No way to indicate failure. */ +} +libc_hidden_def (__rewinddir) +weak_alias (__rewinddir, rewinddir) + + +stub_warning (rewinddir) diff --git a/REORG.TODO/dirent/scandir-cancel.c b/REORG.TODO/dirent/scandir-cancel.c new file mode 100644 index 0000000000..e34a350539 --- /dev/null +++ b/REORG.TODO/dirent/scandir-cancel.c @@ -0,0 +1,31 @@ +/* Cancellation handler used in scandir* implementations. + Copyright (C) 1992-2017 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <dirent.h> + +void +__scandir_cancel_handler (void *arg) +{ + struct scandir_cancel_struct *cp = arg; + void **v = cp->v; + + for (size_t i = 0; i < cp->cnt; ++i) + free (v[i]); + free (v); + (void) __closedir (cp->dp); +} diff --git a/REORG.TODO/dirent/scandir-tail.c b/REORG.TODO/dirent/scandir-tail.c new file mode 100644 index 0000000000..7810fb4d42 --- /dev/null +++ b/REORG.TODO/dirent/scandir-tail.c @@ -0,0 +1,110 @@ +/* Logic guts of scandir*. + Copyright (C) 1992-2017 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <dirent.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <libc-lock.h> + +#ifndef SCANDIR_TAIL +# define SCANDIR_TAIL __scandir_tail +# define READDIR __readdir +# define DIRENT_TYPE struct dirent +#endif + +internal_function +int +SCANDIR_TAIL (DIR *dp, + DIRENT_TYPE ***namelist, + int (*select) (const DIRENT_TYPE *), + int (*cmp) (const DIRENT_TYPE **, const DIRENT_TYPE **)) +{ + if (dp == NULL) + return -1; + + int save = errno; + __set_errno (0); + + int result; + struct scandir_cancel_struct c = { .dp = dp }; + __libc_cleanup_push (&__scandir_cancel_handler, &c); + + DIRENT_TYPE **v = NULL; + size_t vsize = 0; + DIRENT_TYPE *d; + while ((d = READDIR (dp)) != NULL) + { + if (select != NULL) + { + int selected = (*select) (d); + + /* The SELECT function might have changed errno. It was + zero before and it need to be again to make the later + tests work. */ + __set_errno (0); + + if (!selected) + continue; + } + else + __set_errno (0); + + if (__glibc_unlikely (c.cnt == vsize)) + { + if (vsize == 0) + vsize = 10; + else + vsize *= 2; + DIRENT_TYPE **new = realloc (v, vsize * sizeof *v); + if (new == NULL) + break; + c.v = v = new; + } + + size_t dsize = &d->d_name[_D_ALLOC_NAMLEN (d)] - (char *) d; + DIRENT_TYPE *vnew = malloc (dsize); + if (vnew == NULL) + break; + v[c.cnt++] = (DIRENT_TYPE *) memcpy (vnew, d, dsize); + } + + if (__glibc_likely (errno == 0)) + { + __closedir (dp); + + /* Sort the list if we have a comparison function to sort with. */ + if (cmp != NULL) + qsort (v, c.cnt, sizeof *v, (__compar_fn_t) cmp); + + *namelist = v; + result = c.cnt; + } + else + { + /* This frees everything and calls closedir. */ + __scandir_cancel_handler (&c); + result = -1; + } + + __libc_cleanup_pop (0); + + if (result >= 0) + __set_errno (save); + return result; +} diff --git a/REORG.TODO/dirent/scandir.c b/REORG.TODO/dirent/scandir.c new file mode 100644 index 0000000000..ad6342b6d8 --- /dev/null +++ b/REORG.TODO/dirent/scandir.c @@ -0,0 +1,45 @@ +/* Copyright (C) 1992-2017 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* We need to avoid the header declaration of scandir64, because + the types don't match scandir and then the compiler will + complain about the mismatch when we do the alias below. */ +#define scandir64 __renamed_scandir64 + +#include <dirent.h> + +#undef scandir64 + +#ifndef SCANDIR +# define SCANDIR scandir +# define SCANDIR_TAIL __scandir_tail +# define DIRENT_TYPE struct dirent +#endif + + +int +SCANDIR (const char *dir, + DIRENT_TYPE ***namelist, + int (*select) (const DIRENT_TYPE *), + int (*cmp) (const DIRENT_TYPE **, const DIRENT_TYPE **)) +{ + return SCANDIR_TAIL (__opendir (dir), namelist, select, cmp); +} + +#ifdef _DIRENT_MATCHES_DIRENT64 +weak_alias (scandir, scandir64) +#endif diff --git a/REORG.TODO/dirent/scandir64-tail.c b/REORG.TODO/dirent/scandir64-tail.c new file mode 100644 index 0000000000..4d1746aae0 --- /dev/null +++ b/REORG.TODO/dirent/scandir64-tail.c @@ -0,0 +1,26 @@ +/* Logic guts of scandir*64. + Copyright (C) 2015-2017 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <dirent.h> + +#ifndef _DIRENT_MATCHES_DIRENT64 +# define SCANDIR_TAIL __scandir64_tail +# define READDIR __readdir64 +# define DIRENT_TYPE struct dirent64 +# include <scandir-tail.c> +#endif diff --git a/REORG.TODO/dirent/scandir64.c b/REORG.TODO/dirent/scandir64.c new file mode 100644 index 0000000000..cfe553b0f4 --- /dev/null +++ b/REORG.TODO/dirent/scandir64.c @@ -0,0 +1,29 @@ +/* Copyright (C) 2000-2017 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <dirent.h> + +/* scandir.c defines scandir64 as an alias if _DIRENT_MATCHES_DIRENT64. */ +#ifndef _DIRENT_MATCHES_DIRENT64 + +# define SCANDIR scandir64 +# define SCANDIR_TAIL __scandir64_tail +# define DIRENT_TYPE struct dirent64 + +# include <dirent/scandir.c> + +#endif diff --git a/REORG.TODO/dirent/scandirat.c b/REORG.TODO/dirent/scandirat.c new file mode 100644 index 0000000000..b331ea5681 --- /dev/null +++ b/REORG.TODO/dirent/scandirat.c @@ -0,0 +1,49 @@ +/* Copyright (C) 1992-2017 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* We need to avoid the header declaration of scandir64, because + the types don't match scandir and then the compiler will + complain about the mismatch when we do the alias below. */ +#define scandirat64 __renamed_scandirat64 + +#include <dirent.h> + +#undef scandirat64 + +#ifndef SCANDIRAT +# define SCANDIRAT __scandirat +# define SCANDIR_TAIL __scandir_tail +# define DIRENT_TYPE struct dirent +# define SCANDIRAT_WEAK_ALIAS +#endif + +int +SCANDIRAT (int dfd, const char *dir, + DIRENT_TYPE ***namelist, + int (*select) (const DIRENT_TYPE *), + int (*cmp) (const DIRENT_TYPE **, const DIRENT_TYPE **)) +{ + return SCANDIR_TAIL (__opendirat (dfd, dir), namelist, select, cmp); +} +libc_hidden_def (SCANDIRAT) +#ifdef SCANDIRAT_WEAK_ALIAS +weak_alias (__scandirat, scandirat) +#endif + +#ifdef _DIRENT_MATCHES_DIRENT64 +weak_alias (scandirat, scandirat64) +#endif diff --git a/REORG.TODO/dirent/scandirat64.c b/REORG.TODO/dirent/scandirat64.c new file mode 100644 index 0000000000..c5c918a919 --- /dev/null +++ b/REORG.TODO/dirent/scandirat64.c @@ -0,0 +1,29 @@ +/* Copyright (C) 2000-2017 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <dirent.h> + +/* scandirat.c defines scandirat64 as an alias if _DIRENT_MATCHES_DIRENT64. */ +#ifndef _DIRENT_MATCHES_DIRENT64 + +# define SCANDIRAT scandirat64 +# define SCANDIR_TAIL __scandir64_tail +# define DIRENT_TYPE struct dirent64 + +# include <scandirat.c> + +#endif diff --git a/REORG.TODO/dirent/seekdir.c b/REORG.TODO/dirent/seekdir.c new file mode 100644 index 0000000000..6dfc9a73cd --- /dev/null +++ b/REORG.TODO/dirent/seekdir.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1991-2017 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <sys/types.h> +#include <errno.h> +#include <stddef.h> +#include <dirent.h> + +/* Seek to position POS in DIRP. */ +void +seekdir (DIR *dirp, long int pos) +{ + if (dirp == NULL) + { + __set_errno (EINVAL); + return; + } + + __set_errno (ENOSYS); +} + + +stub_warning (seekdir) diff --git a/REORG.TODO/dirent/telldir.c b/REORG.TODO/dirent/telldir.c new file mode 100644 index 0000000000..7d2374e46a --- /dev/null +++ b/REORG.TODO/dirent/telldir.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991-2017 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <sys/types.h> +#include <stddef.h> +#include <dirent.h> + +/* Return the current position of DIRP. */ +long int +telldir (DIR *dirp) +{ + if (dirp == NULL) + { + __set_errno (EINVAL); + return -1l; + } + + __set_errno (ENOSYS); + return -1l; +} + + +stub_warning (telldir) diff --git a/REORG.TODO/dirent/tst-fdopendir.c b/REORG.TODO/dirent/tst-fdopendir.c new file mode 100644 index 0000000000..89bdca9086 --- /dev/null +++ b/REORG.TODO/dirent/tst-fdopendir.c @@ -0,0 +1,128 @@ +#include <stdio.h> +#include <fcntl.h> +#include <stdlib.h> +#include <unistd.h> +#include <dirent.h> +#include <stdbool.h> +#include <string.h> +#include <sys/stat.h> + +#ifndef O_NOATIME +# define O_NOATIME 0 +#endif + +static int +do_test (void) +{ + char fname[] = "/tmp/jXXXXXX"; + int fd = mkstemp (fname); + if (fd == -1) + { + puts ("mkstemp failed"); + return 1; + } + + write (fd, "hello", 5); + close (fd); + + struct stat64 st; + if (stat64 (fname, &st) == -1) + { + puts ("first stat failed"); + return 0; + } + + /* Make sure there is enough time between the creation and the access. */ + sleep (2); + + fd = open (fname, O_RDONLY | O_NOATIME); + if (fd == -1) + { + puts ("first open failed"); + return 1; + } + + char buf[5]; + read(fd, buf, sizeof (buf)); + close(fd); + + struct stat64 st2; + if (stat64 (fname, &st2) == -1) + { + puts ("second stat failed"); + return 0; + } + + bool no_noatime = false; +#ifdef _STATBUF_ST_NSEC + if (st.st_atim.tv_sec != st2.st_atim.tv_sec + || st.st_atim.tv_nsec != st2.st_atim.tv_nsec) +#else + if (st.st_atime != st2.st_atime) +#endif + { + puts ("file atime changed"); + no_noatime = true; + } + + unlink(fname); + + strcpy(fname, "/tmp/dXXXXXX"); + char *d = mkdtemp (fname); + if (d == NULL) + { + puts ("mkdtemp failed"); + return 1; + } + + if (stat64 (d, &st) == -1) + { + puts ("third stat failed"); + return 0; + } + sleep (2); + + fd = open64 (d, O_RDONLY|O_NDELAY|O_DIRECTORY|O_NOATIME); + if (fd == -1) + { + puts ("second open failed"); + return 1; + } + DIR *dir = fdopendir (fd); + if (dir == NULL) + { + puts ("fdopendir failed"); + return 1; + } + + struct dirent *de; + while ((de = readdir (dir)) != NULL) + ; + + closedir (dir); + + if (stat64 (d, &st2) == -1) + { + puts ("fourth stat failed"); + return 0; + } +#ifdef _STATBUF_ST_NSEC + if (!no_noatime + && (st.st_atim.tv_sec != st2.st_atim.tv_sec + || st.st_atim.tv_nsec != st2.st_atim.tv_nsec)) +#else + if (!no_noatime && st.st_atime != st2.st_atime) +#endif + { + puts ("directory atime changed"); + return 1; + } + + rmdir(fname); + + return 0; +} + +#define TIMEOUT 6 +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/REORG.TODO/dirent/tst-fdopendir2.c b/REORG.TODO/dirent/tst-fdopendir2.c new file mode 100644 index 0000000000..7709e4b3bc --- /dev/null +++ b/REORG.TODO/dirent/tst-fdopendir2.c @@ -0,0 +1,42 @@ +#include <errno.h> +#include <dirent.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + + +static int +do_test (void) +{ + char tmpl[] = "/tmp/tst-fdopendir2-XXXXXX"; + int fd = mkstemp (tmpl); + if (fd == -1) + { + puts ("cannot open temp file"); + return 1; + } + + errno = 0; + DIR *d = fdopendir (fd); + + int e = errno; + + close (fd); + unlink (tmpl); + + if (d != NULL) + { + puts ("fdopendir with normal file descriptor did not fail"); + return 1; + } + if (e != ENOTDIR) + { + printf ("fdopendir set errno to %d, not %d as expected\n", e, ENOTDIR); + return 1; + } + + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/REORG.TODO/dirent/tst-scandir.c b/REORG.TODO/dirent/tst-scandir.c new file mode 100644 index 0000000000..4ecfd7b932 --- /dev/null +++ b/REORG.TODO/dirent/tst-scandir.c @@ -0,0 +1,298 @@ +/* Basic test for scandir function. + Copyright (C) 2015-2017 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdbool.h> +#include <dirent.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#ifndef D +# define D(x) x +#endif + +static void prepare (void); +static int do_test (void); +#define PREPARE(argc, argv) prepare () +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" + +static const char *scandir_test_dir; + +static void +prepare (void) +{ + size_t test_dir_len = strlen (test_dir); + static const char dir_name[] = "/tst-scandir.XXXXXX"; + + size_t dirbuflen = test_dir_len + sizeof (dir_name); + char *dirbuf = malloc (dirbuflen); + if (dirbuf == NULL) + { + puts ("out of memory"); + exit (1); + } + + snprintf (dirbuf, dirbuflen, "%s%s", test_dir, dir_name); + if (mkdtemp (dirbuf) == NULL) + { + puts ("cannot create temporary directory"); + exit (1); + } + + add_temp_file (dirbuf); + scandir_test_dir = dirbuf; +} + +/* The directory should be empty save the . and .. files. */ +static void +verify_empty (const char *dirname) +{ + DIR *dir = opendir (dirname); + if (dir == NULL) + { + printf ("opendir (%s): %s\n", dirname, strerror (errno)); + exit (1); + } + + struct dirent64 *d; + while ((d = readdir64 (dir)) != NULL) + if (strcmp (d->d_name, ".") != 0 && strcmp (d->d_name, "..") != 0) + { + printf ("temp directory contains file \"%s\"\n", d->d_name); + exit (1); + } + + closedir (dir); +} + +static void +make_file (const char *dirname, const char *filename) +{ + char *name = NULL; + if (asprintf (&name, "%s/%s", dirname, filename) < 0) + { + puts ("out of memory"); + exit (1); + } + + int fd = open (name, O_WRONLY | O_CREAT | O_EXCL, 0600); + if (fd < 0) + { + printf ("cannot create \"%s\": %s\n", name, strerror (errno)); + exit (1); + } + close (fd); + + free (name); +} + +static void +remove_file (const char *dirname, const char *filename) +{ + char *name = NULL; + if (asprintf (&name, "%s/%s", dirname, filename) < 0) + { + puts ("out of memory"); + exit (1); + } + + remove (name); + + free (name); +} + +static void +freelist (struct D(dirent) **list, size_t n) +{ + for (size_t i = 0; i < n; ++i) + free (list[i]); + free (list); +} + +static int +select_a (const struct D(dirent) *d) +{ + return d->d_name[0] == 'a'; +} + +static int +do_test (void) +{ + verify_empty (scandir_test_dir); + + make_file (scandir_test_dir, "c"); + make_file (scandir_test_dir, "aa"); + make_file (scandir_test_dir, "b"); + make_file (scandir_test_dir, "a"); + + + /* First a basic test with no select or compare functions. */ + + struct D(dirent) **list; + int n = D(scandir) (scandir_test_dir, &list, NULL, NULL); + if (n < 0) + { + printf ("scandir failed on %s: %s\n", + scandir_test_dir, strerror (errno)); + return 1; + } + if (n != 6) + { + printf ("scandir returned %d entries instead of 6\n", n); + return 1; + } + + struct + { + const char *name; + bool found; + } expected[] = + { + { ".", }, + { "..", }, + { "a", }, + { "aa", }, + { "b", }, + { "c", }, + }; + + /* Verify the results, ignoring the order. */ + for (int i = 0; i < n; ++i) + { + for (size_t j = 0; j < sizeof expected / sizeof expected[0]; ++j) + if (!strcmp (list[i]->d_name, expected[j].name)) + { + expected[j].found = true; + goto found; + } + + printf ("scandir yields unexpected entry [%d] \"%s\"\n", + i, list[i]->d_name); + return 1; + + found:; + } + + for (size_t j = 0; j < sizeof expected / sizeof expected[0]; ++j) + if (!expected[j].found) + { + printf ("failed to produce \"%s\"\n", expected[j].name); + return 1; + } + + freelist (list, n); + + + /* Now a test with a comparison function. */ + + n = D(scandir) (scandir_test_dir, &list, NULL, &D(alphasort)); + if (n < 0) + { + printf ("scandir failed on %s: %s\n", + scandir_test_dir, strerror (errno)); + return 1; + } + if (n != 6) + { + printf ("scandir returned %d entries instead of 6\n", n); + return 1; + } + + assert (sizeof expected / sizeof expected[0] == 6); + for (int i = 0; i < n; ++i) + if (strcmp (list[i]->d_name, expected[i].name)) + { + printf ("scandir yields [%d] of \"%s\", expected \"%s\"\n", + i, list[i]->d_name, expected[i].name); + return 1; + } + + freelist (list, n); + + + /* Now a test with a select function but no comparison function. */ + + n = D(scandir) (scandir_test_dir, &list, &select_a, NULL); + if (n < 0) + { + printf ("scandir failed on %s: %s\n", + scandir_test_dir, strerror (errno)); + return 1; + } + if (n != 2) + { + printf ("scandir returned %d entries instead of 2\n", n); + return 1; + } + + if (strcmp (list[0]->d_name, "a") && strcmp (list[0]->d_name, "aa")) + { + printf ("scandir yields [0] \"%s\", expected \"a\" or \"aa\"\n", + list[0]->d_name); + return 1; + } + if (strcmp (list[1]->d_name, "a") && strcmp (list[1]->d_name, "aa")) + { + printf ("scandir yields [1] \"%s\", expected \"a\" or \"aa\"\n", + list[1]->d_name); + return 1; + } + if (!strcmp (list[0]->d_name, list[1]->d_name)) + { + printf ("scandir yields \"%s\" twice!\n", list[0]->d_name); + return 1; + } + + freelist (list, n); + + + /* Now a test with both functions. */ + + n = D(scandir) (scandir_test_dir, &list, &select_a, &D(alphasort)); + if (n < 0) + { + printf ("scandir failed on %s: %s\n", + scandir_test_dir, strerror (errno)); + return 1; + } + if (n != 2) + { + printf ("scandir returned %d entries instead of 2\n", n); + return 1; + } + + if (strcmp (list[0]->d_name, "a") || strcmp (list[1]->d_name, "aa")) + { + printf ("scandir yields {\"%s\", \"%s\"}, expected {\"a\", \"aa\"}\n", + list[0]->d_name, list[1]->d_name); + return 1; + } + + freelist (list, n); + + + /* Clean up the test directory. */ + remove_file (scandir_test_dir, "c"); + remove_file (scandir_test_dir, "aa"); + remove_file (scandir_test_dir, "b"); + remove_file (scandir_test_dir, "a"); + + return 0; +} diff --git a/REORG.TODO/dirent/tst-scandir64.c b/REORG.TODO/dirent/tst-scandir64.c new file mode 100644 index 0000000000..3f4c68ed7c --- /dev/null +++ b/REORG.TODO/dirent/tst-scandir64.c @@ -0,0 +1,2 @@ +#define D(x) x##64 +#include "tst-scandir.c" diff --git a/REORG.TODO/dirent/tst-seekdir.c b/REORG.TODO/dirent/tst-seekdir.c new file mode 100644 index 0000000000..dcdd699b09 --- /dev/null +++ b/REORG.TODO/dirent/tst-seekdir.c @@ -0,0 +1,81 @@ +#include <stdio.h> +#include <dirent.h> +#include <stdlib.h> + +static int +do_test (void) +{ + DIR * dirp; + long int save3 = 0; + long int cur; + int i = 0; + int result = 0; + struct dirent *dp; + long int save0; + long int rewind; + + dirp = opendir ("."); + if (dirp == NULL) + { + printf ("opendir failed: %m\n"); + return 1; + } + + save0 = telldir (dirp); + if (save0 == -1) + { + printf ("telldir failed: %m\n"); + result = 1; + } + + for (dp = readdir (dirp); dp != NULL; dp = readdir (dirp)) + { + /* save position 3 (after 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; + } + + printf ("going back past 4-th entry...\n"); + + /* go back to saved entry */ + seekdir (dirp, save3); + + /* Check whether telldir equals to save3 now. */ + cur = telldir (dirp); + if (cur != save3) + { + printf ("seekdir (d, %ld); telldir (d) == %ld\n", save3, cur); + result = 1; + } + + /* print remaining files (3-last) */ + for (dp = readdir (dirp); dp != NULL; dp = readdir (dirp)) + printf ("%s\n", dp->d_name); + + /* Check rewinddir */ + rewinddir (dirp); + rewind = telldir (dirp); + if (rewind == -1) + { + printf ("telldir failed: %m\n"); + result = 1; + } + else if (save0 != rewind) + { + printf ("rewinddir didn't reset directory stream\n"); + result = 1; + } + + closedir (dirp); + return result; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/REORG.TODO/dirent/versionsort.c b/REORG.TODO/dirent/versionsort.c new file mode 100644 index 0000000000..9e97b29288 --- /dev/null +++ b/REORG.TODO/dirent/versionsort.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1992-2017 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* We need to avoid the header declaration of versionsort64, because + the types don't match versionsort and then the compiler will + complain about the mismatch when we do the alias below. */ +#define versionsort64 __renamed_versionsort64 + +#include <dirent.h> + +#undef versionsort64 + +#include <string.h> + +int +versionsort (const struct dirent **a, const struct dirent **b) +{ + return __strverscmp ((*a)->d_name, (*b)->d_name); +} + +#ifdef _DIRENT_MATCHES_DIRENT64 +weak_alias (versionsort, versionsort64) +#endif diff --git a/REORG.TODO/dirent/versionsort64.c b/REORG.TODO/dirent/versionsort64.c new file mode 100644 index 0000000000..3fceb8947a --- /dev/null +++ b/REORG.TODO/dirent/versionsort64.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1992-2017 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <dirent.h> +#include <string.h> + +/* versionsort.c defines a versionsort64 alias if _DIRENT_MATCHES_DIRENT64. */ +#ifndef _DIRENT_MATCHES_DIRENT64 + +int +versionsort64 (const struct dirent64 **a, const struct dirent64 **b) +{ + return __strverscmp ((*a)->d_name, (*b)->d_name); +} + +#endif |