includes error checking and an appropriate ereport(ERROR) message.
This gets rid of rather tedious and error-prone manipulation of errno,
as well as a Windows-specific bug workaround, at more than a dozen
call sites. After an idea in a recent patch by Heikki Linnakangas.
* Copyright (c) 2002-2005, PostgreSQL Global Development Group
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/contrib/dbsize/dbsize.c,v 1.17 2005/05/27 00:57:48 neilc Exp $
+ * $PostgreSQL: pgsql/contrib/dbsize/dbsize.c,v 1.18 2005/06/19 21:34:00 tgl Exp $
*
*/
if (!dirdesc)
return 0;
- while ((direntry = readdir(dirdesc)) != NULL)
+ while ((direntry = ReadDir(dirdesc, path)) != NULL)
{
struct stat fst;
/* Scan the non-default tablespaces */
snprintf(pathname, MAXPGPATH, "%s/pg_tblspc", DataDir);
dirdesc = AllocateDir(pathname);
- if (!dirdesc)
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not open tablespace directory \"%s\": %m",
- pathname)));
- while ((direntry = readdir(dirdesc)) != NULL)
+ while ((direntry = ReadDir(dirdesc, pathname)) != NULL)
{
if (strcmp(direntry->d_name, ".") == 0 ||
strcmp(direntry->d_name, "..") == 0)
dirdesc = AllocateDir(tblspcPath);
- if (!dirdesc)
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not open tablespace directory \"%s\": %m",
- tblspcPath)));
-
- while ((direntry = readdir(dirdesc)) != NULL)
+ while ((direntry = ReadDir(dirdesc, tblspcPath)) != NULL)
{
struct stat fst;
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/backend/access/transam/slru.c,v 1.24 2005/02/12 23:53:37 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/slru.c,v 1.25 2005/06/19 21:34:01 tgl Exp $
*
*-------------------------------------------------------------------------
*/
cutoffPage -= cutoffPage % SLRU_PAGES_PER_SEGMENT;
cldir = AllocateDir(ctl->Dir);
- if (cldir == NULL)
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not open directory \"%s\": %m",
- ctl->Dir)));
-
- errno = 0;
- while ((clde = readdir(cldir)) != NULL)
+ while ((clde = ReadDir(cldir, ctl->Dir)) != NULL)
{
if (strlen(clde->d_name) == 4 &&
strspn(clde->d_name, "0123456789ABCDEF") == 4)
}
}
}
- errno = 0;
}
-#ifdef WIN32
-
- /*
- * This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but
- * not in released version
- */
- if (GetLastError() == ERROR_NO_MORE_FILES)
- errno = 0;
-#endif
- if (errno)
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not read directory \"%s\": %m", ctl->Dir)));
FreeDir(cldir);
return found;
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/transam/twophase.c,v 1.4 2005/06/19 20:00:38 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/twophase.c,v 1.5 2005/06/19 21:34:01 tgl Exp $
*
* NOTES
* Each global transaction is associated with a global transaction
snprintf(dir, MAXPGPATH, "%s/%s", DataDir, TWOPHASE_DIR);
cldir = AllocateDir(dir);
- if (cldir == NULL)
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not open directory \"%s\": %m", dir)));
-
- errno = 0;
- while ((clde = readdir(cldir)) != NULL)
+ while ((clde = ReadDir(cldir, dir)) != NULL)
{
if (strlen(clde->d_name) == 8 &&
strspn(clde->d_name, "0123456789ABCDEF") == 8)
(errmsg("removing future twophase state file \"%s\"",
clde->d_name)));
RemoveTwoPhaseFile(xid, true);
- errno = 0;
continue;
}
(errmsg("removing corrupt twophase state file \"%s\"",
clde->d_name)));
RemoveTwoPhaseFile(xid, true);
- errno = 0;
continue;
}
clde->d_name)));
RemoveTwoPhaseFile(xid, true);
pfree(buf);
- errno = 0;
continue;
}
pfree(buf);
}
- errno = 0;
}
-#ifdef WIN32
-
- /*
- * This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but
- * not in released version
- */
- if (GetLastError() == ERROR_NO_MORE_FILES)
- errno = 0;
-#endif
- if (errno)
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not read directory \"%s\": %m", dir)));
-
FreeDir(cldir);
return result;
snprintf(dir, MAXPGPATH, "%s/%s", DataDir, TWOPHASE_DIR);
cldir = AllocateDir(dir);
- if (cldir == NULL)
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not open directory \"%s\": %m", dir)));
-
- errno = 0;
- while ((clde = readdir(cldir)) != NULL)
+ while ((clde = ReadDir(cldir, dir)) != NULL)
{
if (strlen(clde->d_name) == 8 &&
strspn(clde->d_name, "0123456789ABCDEF") == 8)
(errmsg("removing stale twophase state file \"%s\"",
clde->d_name)));
RemoveTwoPhaseFile(xid, true);
- errno = 0;
continue;
}
(errmsg("removing corrupt twophase state file \"%s\"",
clde->d_name)));
RemoveTwoPhaseFile(xid, true);
- errno = 0;
continue;
}
pfree(buf);
}
- errno = 0;
}
-#ifdef WIN32
-
- /*
- * This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but
- * not in released version
- */
- if (GetLastError() == ERROR_NO_MORE_FILES)
- errno = 0;
-#endif
- if (errno)
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not read directory \"%s\": %m", dir)));
-
FreeDir(cldir);
}
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.202 2005/06/19 20:00:38 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.203 2005/06/19 21:34:01 tgl Exp $
*
*-------------------------------------------------------------------------
*/
XLogFileName(lastoff, ThisTimeLineID, log, seg);
- errno = 0;
- while ((xlde = readdir(xldir)) != NULL)
+ while ((xlde = ReadDir(xldir, XLogDir)) != NULL)
{
/*
* We ignore the timeline part of the XLOG segment identifiers in
XLogArchiveCleanup(xlde->d_name);
}
}
- errno = 0;
}
-#ifdef WIN32
- /*
- * This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but
- * not in released version
- */
- if (GetLastError() == ERROR_NO_MORE_FILES)
- errno = 0;
-#endif
- if (errno)
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not read transaction log directory \"%s\": %m",
- XLogDir)));
FreeDir(xldir);
}
errmsg("could not open transaction log directory \"%s\": %m",
XLogDir)));
- errno = 0;
- while ((xlde = readdir(xldir)) != NULL)
+ while ((xlde = ReadDir(xldir, XLogDir)) != NULL)
{
if (strlen(xlde->d_name) > 24 &&
strspn(xlde->d_name, "0123456789ABCDEF") == 24 &&
XLogArchiveCleanup(xlde->d_name);
}
}
- errno = 0;
}
-#ifdef WIN32
- /*
- * This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but
- * not in released version
- */
- if (GetLastError() == ERROR_NO_MORE_FILES)
- errno = 0;
-#endif
- if (errno)
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not read transaction log directory \"%s\": %m",
- XLogDir)));
FreeDir(xldir);
}
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.21 2005/06/06 20:22:57 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.22 2005/06/19 21:34:01 tgl Exp $
*
*-------------------------------------------------------------------------
*/
pfree(location);
return true;
}
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not open directory \"%s\": %m",
- location)));
+ /* else let ReadDir report the error */
}
- errno = 0;
- while ((de = readdir(dirdesc)) != NULL)
+ while ((de = ReadDir(dirdesc, location)) != NULL)
{
/* Note we ignore PG_VERSION for the nonce */
if (strcmp(de->d_name, ".") == 0 ||
strcmp(de->d_name, "..") == 0 ||
strcmp(de->d_name, "PG_VERSION") == 0)
- {
- errno = 0;
continue;
- }
subfile = palloc(strlen(location) + 1 + strlen(de->d_name) + 1);
sprintf(subfile, "%s/%s", location, de->d_name);
subfile)));
pfree(subfile);
- errno = 0;
}
-#ifdef WIN32
- /*
- * This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but
- * not in released version
- */
- if (GetLastError() == ERROR_NO_MORE_FILES)
- errno = 0;
-#endif
- if (errno)
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not read directory \"%s\": %m",
- location)));
FreeDir(dirdesc);
/*
struct dirent *de;
dirdesc = AllocateDir(path);
- if (dirdesc == NULL)
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not open directory \"%s\": %m",
- path)));
- errno = 0;
- while ((de = readdir(dirdesc)) != NULL)
+ while ((de = ReadDir(dirdesc, path)) != NULL)
{
if (strcmp(de->d_name, ".") == 0 ||
strcmp(de->d_name, "..") == 0)
- {
- errno = 0;
continue;
- }
FreeDir(dirdesc);
return false;
}
-#ifdef WIN32
- /*
- * This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but
- * not in released version
- */
- if (GetLastError() == ERROR_NO_MORE_FILES)
- errno = 0;
-#endif
- if (errno)
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not read directory \"%s\": %m",
- path)));
FreeDir(dirdesc);
return true;
}
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/postmaster/pgarch.c,v 1.15 2005/03/10 07:14:03 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/postmaster/pgarch.c,v 1.16 2005/06/19 21:34:01 tgl Exp $
*
*-------------------------------------------------------------------------
*/
errmsg("could not open archive status directory \"%s\": %m",
XLogArchiveStatusDir)));
- errno = 0;
- while ((rlde = readdir(rldir)) != NULL)
+ while ((rlde = ReadDir(rldir, XLogArchiveStatusDir)) != NULL)
{
int basenamelen = (int) strlen(rlde->d_name) - 6;
strcpy(newxlog, rlde->d_name);
}
}
-
- errno = 0;
}
-#ifdef WIN32
-
- /*
- * This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but
- * not in released version
- */
- if (GetLastError() == ERROR_NO_MORE_FILES)
- errno = 0;
-#endif
- if (errno)
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not read archive status directory \"%s\": %m",
- XLogArchiveStatusDir)));
FreeDir(rldir);
if (found)
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/file/fd.c,v 1.116 2005/05/20 14:53:26 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/file/fd.c,v 1.117 2005/06/19 21:34:02 tgl Exp $
*
* NOTES:
*
return NULL;
}
+/*
+ * Read a directory opened with AllocateDir, ereport'ing any error.
+ *
+ * This is easier to use than raw readdir() since it takes care of some
+ * otherwise rather tedious and error-prone manipulation of errno. Also,
+ * if you are happy with a generic error message for AllocateDir failure,
+ * you can just do
+ *
+ * dir = AllocateDir(path);
+ * while ((dirent = ReadDir(dir, path)) != NULL)
+ * process dirent;
+ * FreeDir(path);
+ *
+ * since a NULL dir parameter is taken as indicating AllocateDir failed.
+ * (Make sure errno hasn't been changed since AllocateDir if you use this
+ * shortcut.)
+ *
+ * The pathname passed to AllocateDir must be passed to this routine too,
+ * but it is only used for error reporting.
+ */
+struct dirent *
+ReadDir(DIR *dir, const char *dirname)
+{
+ struct dirent *dent;
+
+ /* Give a generic message for AllocateDir failure, if caller didn't */
+ if (dir == NULL)
+ ereport(ERROR,
+ (errcode_for_file_access(),
+ errmsg("could not open directory \"%s\": %m",
+ dirname)));
+
+ errno = 0;
+ if ((dent = readdir(dir)) != NULL)
+ return dent;
+
+#ifdef WIN32
+ /*
+ * This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but
+ * not in released version
+ */
+ if (GetLastError() == ERROR_NO_MORE_FILES)
+ errno = 0;
+#endif
+
+ if (errno)
+ ereport(ERROR,
+ (errcode_for_file_access(),
+ errmsg("could not read directory \"%s\": %m",
+ dirname)));
+ return NULL;
+}
+
/*
* Close a directory opened with AllocateDir.
*
*/
snprintf(db_path, sizeof(db_path), "%s/base", DataDir);
db_dir = AllocateDir(db_path);
- if (db_dir == NULL)
- {
- /* this really should not happen */
- elog(LOG, "could not open directory \"%s\": %m", db_path);
- return;
- }
- while ((db_de = readdir(db_dir)) != NULL)
+ while ((db_de = ReadDir(db_dir, db_path)) != NULL)
{
if (strcmp(db_de->d_name, ".") == 0 ||
strcmp(db_de->d_name, "..") == 0)
return;
}
- while ((temp_de = readdir(temp_dir)) != NULL)
+ while ((temp_de = ReadDir(temp_dir, tmpdirname)) != NULL)
{
if (strcmp(temp_de->d_name, ".") == 0 ||
strcmp(temp_de->d_name, "..") == 0)
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/misc.c,v 1.43 2005/05/19 21:35:47 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/misc.c,v 1.44 2005/06/19 21:34:02 tgl Exp $
*
*-------------------------------------------------------------------------
*/
if (!fctx->dirdesc) /* not a tablespace */
SRF_RETURN_DONE(funcctx);
- while ((de = readdir(fctx->dirdesc)) != NULL)
+ while ((de = ReadDir(fctx->dirdesc, fctx->location)) != NULL)
{
char *subdir;
DIR *dirdesc;
-
Oid datOid = atooid(de->d_name);
/* this test skips . and .., but is awfully weak */
subdir = palloc(strlen(fctx->location) + 1 + strlen(de->d_name) + 1);
sprintf(subdir, "%s/%s", fctx->location, de->d_name);
dirdesc = AllocateDir(subdir);
- pfree(subdir);
- if (!dirdesc)
- continue; /* XXX more sloppiness */
-
- while ((de = readdir(dirdesc)) != 0)
+ while ((de = ReadDir(dirdesc, subdir)) != NULL)
{
if (strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..") != 0)
break;
}
FreeDir(dirdesc);
+ pfree(subdir);
if (!de)
continue; /* indeed, nothing in it */
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/storage/fd.h,v 1.51 2005/05/20 14:53:26 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/storage/fd.h,v 1.52 2005/06/19 21:34:03 tgl Exp $
*
*-------------------------------------------------------------------------
*/
/* Operations to allow use of the library routines */
extern DIR *AllocateDir(const char *dirname);
+extern struct dirent *ReadDir(DIR *dir, const char *dirname);
extern int FreeDir(DIR *dir);
/* If you've really really gotta have a plain kernel FD, use this */
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/timezone/pgtz.c,v 1.33 2005/06/15 00:09:26 momjian Exp $
+ * $PostgreSQL: pgsql/src/timezone/pgtz.c,v 1.34 2005/06/19 21:34:03 tgl Exp $
*
*-------------------------------------------------------------------------
*/
* score. bestzonename must be a buffer of length TZ_STRLEN_MAX + 1.
*/
static void
-scan_available_timezones(char *tzdir, char *tzdirsub, struct tztry * tt,
+scan_available_timezones(char *tzdir, char *tzdirsub, struct tztry *tt,
int *bestscore, char *bestzonename)
{
int tzdir_orig_len = strlen(tzdir);
DIR *dirdesc;
+ struct dirent *direntry;
dirdesc = AllocateDir(tzdir);
if (!dirdesc)
return;
}
- for (;;)
+ while ((direntry = ReadDir(dirdesc, tzdir)) != NULL)
{
- struct dirent *direntry;
struct stat statbuf;
- errno = 0;
- direntry = readdir(dirdesc);
- if (!direntry)
- {
- if (errno)
- ereport(LOG,
- (errcode_for_file_access(),
- errmsg("error reading directory: %m")));
- break;
- }
-
/* Ignore . and .., plus any other "hidden" files */
if (direntry->d_name[0] == '.')
continue;
ereport(LOG,
(errcode_for_file_access(),
errmsg("could not stat \"%s\": %m", tzdir)));
+ tzdir[tzdir_orig_len] = '\0';
continue;
}
StrNCpy(bestzonename, tzdirsub, TZ_STRLEN_MAX + 1);
}
}
+
+ /* Restore tzdir */
+ tzdir[tzdir_orig_len] = '\0';
}
FreeDir(dirdesc);
-
- /* Restore tzdir */
- tzdir[tzdir_orig_len] = '\0';
}
#else /* WIN32 */