1 /*-------------------------------------------------------------------------
2 *
3 * pgfnames.c
4 * directory handling functions
5 *
6 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 * IDENTIFICATION
10 * src/common/pgfnames.c
11 *
12 *-------------------------------------------------------------------------
13 */
14
15 #ifndef FRONTEND
16 #include "postgres.h"
17 #else
18 #include "postgres_fe.h"
19 #endif
20
21 #include <dirent.h>
22
23 /*
24 * pgfnames
25 *
26 * return a list of the names of objects in the argument directory. Caller
27 * must call pgfnames_cleanup later to free the memory allocated by this
28 * function.
29 */
30 char **
pgfnames(const char * path)31 pgfnames(const char *path)
32 {
33 DIR *dir;
34 struct dirent *file;
35 char **filenames;
36 int numnames = 0;
37 int fnsize = 200; /* enough for many small dbs */
38
39 dir = opendir(path);
40 if (dir == NULL)
41 {
42 #ifndef FRONTEND
43 elog(WARNING, "could not open directory \"%s\": %m", path);
44 #else
45 fprintf(stderr, _("could not open directory \"%s\": %s\n"),
46 path, strerror(errno));
47 #endif
48 return NULL;
49 }
50
51 filenames = (char **) palloc(fnsize * sizeof(char *));
52
53 while (errno = 0, (file = readdir(dir)) != NULL)
54 {
55 if (strcmp(file->d_name, ".") != 0 && strcmp(file->d_name, "..") != 0)
56 {
57 if (numnames + 1 >= fnsize)
58 {
59 fnsize *= 2;
60 filenames = (char **) repalloc(filenames,
61 fnsize * sizeof(char *));
62 }
63 filenames[numnames++] = pstrdup(file->d_name);
64 }
65 }
66
67 if (errno)
68 {
69 #ifndef FRONTEND
70 elog(WARNING, "could not read directory \"%s\": %m", path);
71 #else
72 fprintf(stderr, _("could not read directory \"%s\": %s\n"),
73 path, strerror(errno));
74 #endif
75 }
76
77 filenames[numnames] = NULL;
78
79 if (closedir(dir))
80 {
81 #ifndef FRONTEND
82 elog(WARNING, "could not close directory \"%s\": %m", path);
83 #else
84 fprintf(stderr, _("could not close directory \"%s\": %s\n"),
85 path, strerror(errno));
86 #endif
87 }
88
89 return filenames;
90 }
91
92
93 /*
94 * pgfnames_cleanup
95 *
96 * deallocate memory used for filenames
97 */
98 void
pgfnames_cleanup(char ** filenames)99 pgfnames_cleanup(char **filenames)
100 {
101 char **fn;
102
103 for (fn = filenames; *fn; fn++)
104 pfree(*fn);
105
106 pfree(filenames);
107 }
108