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-2019, 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) whitespaceEqual(a: str, b: str)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 getNumFromStr(usrStr: str, numbers: str = '0123456789')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; hyphenToCamelCase(usrStr: str, replacement: str = '-')88 89 return result; 90 } 91