Header And Logo

PostgreSQL
| The world's most advanced open source database.

pgcheckdir.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * src/port/pgcheckdir.c
00004  *
00005  * A simple subroutine to check whether a directory exists and is empty or not.
00006  * Useful in both initdb and the backend.
00007  *
00008  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00009  * Portions Copyright (c) 1994, Regents of the University of California
00010  *
00011  *-------------------------------------------------------------------------
00012  */
00013 
00014 #include "c.h"
00015 
00016 #include <dirent.h>
00017 
00018 
00019 /*
00020  * Test to see if a directory exists and is empty or not.
00021  *
00022  * Returns:
00023  *      0 if nonexistent
00024  *      1 if exists and empty
00025  *      2 if exists and not empty
00026  *      -1 if trouble accessing directory (errno reflects the error)
00027  */
00028 int
00029 pg_check_dir(const char *dir)
00030 {
00031     int         result = 1;
00032     DIR        *chkdir;
00033     struct dirent *file;
00034     bool        dot_found = false;
00035 
00036     errno = 0;
00037 
00038     chkdir = opendir(dir);
00039 
00040     if (chkdir == NULL)
00041         return (errno == ENOENT) ? 0 : -1;
00042 
00043     while ((file = readdir(chkdir)) != NULL)
00044     {
00045         if (strcmp(".", file->d_name) == 0 ||
00046             strcmp("..", file->d_name) == 0)
00047         {
00048             /* skip this and parent directory */
00049             continue;
00050         }
00051 #ifndef WIN32
00052         /* file starts with "." */
00053         else if (file->d_name[0] == '.')
00054         {
00055             dot_found = true;
00056         }
00057         else if (strcmp("lost+found", file->d_name) == 0)
00058         {
00059             result = 3;         /* not empty, mount point */
00060             break;
00061         }
00062 #endif
00063         else
00064         {
00065             result = 4;         /* not empty */
00066             break;
00067         }
00068     }
00069 
00070 #ifdef WIN32
00071     /*
00072      * This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but not in
00073      * released version
00074      */
00075     if (GetLastError() == ERROR_NO_MORE_FILES)
00076         errno = 0;
00077 #endif
00078 
00079     closedir(chkdir);
00080 
00081     if (errno != 0)
00082         result = -1;            /* some kind of I/O error? */
00083 
00084     /* We report on dot-files if we _only_ find dot files */
00085     if (result == 1 && dot_found)
00086         result = 2;
00087 
00088     return result;
00089 }