1 /*-------------------------------------------------------------------------
2  *
3  * pgfnames.c
4  *	  directory handling functions
5  *
6  * Portions Copyright (c) 1996-2020, 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	  **
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
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