~ubuntu-branches/ubuntu/vivid/gzip/vivid

« back to all changes in this revision

Viewing changes to lib/savedir.c

  • Committer: Steve Langasek
  • Date: 2012-06-29 02:07:40 UTC
  • mfrom: (4.1.9 sid)
  • Revision ID: steve.langasek@canonical.com-20120629020740-qqikrblzana08v2y
Merge version 1.5-1.1 from Debian

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* savedir.c -- save the list of files in a directory in a string
 
2
 
 
3
   Copyright (C) 1990, 1997-2001, 2003-2006, 2009-2012 Free Software
 
4
   Foundation, Inc.
 
5
 
 
6
   This program is free software: you can redistribute it and/or modify
 
7
   it under the terms of the GNU General Public License as published by
 
8
   the Free Software Foundation; either version 3 of the License, or
 
9
   (at your option) any later version.
 
10
 
 
11
   This program is distributed in the hope that it will be useful,
 
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
   GNU General Public License for more details.
 
15
 
 
16
   You should have received a copy of the GNU General Public License
 
17
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
18
 
 
19
/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
 
20
 
 
21
#include <config.h>
 
22
 
 
23
#include "savedir.h"
 
24
 
 
25
#include <sys/types.h>
 
26
 
 
27
#include <errno.h>
 
28
 
 
29
#include "dirent--.h"
 
30
#ifndef _D_EXACT_NAMLEN
 
31
# define _D_EXACT_NAMLEN(dp)    strlen ((dp)->d_name)
 
32
#endif
 
33
 
 
34
#include <stddef.h>
 
35
#include <stdlib.h>
 
36
#include <string.h>
 
37
 
 
38
#include "xalloc.h"
 
39
 
 
40
#ifndef NAME_SIZE_DEFAULT
 
41
# define NAME_SIZE_DEFAULT 512
 
42
#endif
 
43
 
 
44
/* Return a freshly allocated string containing the file names
 
45
   in directory DIRP, separated by '\0' characters;
 
46
   the end is marked by two '\0' characters in a row.
 
47
   Return NULL (setting errno) if DIRP cannot be read.
 
48
   If DIRP is NULL, return NULL without affecting errno.  */
 
49
 
 
50
char *
 
51
streamsavedir (DIR *dirp)
 
52
{
 
53
  char *name_space;
 
54
  size_t allocated = NAME_SIZE_DEFAULT;
 
55
  size_t used = 0;
 
56
  int save_errno;
 
57
 
 
58
  if (dirp == NULL)
 
59
    return NULL;
 
60
 
 
61
  name_space = xmalloc (allocated);
 
62
 
 
63
  for (;;)
 
64
    {
 
65
      struct dirent const *dp;
 
66
      char const *entry;
 
67
 
 
68
      errno = 0;
 
69
      dp = readdir (dirp);
 
70
      if (! dp)
 
71
        break;
 
72
 
 
73
      /* Skip "", ".", and "..".  "" is returned by at least one buggy
 
74
         implementation: Solaris 2.4 readdir on NFS file systems.  */
 
75
      entry = dp->d_name;
 
76
      if (entry[entry[0] != '.' ? 0 : entry[1] != '.' ? 1 : 2] != '\0')
 
77
        {
 
78
          size_t entry_size = _D_EXACT_NAMLEN (dp) + 1;
 
79
          if (used + entry_size < used)
 
80
            xalloc_die ();
 
81
          if (allocated <= used + entry_size)
 
82
            {
 
83
              do
 
84
                {
 
85
                  if (2 * allocated < allocated)
 
86
                    xalloc_die ();
 
87
                  allocated *= 2;
 
88
                }
 
89
              while (allocated <= used + entry_size);
 
90
 
 
91
              name_space = xrealloc (name_space, allocated);
 
92
            }
 
93
          memcpy (name_space + used, entry, entry_size);
 
94
          used += entry_size;
 
95
        }
 
96
    }
 
97
  name_space[used] = '\0';
 
98
  save_errno = errno;
 
99
  if (save_errno != 0)
 
100
    {
 
101
      free (name_space);
 
102
      errno = save_errno;
 
103
      return NULL;
 
104
    }
 
105
  return name_space;
 
106
}
 
107
 
 
108
/* Like streamsavedir (DIRP), except also close DIRP.  */
 
109
 
 
110
static char *
 
111
savedirstream (DIR *dirp)
 
112
{
 
113
  char *name_space = streamsavedir (dirp);
 
114
  if (dirp && closedir (dirp) != 0)
 
115
    {
 
116
      int save_errno = errno;
 
117
      free (name_space);
 
118
      errno = save_errno;
 
119
      return NULL;
 
120
    }
 
121
  return name_space;
 
122
}
 
123
 
 
124
/* Return a freshly allocated string containing the file names
 
125
   in directory DIR, separated by '\0' characters;
 
126
   the end is marked by two '\0' characters in a row.
 
127
   Return NULL (setting errno) if DIR cannot be opened, read, or closed.  */
 
128
 
 
129
char *
 
130
savedir (char const *dir)
 
131
{
 
132
  return savedirstream (opendir (dir));
 
133
}
 
134
 
 
135
/* Return a freshly allocated string containing the file names
 
136
   in directory FD, separated by '\0' characters;
 
137
   the end is marked by two '\0' characters in a row.
 
138
   Return NULL (setting errno) if FD cannot be read or closed.  */
 
139
 
 
140
/* deprecated */
 
141
char *
 
142
fdsavedir (int fd)
 
143
{
 
144
  return savedirstream (fdopendir (fd));
 
145
}