Header And Logo

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

dirent.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * dirent.c
00004  *    opendir/readdir/closedir for win32/msvc
00005  *
00006  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00007  * Portions Copyright (c) 1994, Regents of the University of California
00008  *
00009  *
00010  * IDENTIFICATION
00011  *    src/port/dirent.c
00012  *
00013  *-------------------------------------------------------------------------
00014  */
00015 
00016 #ifndef FRONTEND
00017 #include "postgres.h"
00018 #else
00019 #include "postgres_fe.h"
00020 #endif
00021 
00022 #include <dirent.h>
00023 
00024 
00025 struct DIR
00026 {
00027     char       *dirname;
00028     struct dirent ret;          /* Used to return to caller */
00029     HANDLE      handle;
00030 };
00031 
00032 DIR *
00033 opendir(const char *dirname)
00034 {
00035     DWORD       attr;
00036     DIR        *d;
00037 
00038     /* Make sure it is a directory */
00039     attr = GetFileAttributes(dirname);
00040     if (attr == INVALID_FILE_ATTRIBUTES)
00041     {
00042         errno = ENOENT;
00043         return NULL;
00044     }
00045     if ((attr & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY)
00046     {
00047         errno = ENOTDIR;
00048         return NULL;
00049     }
00050 
00051     d = malloc(sizeof(DIR));
00052     if (!d)
00053     {
00054         errno = ENOMEM;
00055         return NULL;
00056     }
00057     d->dirname = malloc(strlen(dirname) + 4);
00058     if (!d->dirname)
00059     {
00060         errno = ENOMEM;
00061         free(d);
00062         return NULL;
00063     }
00064     strcpy(d->dirname, dirname);
00065     if (d->dirname[strlen(d->dirname) - 1] != '/' &&
00066         d->dirname[strlen(d->dirname) - 1] != '\\')
00067         strcat(d->dirname, "\\");       /* Append backslash if not already
00068                                          * there */
00069     strcat(d->dirname, "*");    /* Search for entries named anything */
00070     d->handle = INVALID_HANDLE_VALUE;
00071     d->ret.d_ino = 0;           /* no inodes on win32 */
00072     d->ret.d_reclen = 0;        /* not used on win32 */
00073 
00074     return d;
00075 }
00076 
00077 struct dirent *
00078 readdir(DIR *d)
00079 {
00080     WIN32_FIND_DATA fd;
00081 
00082     if (d->handle == INVALID_HANDLE_VALUE)
00083     {
00084         d->handle = FindFirstFile(d->dirname, &fd);
00085         if (d->handle == INVALID_HANDLE_VALUE)
00086         {
00087             errno = ENOENT;
00088             return NULL;
00089         }
00090     }
00091     else
00092     {
00093         if (!FindNextFile(d->handle, &fd))
00094         {
00095             if (GetLastError() == ERROR_NO_MORE_FILES)
00096             {
00097                 /* No more files, force errno=0 (unlike mingw) */
00098                 errno = 0;
00099                 return NULL;
00100             }
00101             _dosmaperr(GetLastError());
00102             return NULL;
00103         }
00104     }
00105     strcpy(d->ret.d_name, fd.cFileName);        /* Both strings are MAX_PATH
00106                                                  * long */
00107     d->ret.d_namlen = strlen(d->ret.d_name);
00108     return &d->ret;
00109 }
00110 
00111 int
00112 closedir(DIR *d)
00113 {
00114     if (d->handle != INVALID_HANDLE_VALUE)
00115         FindClose(d->handle);
00116     free(d->dirname);
00117     free(d);
00118     return 0;
00119 }