1 /* savedir.c -- save the list of files in a directory in a string
2 Copyright (C) 1990, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18 /* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
24 #include <sys/types.h>
34 # define dirent direct
36 # include <sys/ndir.h>
47 /* Fake a return value. */
48 # define CLOSEDIR(d) (closedir (d), 0)
50 # define CLOSEDIR(d) closedir (d)
64 /* Return a freshly allocated string containing the filenames
65 in directory DIR, separated by '\0' characters;
66 the end is marked by two '\0' characters in a row.
67 NAME_SIZE is the number of bytes to initially allocate
68 for the string; it will be enlarged as needed.
69 Use NAME_SIZE == -1 if you do not know the size.
70 Return NULL (setting errno) if DIR cannot be opened, read, or closed. */
72 #ifndef NAME_SIZE_DEFAULT
73 # define NAME_SIZE_DEFAULT 512
77 savedir (const char *dir
, off_t name_size
)
82 size_t allocated
= name_size
; /* Overflow is checked indirectly below. */
90 /* Use the default if the size is not known. Be sure "allocated"
91 is at least `1' so there's room for the final NUL byte.
92 Do not simply test name_size <= 0, because the initialization
93 of "allocated" might have overflowed. */
94 if (name_size
< 0 || allocated
== 0)
95 allocated
= NAME_SIZE_DEFAULT
;
97 name_space
= xmalloc (allocated
);
100 while ((dp
= readdir (dirp
)) != NULL
)
102 /* Skip "", ".", and "..". "" is returned by at least one buggy
103 implementation: Solaris 2.4 readdir on NFS filesystems. */
104 char const *entry
= dp
->d_name
;
105 if (entry
[entry
[0] != '.' ? 0 : entry
[1] != '.' ? 1 : 2] != '\0')
107 size_t entry_size
= strlen (entry
) + 1;
108 if (used
+ entry_size
< used
)
110 if (allocated
<= used
+ entry_size
)
114 if (2 * allocated
< allocated
)
118 while (allocated
<= used
+ entry_size
);
120 name_space
= xrealloc (name_space
, allocated
);
122 memcpy (name_space
+ used
, entry
, entry_size
);
126 name_space
[used
] = '\0';
128 if (CLOSEDIR (dirp
) != 0)