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:

Previous
From: Andreas Pflug
Date:
Subject: Re: logger subprocess
Next
From: Alvaro Herrera
Date:
Subject: Re: [subxacts] Fixing TODO items