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