1 /*-------------------------------------------------------------------------
2 *
3 * pgfnames.c
4 * directory handling functions
5 *
6 * Portions Copyright (c) 1996-2019, 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 #ifndef FRONTEND
24 #define pg_log_warning(...) elog(WARNING, __VA_ARGS__)
25 #else
26 #include "common/logging.h"
27 #endif
28
29 /*
30 * pgfnames
31 *
32 * return a list of the names of objects in the argument directory. Caller
33 * must call pgfnames_cleanup later to free the memory allocated by this
34 * function.
35 */
36 char **
pgfnames(const char * path)37 pgfnames(const char *path)
38 {
39 DIR *dir;
40 struct dirent *file;
41 char **filenames;
42 int numnames = 0;
43 int fnsize = 200; /* enough for many small dbs */
44
45 dir = opendir(path);
46 if (dir == NULL)
47 {
48 pg_log_warning("could not open directory \"%s\": %m", path);
49 return NULL;
50 }
51
52 filenames = (char **) palloc(fnsize * sizeof(char *));
53
54 while (errno = 0, (file = readdir(dir)) != NULL)
55 {
56 if (strcmp(file->d_name, ".") != 0 && strcmp(file->d_name, "..") != 0)
57 {
58 if (numnames + 1 >= fnsize)
59 {
60 fnsize *= 2;
61 filenames = (char **) repalloc(filenames,
62 fnsize * sizeof(char *));
63 }
64 filenames[numnames++] = pstrdup(file->d_name);
65 }
66 }
67
68 if (errno)
69 pg_log_warning("could not read directory \"%s\": %m", path);
70
71 filenames[numnames] = NULL;
72
73 if (closedir(dir))
74 pg_log_warning("could not close directory \"%s\": %m", path);
75
76 return filenames;
77 }
78
79
80 /*
81 * pgfnames_cleanup
82 *
83 * deallocate memory used for filenames
84 */
85 void
pgfnames_cleanup(char ** filenames)86 pgfnames_cleanup(char **filenames)
87 {
88 char **fn;
89
90 for (fn = filenames; *fn; fn++)
91 pfree(*fn);
92
93 pfree(filenames);
94 }
95