LCOV - code coverage report
Current view: top level - src/port - pgcheckdir.c (source / functions) Hit Total Coverage
Test: PostgreSQL 17devel Lines: 24 28 85.7 %
Date: 2024-04-19 20:11:07 Functions: 1 1 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14