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
  
  
