Age Owner Branch data TLA Line data Source code
1 : : /*-------------------------------------------------------------------------
2 : : *
3 : : * 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-2024, PostgreSQL Global Development Group
9 : : * Portions Copyright (c) 1994, Regents of the University of California
10 : : *
11 : : * IDENTIFICATION
12 : : * src/port/pgcheckdir.c
13 : : *-------------------------------------------------------------------------
14 : : */
15 : :
16 : : #include "c.h"
17 : :
18 : : #include <dirent.h>
19 : :
20 : :
21 : : /*
22 : : * Test to see if a directory exists and is empty or not.
23 : : *
24 : : * Returns:
25 : : * 0 if nonexistent
26 : : * 1 if exists and empty
27 : : * 2 if exists and contains _only_ dot files
28 : : * 3 if exists and contains a mount point
29 : : * 4 if exists and not empty
30 : : * -1 if trouble accessing directory (errno reflects the error)
31 : : */
32 : : int
4874 tgl@sss.pgh.pa.us 33 :CBC 253 : pg_check_dir(const char *dir)
34 : : {
35 : 253 : int result = 1;
36 : : DIR *chkdir;
37 : : struct dirent *file;
4075 bruce@momjian.us 38 : 253 : bool dot_found = false;
3344 rhaas@postgresql.org 39 : 253 : bool mount_found = false;
40 : : int readdir_errno;
41 : :
4874 tgl@sss.pgh.pa.us 42 : 253 : chkdir = opendir(dir);
43 [ + + ]: 253 : if (chkdir == NULL)
44 [ + - ]: 226 : return (errno == ENOENT) ? 0 : -1;
45 : :
3677 bruce@momjian.us 46 [ + + ]: 82 : while (errno = 0, (file = readdir(chkdir)) != NULL)
47 : : {
4874 tgl@sss.pgh.pa.us 48 [ + + ]: 60 : if (strcmp(".", file->d_name) == 0 ||
49 [ + + ]: 33 : strcmp("..", file->d_name) == 0)
50 : : {
51 : : /* skip this and parent directory */
52 : 54 : continue;
53 : : }
54 : : #ifndef WIN32
55 : : /* file starts with "." */
4075 bruce@momjian.us 56 [ - + ]: 6 : else if (file->d_name[0] == '.')
57 : : {
4075 bruce@momjian.us 58 :UBC 0 : dot_found = true;
59 : : }
60 : : /* lost+found directory */
4075 bruce@momjian.us 61 [ + + ]:CBC 6 : else if (strcmp("lost+found", file->d_name) == 0)
62 : : {
3344 rhaas@postgresql.org 63 : 1 : mount_found = true;
64 : : }
65 : : #endif
66 : : else
67 : : {
4075 bruce@momjian.us 68 : 5 : result = 4; /* not empty */
4874 tgl@sss.pgh.pa.us 69 : 5 : break;
70 : : }
71 : : }
72 : :
3344 rhaas@postgresql.org 73 [ - + ]: 27 : if (errno)
4874 tgl@sss.pgh.pa.us 74 :UBC 0 : result = -1; /* some kind of I/O error? */
75 : :
76 : : /* Close chkdir and avoid overwriting the readdir errno on success */
3344 rhaas@postgresql.org 77 :CBC 27 : readdir_errno = errno;
78 [ - + ]: 27 : if (closedir(chkdir))
3344 rhaas@postgresql.org 79 :UBC 0 : result = -1; /* error executing closedir */
80 : : else
3344 rhaas@postgresql.org 81 :CBC 27 : errno = readdir_errno;
82 : :
83 : : /* We report on mount point if we find a lost+found directory */
84 [ + + + + ]: 27 : if (result == 1 && mount_found)
85 : 1 : result = 3;
86 : :
87 : : /* We report on dot-files if we _only_ find dot files */
4075 bruce@momjian.us 88 [ + + - + ]: 27 : if (result == 1 && dot_found)
4075 bruce@momjian.us 89 :UBC 0 : result = 2;
90 : :
4874 tgl@sss.pgh.pa.us 91 :CBC 27 : return result;
92 : : }
|