From 4207d6bf300538d4dde2d26b81cbe5deb5473447 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Fri, 9 May 2003 01:16:29 +0000 Subject: [PATCH] Add opendir/readdir/closedir() for Win32. Keep SRA copyright on file because it contains BSD license clause. --- configure | 3 +- configure.in | 5 +- src/include/c.h | 27 +++++++++- src/port/opendir.c | 122 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 153 insertions(+), 4 deletions(-) create mode 100644 src/port/opendir.c diff --git a/configure b/configure index 84e47dc2b0..8764d931f5 100755 --- a/configure +++ b/configure @@ -11257,7 +11257,8 @@ esac # Win32 can't to rename or unlink on an open file case $host_os in win32*) -LIBOBJS="$LIBOBJS dirmod.$ac_objext" ;; +LIBOBJS="$LIBOBJS dirmod.$ac_objext" +LIBOBJS="$LIBOBJS opendir.$ac_objext" ;; esac # On HPUX 9, rint() is not in regular libm.a but in /lib/pa1.1/libm.a; diff --git a/configure.in b/configure.in index e31eb5db78..c209c6ceae 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ dnl Process this file with autoconf to produce a configure script. -dnl $Header: /cvsroot/pgsql/configure.in,v 1.245 2003/05/07 03:47:08 momjian Exp $ +dnl $Header: /cvsroot/pgsql/configure.in,v 1.246 2003/05/09 01:16:29 momjian Exp $ dnl dnl Developers, please strive to achieve this order: dnl @@ -863,7 +863,8 @@ esac # Win32 can't to rename or unlink on an open file case $host_os in win32*) -AC_LIBOBJ(dirmod) ;; +AC_LIBOBJ(dirmod) +AC_LIBOBJ(opendir) ;; esac # On HPUX 9, rint() is not in regular libm.a but in /lib/pa1.1/libm.a; diff --git a/src/include/c.h b/src/include/c.h index 4c9f930cef..a580c90ab2 100644 --- a/src/include/c.h +++ b/src/include/c.h @@ -12,7 +12,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: c.h,v 1.141 2003/04/25 16:18:40 momjian Exp $ + * $Id: c.h,v 1.142 2003/05/09 01:16:29 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -721,6 +721,31 @@ int pgunlink(const char *path); #define unlink(from, to) pgunlink(from, to) #endif +/* + * Win32 doesn't have opendir/readdir/closedir() + */ +#ifdef WIN32 +struct dirent { + ino_t d_ino; /* inode (always 1 on WIN32) */ + char d_name[MAX_PATH + 1]; /* filename (null terminated) */ +}; + +typedef struct { + HANDLE handle; /* handle for FindFirstFile or + * FindNextFile */ + long offset; /* offset into directory */ + int finished; /* 1 if there are not more files */ + WIN32_FIND_DATA finddata; /* file data FindFirstFile or FindNextFile + * returns */ + char *dir; /* the directory path we are reading */ + struct dirent ent; /* the dirent to return */ +} DIR; + +extern DIR *opendir(const char *); +extern struct dirent *readdir(DIR *); +extern int closedir(DIR *); +#endif + /* * Win32 requires a special close for sockets and pipes, while on Unix * close() does them all. diff --git a/src/port/opendir.c b/src/port/opendir.c new file mode 100644 index 0000000000..79ef4d38ac --- /dev/null +++ b/src/port/opendir.c @@ -0,0 +1,122 @@ +/* + * $Header: /cvsroot/pgsql/src/port/Attic/opendir.c,v 1.1 2003/05/09 01:16:29 momjian Exp $ + * + * Copyright (c) 2003 SRA, Inc. + * Copyright (c) 2003 SKC, Inc. + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose, without fee, and without a + * written agreement is hereby granted, provided that the above + * copyright notice and this paragraph and the following two + * paragraphs appear in all copies. + * + * IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, + * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING + * LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS + * DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS + * IS" BASIS, AND THE AUTHOR HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, + * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#include "postgres.h" + +#include +#include +#include + +#include "dirent.h" + +DIR * +opendir(const char *dir) +{ + DIR *dp; + char *findspec; + HANDLE handle; + size_t dirlen; + + dirlen = strlen(dir); + findspec = palloc(dirlen + 2 + 1); + if (findspec == NULL) + return NULL; + + if (dirlen == 0) + strcpy(findspec, "*"); + else if (isalpha(dir[0]) && dir[1] == ':' && dir[2] == '\0') + sprintf(findspec, "%s*", dir); + else if (dir[dirlen - 1] == '/' || dir[dirlen - 1] == '\\') + sprintf(findspec, "%s*", dir); + else + sprintf(findspec, "%s\\*", dir); + + dp = (DIR *)palloc(sizeof(DIR)); + if (dp == NULL) + { + pfree(findspec); + errno = ENOMEM; + return NULL; + } + + dp->offset = 0; + dp->finished = 0; + dp->dir = pstrdup(dir); + if (dp->dir == NULL) + { + pfree(dp); + pfree(findspec); + errno = ENOMEM; + return NULL; + } + + handle = FindFirstFile(findspec, &(dp->finddata)); + if (handle == INVALID_HANDLE_VALUE) + { + pfree(dp->dir); + pfree(dp); + pfree(findspec); + errno = ENOENT; + return NULL; + } + dp->handle = handle; + + pfree(findspec); + return dp; +} + + +struct dirent * +readdir(DIR *dp) +{ + if (dp == NULL || dp->finished) + return NULL; + + if (dp->offset != 0) + { + if (FindNextFile(dp->handle, &(dp->finddata)) == 0) + { + dp->finished = 1; + return NULL; + } + } + dp->offset++; + + strncpy(dp->ent.d_name, dp->finddata.cFileName, MAX_PATH); + dp->ent.d_ino = 1; + + return &(dp->ent); +} + + +int +closedir(DIR *dp) +{ + FindClose(dp->handle); + pfree(dp->dir); + pfree(dp); + + return 0; +}