]> granicus.if.org Git - postgresql/blob - src/port/pgcheckdir.c
Don't dump core when destroying an unused ParallelContext.
[postgresql] / src / port / pgcheckdir.c
1 /*-------------------------------------------------------------------------
2  *
3  * src/port/pgcheckdir.c
4  *
5  * A simple subroutine to check whether a directory exists and is empty or not.
6  * Useful in both initdb and the backend.
7  *
8  * Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group
9  * Portions Copyright (c) 1994, Regents of the University of California
10  *
11  *-------------------------------------------------------------------------
12  */
13
14 #include "c.h"
15
16 #include <dirent.h>
17
18
19 /*
20  * Test to see if a directory exists and is empty or not.
21  *
22  * Returns:
23  *              0 if nonexistent
24  *              1 if exists and empty
25  *              2 if exists and contains _only_ dot files
26  *              3 if exists and contains a mount point
27  *              4 if exists and not empty
28  *              -1 if trouble accessing directory (errno reflects the error)
29  */
30 int
31 pg_check_dir(const char *dir)
32 {
33         int                     result = 1;
34         DIR                *chkdir;
35         struct dirent *file;
36         bool            dot_found = false;
37         bool            mount_found = false;
38         int                     readdir_errno;
39
40         chkdir = opendir(dir);
41         if (chkdir == NULL)
42                 return (errno == ENOENT) ? 0 : -1;
43
44         while (errno = 0, (file = readdir(chkdir)) != NULL)
45         {
46                 if (strcmp(".", file->d_name) == 0 ||
47                         strcmp("..", file->d_name) == 0)
48                 {
49                         /* skip this and parent directory */
50                         continue;
51                 }
52 #ifndef WIN32
53                 /* file starts with "." */
54                 else if (file->d_name[0] == '.')
55                 {
56                         dot_found = true;
57                 }
58                 /* lost+found directory */
59                 else if (strcmp("lost+found", file->d_name) == 0)
60                 {
61                         mount_found = true;
62                 }
63 #endif
64                 else
65                 {
66                         result = 4;                     /* not empty */
67                         break;
68                 }
69         }
70
71         if (errno)
72                 result = -1;                    /* some kind of I/O error? */
73
74         /* Close chkdir and avoid overwriting the readdir errno on success */
75         readdir_errno = errno;
76         if (closedir(chkdir))
77                 result = -1;                    /* error executing closedir */
78         else
79                 errno = readdir_errno;
80
81         /* We report on mount point if we find a lost+found directory */
82         if (result == 1 && mount_found)
83                 result = 3;
84
85         /* We report on dot-files if we _only_ find dot files */
86         if (result == 1 && dot_found)
87                 result = 2;
88
89         return result;
90 }