Re: [HACKERS] Cannot initdb in cvs tip - Mailing list pgsql-patches
| From | Andrew Dunstan |
|---|---|
| Subject | Re: [HACKERS] Cannot initdb in cvs tip |
| Date | |
| Msg-id | 4107E3C2.6060301@dunslane.net Whole thread Raw |
| In response to | Re: [HACKERS] Cannot initdb in cvs tip (Bruce Momjian <pgman@candle.pha.pa.us>) |
| Responses |
Re: [HACKERS] Cannot initdb in cvs tip
Re: [HACKERS] Cannot initdb in cvs tip |
| List | pgsql-patches |
Bruce Momjian wrote:
>Andrew Dunstan wrote:
>
>
>>>I wanted to keep a solution that was as native to the OS as possible,
>>>but because we can't do that on Win32 and few people like the unix
>>>system call to 'rm', it is time to clean it up.
>>>
>>>One question --- why is there a sleep loop needed for unlink in your
>>>patch?
>>>
>>>
>>>
>>>
>>>
>>>
>>We will just be calling the existing pgunlink() (which has a sleep) in
>>the Windows cases, so this question becomes moot.
>>
>>
>
>Great. Thanks. Sorry I delayed addressing this for so long.
>
>
Please check the enclosed patch to see if it does what you want.
>Should we look at replacing cp/copy in 7.6?
>
>
>
probably. Put it as a possible TODO maybe.
cheers
andrew
Index: src/Makefile.global.in
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/Makefile.global.in,v
retrieving revision 1.189
diff -c -r1.189 Makefile.global.in
*** src/Makefile.global.in 2 Jun 2004 21:05:52 -0000 1.189
--- src/Makefile.global.in 28 Jul 2004 17:29:31 -0000
***************
*** 340,346 ****
#
# substitute implementations of the C library
! LIBOBJS = @LIBOBJS@ exec.o noblock.o path.o pipe.o pgsleep.o pgstrcasecmp.o sprompt.o thread.o
ifneq (,$(LIBOBJS))
LIBS := -lpgport $(LIBS)
--- 340,346 ----
#
# substitute implementations of the C library
! LIBOBJS = @LIBOBJS@ dirmod.o exec.o noblock.o path.o pipe.o pgsleep.o pgstrcasecmp.o sprompt.o thread.o
ifneq (,$(LIBOBJS))
LIBS := -lpgport $(LIBS)
Index: src/backend/commands/dbcommands.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/backend/commands/dbcommands.c,v
retrieving revision 1.137
diff -c -r1.137 dbcommands.c
*** src/backend/commands/dbcommands.c 25 Jun 2004 21:55:53 -0000 1.137
--- src/backend/commands/dbcommands.c 28 Jul 2004 17:29:32 -0000
***************
*** 915,921 ****
Relation rel;
HeapScanDesc scan;
HeapTuple tuple;
- char buf[MAXPGPATH + 100];
rel = heap_openr(TableSpaceRelationName, AccessShareLock);
scan = heap_beginscan(rel, SnapshotNow, 0, NULL);
--- 915,920 ----
***************
*** 938,954 ****
continue;
}
! #ifndef WIN32
! snprintf(buf, sizeof(buf), "rm -rf '%s'", dstpath);
! #else
! snprintf(buf, sizeof(buf), "rmdir /s /q \"%s\"", dstpath);
! #endif
! if (system(buf) != 0)
{
ereport(WARNING,
(errmsg("could not remove database directory \"%s\"",
dstpath),
- errdetail("Failing system command was: %s", buf),
errhint("Look in the postmaster's stderr log for more information.")));
}
--- 937,947 ----
continue;
}
! if (! rmtree(dstpath,true) )
{
ereport(WARNING,
(errmsg("could not remove database directory \"%s\"",
dstpath),
errhint("Look in the postmaster's stderr log for more information.")));
}
Index: src/bin/initdb/Makefile
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/bin/initdb/Makefile,v
retrieving revision 1.41
diff -c -r1.41 Makefile
*** src/bin/initdb/Makefile 24 May 2004 01:01:37 -0000 1.41
--- src/bin/initdb/Makefile 28 Jul 2004 17:29:32 -0000
***************
*** 15,21 ****
override CPPFLAGS := -DFRONTEND -I$(libpq_srcdir) $(CPPFLAGS)
! OBJS= initdb.o exec.o
all: submake-libpq submake-libpgport initdb
--- 15,21 ----
override CPPFLAGS := -DFRONTEND -I$(libpq_srcdir) $(CPPFLAGS)
! OBJS= initdb.o exec.o dirmod.o
all: submake-libpq submake-libpgport initdb
***************
*** 25,30 ****
--- 25,33 ----
exec.c: % : $(top_srcdir)/src/port/%
rm -f $@ && $(LN_S) $< .
+ dirmod.c: % : $(top_srcdir)/src/port/%
+ rm -f $@ && $(LN_S) $< .
+
install: all installdirs
$(INSTALL_PROGRAM) initdb$(X) $(DESTDIR)$(bindir)/initdb$(X)
Index: src/bin/initdb/initdb.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/bin/initdb/initdb.c,v
retrieving revision 1.44
diff -c -r1.44 initdb.c
*** src/bin/initdb/initdb.c 19 Jul 2004 02:47:12 -0000 1.44
--- src/bin/initdb/initdb.c 28 Jul 2004 17:29:32 -0000
***************
*** 135,141 ****
static void *xmalloc(size_t size);
static char *xstrdup(const char *s);
- static bool rmtree(char *path, bool rmtopdir);
static char **replace_token(char **lines, char *token, char *replacement);
static char **readfile(char *path);
static void writefile(char *path, char **lines);
--- 135,140 ----
***************
*** 241,270 ****
}
/*
- * delete a directory tree recursively
- * assumes path points to a valid directory
- * deletes everything under path
- * if rmtopdir is true deletes the directory too
- */
- static bool
- rmtree(char *path, bool rmtopdir)
- {
- char buf[MAXPGPATH + 64];
-
- #ifndef WIN32
- /* doesn't handle .* files, but we don't make any... */
- snprintf(buf, sizeof(buf), "rm -rf \"%s\"%s", path,
- rmtopdir ? "" : "/*");
- #else
- snprintf(buf, sizeof(buf), "%s /s /q \"%s\"",
- rmtopdir ? "rmdir" : "del", path);
- #endif
-
- return !system(buf);
- }
-
-
- /*
* make a copy of the array of lines, with token replaced by replacement
* the first time it occurs on each line.
*
--- 240,245 ----
Index: src/include/port.h
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/include/port.h,v
retrieving revision 1.45
diff -c -r1.45 port.h
*** src/include/port.h 23 Jul 2004 01:58:36 -0000 1.45
--- src/include/port.h 28 Jul 2004 17:29:32 -0000
***************
*** 148,153 ****
--- 148,155 ----
#define unlink(path) pgunlink(path)
#endif
+ extern bool rmtree(char *path, bool rmtopdir);
+
#ifdef WIN32
/* open() replacement to allow delete of held files */
Index: src/port/dirmod.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/port/dirmod.c,v
retrieving revision 1.12
diff -c -r1.12 dirmod.c
*** src/port/dirmod.c 26 Feb 2004 02:59:26 -0000 1.12
--- src/port/dirmod.c 28 Jul 2004 17:29:32 -0000
***************
*** 15,30 ****
*-------------------------------------------------------------------------
*/
- #ifndef TEST_VERSION
-
- #if defined(WIN32) || defined(__CYGWIN__)
-
-
#ifndef FRONTEND
#include "postgres.h"
#else
#include "postgres_fe.h"
#endif
#include "miscadmin.h"
#undef rename
--- 15,37 ----
*-------------------------------------------------------------------------
*/
#ifndef FRONTEND
#include "postgres.h"
#else
#include "postgres_fe.h"
#endif
+
+ #include <unistd.h>
+ #include <dirent.h>
+ #include <sys/stat.h>
+
+ #define _(x) gettext((x))
+
+ #ifndef TEST_VERSION
+
+ #if defined(WIN32) || defined(__CYGWIN__)
+
+
#include "miscadmin.h"
#undef rename
***************
*** 105,110 ****
--- 112,277 ----
#endif
+ #if defined(WIN32) || defined(__CYGWIN__)
+ #define rmt_unlink(path) pgunlink(path)
+ #else
+ #define rmt_unlink(path) unlink(path)
+ #endif
+
+ #ifdef FRONTEND
+
+ static void *
+ xmalloc(size_t size)
+ {
+ void *result;
+
+ result = malloc(size);
+ if (!result)
+ {
+ fprintf(stderr, _("out of memory\n"));
+ exit(1);
+ }
+ return result;
+ }
+
+ static char *
+ xstrdup(const char *s)
+ {
+ char *result;
+
+ result = strdup(s);
+ if (!result)
+ {
+ fprintf(stderr, _("out of memory\n"));
+ exit(1);
+ }
+ return result;
+ }
+
+ #define xfree(n) free(n)
+
+ #else
+
+ /* on the backend, use palloc and friends */
+
+ #define xmalloc(n) palloc(n)
+ #define xstrdup(n) pstrdup (n)
+ #define xfree(n) pfree(n)
+
+ #endif
+
+ /*
+ * deallocate memory used for filenames
+ */
+
+ static void
+ rmt_cleanup(char ** filenames)
+ {
+ char ** fn;
+
+ for (fn = filenames; *fn; fn++)
+ xfree(*fn);
+
+ xfree(filenames);
+ }
+
+
+
+ /*
+ * delete a directory tree recursively
+ * assumes path points to a valid directory
+ * deletes everything under path
+ * if rmtopdir is true deletes the directory too
+ *
+ */
+
+ bool
+ rmtree(char *path, bool rmtopdir)
+ {
+ char filepath[MAXPGPATH];
+ DIR *dir;
+ struct dirent *file;
+ char **filenames;
+ char **filename;
+ int numnames = 0;
+ struct stat statbuf;
+
+ /*
+ * we copy all the names out of the directory before we start
+ * modifying it.
+ *
+ */
+
+ dir = opendir(path);
+ if (dir == NULL)
+ return false;
+
+ while ((file = readdir(dir)) != NULL)
+ {
+ if (strcmp(file->d_name, ".") != 0 && strcmp(file->d_name, "..") != 0)
+ numnames++;
+ }
+
+ rewinddir(dir);
+
+ filenames = xmalloc((numnames + 2) * sizeof(char *));
+ numnames = 0;
+
+ while ((file = readdir(dir)) != NULL)
+ {
+ if (strcmp(file->d_name, ".") != 0 && strcmp(file->d_name, "..") != 0)
+ filenames[numnames++] = xstrdup(file->d_name);
+ }
+
+ filenames[numnames] = NULL;
+
+ closedir(dir);
+
+ /* now we have the names we can start removing things */
+
+ for (filename = filenames; *filename; filename++)
+ {
+ snprintf(filepath, MAXPGPATH, "%s/%s", path, *filename);
+
+ if (stat(filepath, &statbuf) != 0)
+ {
+ rmt_cleanup(filenames);
+ return false;
+ }
+
+ if (S_ISDIR(statbuf.st_mode))
+ {
+ /* call ourselves recursively for a directory */
+ if (!rmtree(filepath, true))
+ {
+ rmt_cleanup(filenames);
+ return false;
+ }
+ }
+ else
+ {
+ if (rmt_unlink(filepath) != 0)
+ {
+ rmt_cleanup(filenames);
+ return false;
+ }
+ }
+ }
+
+ if (rmtopdir)
+ {
+ if (rmdir(path) != 0)
+ {
+ rmt_cleanup(filenames);
+ return false;
+ }
+ }
+
+ rmt_cleanup(filenames);
+ return true;
+ }
+
+
#else
pgsql-patches by date: