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: