Coverage Report

Created: 2025-07-03 06:49

/src/postgres/src/port/pgcheckdir.c
Line
Count
Source (jump to first uncovered line)
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-2025, 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
33
pg_check_dir(const char *dir)
34
0
{
35
0
  int     result = 1;
36
0
  DIR      *chkdir;
37
0
  struct dirent *file;
38
0
  bool    dot_found = false;
39
0
  bool    mount_found = false;
40
0
  int     readdir_errno;
41
42
0
  chkdir = opendir(dir);
43
0
  if (chkdir == NULL)
44
0
    return (errno == ENOENT) ? 0 : -1;
45
46
0
  while (errno = 0, (file = readdir(chkdir)) != NULL)
47
0
  {
48
0
    if (strcmp(".", file->d_name) == 0 ||
49
0
      strcmp("..", file->d_name) == 0)
50
0
    {
51
      /* skip this and parent directory */
52
0
      continue;
53
0
    }
54
0
#ifndef WIN32
55
    /* file starts with "." */
56
0
    else if (file->d_name[0] == '.')
57
0
    {
58
0
      dot_found = true;
59
0
    }
60
    /* lost+found directory */
61
0
    else if (strcmp("lost+found", file->d_name) == 0)
62
0
    {
63
0
      mount_found = true;
64
0
    }
65
0
#endif
66
0
    else
67
0
    {
68
0
      result = 4;     /* not empty */
69
0
      break;
70
0
    }
71
0
  }
72
73
0
  if (errno)
74
0
    result = -1;     /* some kind of I/O error? */
75
76
  /* Close chkdir and avoid overwriting the readdir errno on success */
77
0
  readdir_errno = errno;
78
0
  if (closedir(chkdir))
79
0
    result = -1;     /* error executing closedir */
80
0
  else
81
0
    errno = readdir_errno;
82
83
  /* We report on mount point if we find a lost+found directory */
84
0
  if (result == 1 && mount_found)
85
0
    result = 3;
86
87
  /* We report on dot-files if we _only_ find dot files */
88
0
  if (result == 1 && dot_found)
89
0
    result = 2;
90
91
0
  return result;
92
0
}