It requires pgfnames() from libpgcommon.
# src/bin/initdb/nls.mk
CATALOG_NAME = initdb
AVAIL_LANGUAGES = cs de es fr it ja pl pt_BR ru zh_CN
-GETTEXT_FILES = findtimezone.c initdb.c ../../common/exec.c ../../common/fe_memutils.c ../../common/pgfnames.c ../../common/wait_error.c ../../port/dirmod.c
+GETTEXT_FILES = findtimezone.c initdb.c ../../common/exec.c ../../common/fe_memutils.c ../../common/pgfnames.c ../../common/rmtree.c ../../common/wait_error.c ../../port/dirmod.c
GETTEXT_TRIGGERS = simple_prompt
override CPPFLAGS := -DFRONTEND $(CPPFLAGS)
LIBS += $(PTHREAD_LIBS)
-OBJS_COMMON = exec.o pgfnames.o relpath.o wait_error.o
+OBJS_COMMON = exec.o pgfnames.o relpath.o rmtree.o wait_error.o
OBJS_FRONTEND = $(OBJS_COMMON) fe_memutils.o
--- /dev/null
+/*-------------------------------------------------------------------------
+ *
+ * rmtree.c
+ *
+ * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * IDENTIFICATION
+ * src/common/rmtree.c
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef FRONTEND
+#include "postgres.h"
+#else
+#include "postgres_fe.h"
+#endif
+
+#include <unistd.h>
+#include <sys/stat.h>
+
+
+/*
+ * rmtree
+ *
+ * Delete a directory tree recursively.
+ * Assumes path points to a valid directory.
+ * Deletes everything under path.
+ * If rmtopdir is true deletes the directory too.
+ * Returns true if successful, false if there was any problem.
+ * (The details of the problem are reported already, so caller
+ * doesn't really have to say anything more, but most do.)
+ */
+bool
+rmtree(const char *path, bool rmtopdir)
+{
+ bool result = true;
+ char pathbuf[MAXPGPATH];
+ char **filenames;
+ char **filename;
+ struct stat statbuf;
+
+ /*
+ * we copy all the names out of the directory before we start modifying
+ * it.
+ */
+ filenames = pgfnames(path);
+
+ if (filenames == NULL)
+ return false;
+
+ /* now we have the names we can start removing things */
+ for (filename = filenames; *filename; filename++)
+ {
+ snprintf(pathbuf, MAXPGPATH, "%s/%s", path, *filename);
+
+ /*
+ * It's ok if the file is not there anymore; we were just about to
+ * delete it anyway.
+ *
+ * This is not an academic possibility. One scenario where this
+ * happens is when bgwriter has a pending unlink request for a file in
+ * a database that's being dropped. In dropdb(), we call
+ * ForgetDatabaseFsyncRequests() to flush out any such pending unlink
+ * requests, but because that's asynchronous, it's not guaranteed that
+ * the bgwriter receives the message in time.
+ */
+ if (lstat(pathbuf, &statbuf) != 0)
+ {
+ if (errno != ENOENT)
+ {
+#ifndef FRONTEND
+ elog(WARNING, "could not stat file or directory \"%s\": %m",
+ pathbuf);
+#else
+ fprintf(stderr, _("could not stat file or directory \"%s\": %s\n"),
+ pathbuf, strerror(errno));
+#endif
+ result = false;
+ }
+ continue;
+ }
+
+ if (S_ISDIR(statbuf.st_mode))
+ {
+ /* call ourselves recursively for a directory */
+ if (!rmtree(pathbuf, true))
+ {
+ /* we already reported the error */
+ result = false;
+ }
+ }
+ else
+ {
+ if (unlink(pathbuf) != 0)
+ {
+ if (errno != ENOENT)
+ {
+#ifndef FRONTEND
+ elog(WARNING, "could not remove file or directory \"%s\": %m",
+ pathbuf);
+#else
+ fprintf(stderr, _("could not remove file or directory \"%s\": %s\n"),
+ pathbuf, strerror(errno));
+#endif
+ result = false;
+ }
+ }
+ }
+ }
+
+ if (rmtopdir)
+ {
+ if (rmdir(path) != 0)
+ {
+#ifndef FRONTEND
+ elog(WARNING, "could not remove file or directory \"%s\": %m",
+ path);
+#else
+ fprintf(stderr, _("could not remove file or directory \"%s\": %s\n"),
+ path, strerror(errno));
+#endif
+ result = false;
+ }
+ }
+
+ pgfnames_cleanup(filenames);
+
+ return result;
+}
#endif /* defined(WIN32) && !defined(__CYGWIN__) */
-/*
- * rmtree
- *
- * Delete a directory tree recursively.
- * Assumes path points to a valid directory.
- * Deletes everything under path.
- * If rmtopdir is true deletes the directory too.
- * Returns true if successful, false if there was any problem.
- * (The details of the problem are reported already, so caller
- * doesn't really have to say anything more, but most do.)
- */
-bool
-rmtree(const char *path, bool rmtopdir)
-{
- bool result = true;
- char pathbuf[MAXPGPATH];
- char **filenames;
- char **filename;
- struct stat statbuf;
-
- /*
- * we copy all the names out of the directory before we start modifying
- * it.
- */
- filenames = pgfnames(path);
-
- if (filenames == NULL)
- return false;
-
- /* now we have the names we can start removing things */
- for (filename = filenames; *filename; filename++)
- {
- snprintf(pathbuf, MAXPGPATH, "%s/%s", path, *filename);
-
- /*
- * It's ok if the file is not there anymore; we were just about to
- * delete it anyway.
- *
- * This is not an academic possibility. One scenario where this
- * happens is when bgwriter has a pending unlink request for a file in
- * a database that's being dropped. In dropdb(), we call
- * ForgetDatabaseFsyncRequests() to flush out any such pending unlink
- * requests, but because that's asynchronous, it's not guaranteed that
- * the bgwriter receives the message in time.
- */
- if (lstat(pathbuf, &statbuf) != 0)
- {
- if (errno != ENOENT)
- {
-#ifndef FRONTEND
- elog(WARNING, "could not stat file or directory \"%s\": %m",
- pathbuf);
-#else
- fprintf(stderr, _("could not stat file or directory \"%s\": %s\n"),
- pathbuf, strerror(errno));
-#endif
- result = false;
- }
- continue;
- }
-
- if (S_ISDIR(statbuf.st_mode))
- {
- /* call ourselves recursively for a directory */
- if (!rmtree(pathbuf, true))
- {
- /* we already reported the error */
- result = false;
- }
- }
- else
- {
- if (unlink(pathbuf) != 0)
- {
- if (errno != ENOENT)
- {
-#ifndef FRONTEND
- elog(WARNING, "could not remove file or directory \"%s\": %m",
- pathbuf);
-#else
- fprintf(stderr, _("could not remove file or directory \"%s\": %s\n"),
- pathbuf, strerror(errno));
-#endif
- result = false;
- }
- }
- }
- }
-
- if (rmtopdir)
- {
- if (rmdir(path) != 0)
- {
-#ifndef FRONTEND
- elog(WARNING, "could not remove file or directory \"%s\": %m",
- path);
-#else
- fprintf(stderr, _("could not remove file or directory \"%s\": %s\n"),
- path, strerror(errno));
-#endif
- result = false;
- }
- }
-
- pgfnames_cleanup(filenames);
-
- return result;
-}
-
-
#if defined(WIN32) && !defined(__CYGWIN__)
#undef stat
win32error.c win32setlocale.c);
our @pgcommonallfiles = qw(
- exec.c pgfnames.c relpath.c wait_error.c);
+ exec.c pgfnames.c relpath.c rmtree.c wait_error.c);
our @pgcommonfrontendfiles = (@pgcommonallfiles, qw(fe_memutils.c));