Index: src/include/port.h =================================================================== RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/include/port.h,v retrieving revision 1.107 diff -c -r1.107 port.h *** src/include/port.h 5 Jan 2007 22:19:50 -0000 1.107 --- src/include/port.h 7 Jan 2007 15:11:12 -0000 *************** *** 46,51 **** --- 46,56 ---- extern bool get_home_path(char *ret_path); extern void get_parent_directory(char *path); + + /* port/dirmod.c */ + extern char **pgfnames(char *path); + extern void pgfnames_cleanup(char **filenames); + /* * is_absolute_path * Index: src/port/dirmod.c =================================================================== RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/port/dirmod.c,v retrieving revision 1.46 diff -c -r1.46 dirmod.c *** src/port/dirmod.c 5 Jan 2007 22:20:02 -0000 1.46 --- src/port/dirmod.c 7 Jan 2007 15:13:27 -0000 *************** *** 287,298 **** /* ! * fnames * * return a list of the names of objects in the argument directory */ ! static char ** ! fnames(char *path) { DIR *dir; struct dirent *file; --- 287,298 ---- /* ! * pgfnames * * return a list of the names of objects in the argument directory */ ! char ** ! pgfnames(char *path) { DIR *dir; struct dirent *file; *************** *** 357,368 **** /* ! * fnames_cleanup * * deallocate memory used for filenames */ ! static void ! fnames_cleanup(char **filenames) { char **fn; --- 357,368 ---- /* ! * pgfnames_cleanup * * deallocate memory used for filenames */ ! void ! pgfnames_cleanup(char **filenames) { char **fn; *************** *** 394,400 **** * we copy all the names out of the directory before we start modifying * it. */ ! filenames = fnames(path); if (filenames == NULL) return false; --- 394,400 ---- * we copy all the names out of the directory before we start modifying * it. */ ! filenames = pgfnames(path); if (filenames == NULL) return false; *************** *** 415,421 **** if (!rmtree(filepath, true)) { /* we already reported the error */ ! fnames_cleanup(filenames); return false; } } --- 415,421 ---- if (!rmtree(filepath, true)) { /* we already reported the error */ ! pgfnames_cleanup(filenames); return false; } } *************** *** 433,439 **** goto report_and_fail; } ! fnames_cleanup(filenames); return true; report_and_fail: --- 433,439 ---- goto report_and_fail; } ! pgfnames_cleanup(filenames); return true; report_and_fail: *************** *** 444,449 **** fprintf(stderr, _("could not remove file or directory \"%s\": %s\n"), filepath, strerror(errno)); #endif ! fnames_cleanup(filenames); return false; } --- 444,449 ---- fprintf(stderr, _("could not remove file or directory \"%s\": %s\n"), filepath, strerror(errno)); #endif ! pgfnames_cleanup(filenames); return false; } Index: src/test/regress/GNUmakefile =================================================================== RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/test/regress/GNUmakefile,v retrieving revision 1.63 diff -c -r1.63 GNUmakefile *** src/test/regress/GNUmakefile 5 Jan 2007 22:20:03 -0000 1.63 --- src/test/regress/GNUmakefile 7 Jan 2007 15:13:40 -0000 *************** *** 40,46 **** # stuff to pass into build of pg_regress EXTRADEFS = '-DHOST_TUPLE="$(host_tuple)"' \ '-DMAKEPROG="$(MAKE)"' \ ! '-DSHELLPROG="$(SHELL)"' ## ## Prepare for tests --- 40,47 ---- # stuff to pass into build of pg_regress EXTRADEFS = '-DHOST_TUPLE="$(host_tuple)"' \ '-DMAKEPROG="$(MAKE)"' \ ! '-DSHELLPROG="$(SHELL)"' \ ! '-DDLSUFFIX="$(DLSUFFIX)"' ## ## Prepare for tests *************** *** 83,96 **** rm -f $(NAME)$(DLSUFFIX) $(LN_S) $(shlib) $(NAME)$(DLSUFFIX) - # Build test input and expected files - - file_list := copy create_function_1 create_function_2 misc constraints tablespace - input_files := $(foreach file, $(file_list), sql/$(file).sql) - output_files := $(foreach file, $(file_list), expected/$(file).out) - - all: $(input_files) $(output_files) - ifneq ($(PORTNAME),win32) abs_srcdir := $(shell cd $(srcdir) && pwd) abs_builddir := $(shell pwd) --- 84,89 ---- *************** *** 99,120 **** abs_builddir := $(shell pwd -W) endif - testtablespace := $(abs_builddir)/testtablespace - - - define sed-command - sed -e 's,@abs_srcdir@,$(abs_srcdir),g' \ - -e 's,@abs_builddir@,$(abs_builddir),g' \ - -e 's,@testtablespace@,$(testtablespace),g' \ - -e 's/@DLSUFFIX@/$(DLSUFFIX)/g' $< >$@ - endef - - $(input_files): sql/%.sql: input/%.source - $(sed-command) - - $(output_files): expected/%.out: output/%.source - $(sed-command) - # When doing a VPATH build, copy over the remaining .sql and .out # files so that the driver script can find them. We have to use an # absolute path for the targets, because otherwise make will try to --- 92,97 ---- *************** *** 148,154 **** check: all -rm -rf ./testtablespace mkdir ./testtablespace ! ./pg_regress --temp-install=./tmp_check --top-builddir=$(top_builddir) --temp-port=$(TEMP_PORT) --schedule=$(srcdir)/parallel_schedule --multibyte=$(MULTIBYTE) --load-language=plpgsql $(MAXCONNOPT) $(NOLOCALE) installcheck: all -rm -rf ./testtablespace --- 125,131 ---- check: all -rm -rf ./testtablespace mkdir ./testtablespace ! ./pg_regress --temp-install=./tmp_check --top-builddir=$(top_builddir) --srcdir=$(abs_srcdir) --temp-port=$(TEMP_PORT) --schedule=$(srcdir)/parallel_schedule --multibyte=$(MULTIBYTE) --load-language=plpgsql $(MAXCONNOPT) $(NOLOCALE) installcheck: all -rm -rf ./testtablespace *************** *** 168,174 **** runtest-parallel: installcheck-parallel bigtest: ! ./pg_regress --psqldir=$(PSQLDIR) --schedule=$(srcdir)/serial_schedule --multibyte=$(MULTIBYTE) --load-language=plpgsql $(NOLOCALE) numeric_big bigcheck: ./pg_regress --temp-install=./tmp_check --top-builddir=$(top_builddir) --temp-port=$(TEMP_PORT) --schedule=$(srcdir)/parallel_schedule --multibyte=$(MULTIBYTE) --load-language=plpgsql $(MAXCONNOPT) $(NOLOCALE) numeric_big --- 145,151 ---- runtest-parallel: installcheck-parallel bigtest: ! ./pg_regress --psqldir=$(PSQLDIR) --schedule=$(srcdir)/serial_schedule --multibyte=$(MULTIBYTE) --load-language=plpgsql $(NOLOCALE) numeric_big bigcheck: ./pg_regress --temp-install=./tmp_check --top-builddir=$(top_builddir) --temp-port=$(TEMP_PORT) --schedule=$(srcdir)/parallel_schedule --multibyte=$(MULTIBYTE) --load-language=plpgsql $(MAXCONNOPT) $(NOLOCALE) numeric_big Index: src/test/regress/pg_regress.c =================================================================== RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/test/regress/pg_regress.c,v retrieving revision 1.25 diff -c -r1.25 pg_regress.c *** src/test/regress/pg_regress.c 5 Jan 2007 22:20:03 -0000 1.25 --- src/test/regress/pg_regress.c 7 Jan 2007 15:13:41 -0000 *************** *** 67,73 **** --- 67,75 ---- static char *libdir = LIBDIR; static char *datadir = PGSHAREDIR; static char *host_platform = HOST_TUPLE; + #ifndef WIN32_ONLY_COMPILER static char *makeprog = MAKEPROG; + #endif #ifndef WIN32 /* not used in WIN32 case */ static char *shellprog = SHELLPROG; *************** *** 95,100 **** --- 97,103 ---- static char *hostname = NULL; static int port = -1; static char *user = NULL; + static char *srcdir = NULL; /* internal variables */ static const char *progname; *************** *** 111,116 **** --- 114,124 ---- static int fail_count = 0; static int fail_ignore_count = 0; + static bool + directory_exists(const char *dir); + static void + make_directory(const char *dir); + static void header(const char *fmt,...) /* This extension allows gcc to check the format string for consistency with *************** *** 152,157 **** --- 160,169 ---- #endif + #ifdef WIN32 + typedef BOOL(WINAPI * __CreateRestrictedToken) (HANDLE, DWORD, DWORD, PSID_AND_ATTRIBUTES, DWORD, PLUID_AND_ATTRIBUTES, DWORD, PSID_AND_ATTRIBUTES, PHANDLE); + #endif + /* * Add an item at the end of a stringlist. */ *************** *** 331,336 **** --- 343,468 ---- } /* + * Replace all occurances of a string in a string with a different stirng. + * NOTE: Assumes there is enough room in the target buffer! + */ + static void + replace_string(char *string, char *replace, char *replacement) + { + char *ptr; + + while ((ptr = strstr(string, replace)) != NULL) + { + char *dup = strdup(string); + + strncpy(string, dup, ptr-string); + string[ptr-string]=0; + strcat(string, replacement); + strcat(string, dup+(ptr-string)+strlen(replace)); + free(dup); + } + } + + /* + * Convert *.source in input/ and output/ into actual files used by the + * regression tests in sql/ and expected/. + */ + static void + convert_sourcefiles_in(char *source, char *dest, char *suffix) + { + char abs_srcdir[MAXPGPATH]; + char abs_builddir[MAXPGPATH]; + char testtablespace[MAXPGPATH]; + char **name; + char **names = pgfnames(source); + #ifdef WIN32 + char *c; + #endif + + if (!names) + /* Error logged in pgfnames */ + exit_nicely(2); + + if (!getcwd(abs_builddir, sizeof(abs_builddir))) + { + fprintf(stderr, _("%s: could not get current directory: %s\n"), + progname, strerror(errno)); + exit_nicely(2); + } + if (srcdir) + strcpy(abs_srcdir, srcdir); + else + strcpy(abs_srcdir, abs_builddir); + #ifdef WIN32 + for (c = abs_builddir; *c; c++) + if (*c == '\\') + *c = '/'; + for (c = abs_srcdir; *c; c++) + if (*c == '\\') + *c = '/'; + #endif + + + snprintf(testtablespace, sizeof(testtablespace), "%s/testtablespace", abs_builddir); + if (directory_exists(testtablespace)) + rmtree(testtablespace, true); + make_directory(testtablespace); + + for (name = names; *name; name++) + { + char srcfile[MAXPGPATH]; + char destfile[MAXPGPATH]; + FILE *infile, *outfile; + char line[1024]; + + if (strlen(*name) < 8) + continue; + if (strcmp(*name+strlen(*name)-7,".source")) + continue; + + strcpy(srcfile,source); + strcat(srcfile, *name); + strcpy(destfile,dest); + strncat(destfile, *name, strlen(*name)-6); + strcat(destfile,suffix); + + infile = fopen(srcfile,"r"); + if (!infile) + { + fprintf(stderr, _("%s: could not open file \"%s\" for reading: %s\n"), + progname, srcfile, strerror(errno)); + exit_nicely(2); + } + outfile = fopen(destfile,"w"); + if (!outfile) + { + fprintf(stderr, _("%s: could not open file \"%s\" for writing: %s\n"), + progname, destfile, strerror(errno)); + exit_nicely(2); + } + while (fgets(line, sizeof(line), infile)) + { + replace_string(line,"@abs_srcdir@", abs_srcdir); + replace_string(line,"@abs_builddir@", abs_builddir); + replace_string(line,"@testtablespace@", testtablespace); + replace_string(line,"@DLSUFFIX@", DLSUFFIX); + fputs(line, outfile); + } + fclose(infile); + fclose(outfile); + } + + pgfnames_cleanup(names); + } + + static void + convert_sourcefiles(void) + { + convert_sourcefiles_in("input/","sql/","sql"); + convert_sourcefiles_in("output/","expected/","out"); + } + + /* * Scan resultmap file to find which platform-specific expected files to use. * * The format of each line of the file is *************** *** 593,598 **** --- 725,731 ---- printf(_("(using postmaster on Unix socket, default port)\n")); } + convert_sourcefiles(); load_resultmap(); } *************** *** 690,705 **** return pid; #else char *cmdline2; STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); cmdline2 = malloc(strlen(cmdline) + 8); sprintf(cmdline2, "cmd /c %s", cmdline); ! if (!CreateProcess(NULL, cmdline2, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { fprintf(stderr, _("could not start process for \"%s\": %lu\n"), cmdline2, GetLastError()); --- 823,898 ---- return pid; #else char *cmdline2; + BOOL b; STARTUPINFO si; PROCESS_INFORMATION pi; + HANDLE origToken; + HANDLE restrictedToken; + SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY}; + SID_AND_ATTRIBUTES dropSids[2]; + __CreateRestrictedToken _CreateRestrictedToken = NULL; + HANDLE Advapi32Handle; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); + Advapi32Handle = LoadLibrary("ADVAPI32.DLL"); + if (Advapi32Handle != NULL) + { + _CreateRestrictedToken = (__CreateRestrictedToken) GetProcAddress(Advapi32Handle, "CreateRestrictedToken"); + } + + if (_CreateRestrictedToken == NULL) + { + fprintf(stderr, "WARNING: Unable to create restricted tokens on this platform\n"); + if (Advapi32Handle != NULL) + FreeLibrary(Advapi32Handle); + return 0; + } + + /* Open the current token to use as a base for the restricted one */ + if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &origToken)) + { + fprintf(stderr, "Failed to open process token: %lu\n", GetLastError()); + return 0; + } + + /* Allocate list of SIDs to remove */ + ZeroMemory(&dropSids, sizeof(dropSids)); + if (!AllocateAndInitializeSid(&NtAuthority, 2, + SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, + 0, &dropSids[0].Sid) || + !AllocateAndInitializeSid(&NtAuthority, 2, + SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS, 0, 0, 0, 0, 0, + 0, &dropSids[1].Sid)) + { + fprintf(stderr, "Failed to allocate SIDs: %lu\n", GetLastError()); + return 0; + } + + b = _CreateRestrictedToken(origToken, + DISABLE_MAX_PRIVILEGE, + sizeof(dropSids) / sizeof(dropSids[0]), + dropSids, + 0, NULL, + 0, NULL, + &restrictedToken); + + FreeSid(dropSids[1].Sid); + FreeSid(dropSids[0].Sid); + CloseHandle(origToken); + FreeLibrary(Advapi32Handle); + + if (!b) + { + fprintf(stderr, "Failed to create restricted token: %lu\n", GetLastError()); + return 0; + } + cmdline2 = malloc(strlen(cmdline) + 8); sprintf(cmdline2, "cmd /c %s", cmdline); ! if (!CreateProcessAsUser(restrictedToken, NULL, cmdline2, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { fprintf(stderr, _("could not start process for \"%s\": %lu\n"), cmdline2, GetLastError()); *************** *** 1322,1327 **** --- 1515,1521 ---- printf(_(" --outputdir=DIR place output files in DIR (default \".\")\n")); printf(_(" --schedule=FILE use test ordering schedule from FILE\n")); printf(_(" (may be used multiple times to concatenate)\n")); + printf(_(" --srcdir=DIR absolute path to source directory (for VPATH builds)\n")); printf(_(" --temp-install=DIR create a temporary installation in DIR\n")); printf(_(" --no-locale use C locale\n")); printf(_("\n")); *************** *** 1369,1374 **** --- 1563,1569 ---- {"port", required_argument, NULL, 14}, {"user", required_argument, NULL, 15}, {"psqldir", required_argument, NULL, 16}, + {"srcdir", required_argument, NULL, 17}, {NULL, 0, NULL, 0} }; *************** *** 1461,1466 **** --- 1656,1664 ---- if (strlen(optarg)) psqldir = strdup(optarg); break; + case 17: + srcdir = strdup(optarg); + break; default: /* getopt_long already emitted a complaint */ fprintf(stderr, _("\nTry \"%s -h\" for more information.\n"), *************** *** 1520,1528 **** --- 1718,1732 ---- make_directory(buf); /* "make install" */ + #ifndef WIN32_ONLY_COMPILER snprintf(buf, sizeof(buf), SYSTEMQUOTE "\"%s\" -C \"%s\" DESTDIR=\"%s/install\" install with_perl=no with_python=no > \"%s/log/install.log\" 2>&1" SYSTEMQUOTE, makeprog, top_builddir, temp_install, outputdir); + #else + snprintf(buf, sizeof(buf), + SYSTEMQUOTE "perl \"%s/src/tools/msvc/install.pl\" \"%s/install\" >\"%s/log/install.log\" 2>&1" SYSTEMQUOTE, + top_builddir, temp_install, outputdir); + #endif if (system(buf)) { fprintf(stderr, _("\n%s: installation failed\nExamine %s/log/install.log for the reason.\nCommand was: %s\n"), progname, outputdir, buf); Index: src/test/regress/resultmap =================================================================== RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/test/regress/resultmap,v retrieving revision 1.83 diff -c -r1.83 resultmap *** src/test/regress/resultmap 3 Aug 2006 17:04:00 -0000 1.83 --- src/test/regress/resultmap 29 Dec 2006 19:51:45 -0000 *************** *** 1,8 **** --- 1,11 ---- float4/i.86-pc-mingw32=float4-exp-three-digits + float4/i.86-pc-win32vc=float4-exp-three-digits float8/i.86-.*-freebsd=float8-small-is-zero float8/i.86-.*-openbsd=float8-small-is-zero float8/i.86-.*-netbsd=float8-small-is-zero float8/m68k-.*-netbsd=float8-small-is-zero float8/i.86-pc-mingw32=float8-exp-three-digits-win32 + float8/i.86-pc-win32vc=float8-exp-three-digits-win32 float8/i.86-pc-cygwin=float8-small-is-zero int8/i.86-pc-mingw32=int8-exp-three-digits + int8/i.86-pc-win32vc=int8-exp-three-digits Index: src/tools/msvc/Solution.pm =================================================================== RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/tools/msvc/Solution.pm,v retrieving revision 1.5 diff -c -r1.5 Solution.pm *** src/tools/msvc/Solution.pm 29 Dec 2006 16:49:02 -0000 1.5 --- src/tools/msvc/Solution.pm 1 Jan 2007 14:57:21 -0000 *************** *** 197,213 **** print "Generating pg_config_paths.h...\n"; open(O,'>', 'src\port\pg_config_paths.h') || confess "Could not open pg_config_paths.h"; print O <', 'src\port\pg_config_paths.h') || confess "Could not open pg_config_paths.h"; print O <) { chomp; my $tgt = $target . basename($_); print "."; ! copy($_, $tgt) || croak "Could not copy $_\n"; } close($D); print "\n"; --- 70,79 ---- open($D, "dir /b /s $spec |") || croak "Could not list $spec\n"; while (<$D>) { chomp; + next if /regress/; # Skip temporary install in regression subdir my $tgt = $target . basename($_); print "."; ! copy($_, $tgt) || croak "Could not copy $_: $!\n"; } close($D); print "\n"; Index: src/tools/msvc/mkvcbuild.pl =================================================================== RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/tools/msvc/mkvcbuild.pl,v retrieving revision 1.8 diff -c -r1.8 mkvcbuild.pl *** src/tools/msvc/mkvcbuild.pl 21 Nov 2006 17:54:26 -0000 1.8 --- src/tools/msvc/mkvcbuild.pl 29 Dec 2006 19:50:59 -0000 *************** *** 255,264 **** } ! # Regression DLLs my $regress = $solution->AddProject('regress','dll','misc'); $regress->AddFile('src\test\regress\regress.c'); $regress->AddReference($postgres); $solution->Save(); --- 255,271 ---- } ! # Regression DLL and EXE my $regress = $solution->AddProject('regress','dll','misc'); $regress->AddFile('src\test\regress\regress.c'); $regress->AddReference($postgres); + + my $pgregress = $solution->AddProject('pg_regress','exe','misc'); + $pgregress->AddFile('src\test\regress\pg_regress.c'); + $pgregress->AddIncludeDir('src\port'); + $pgregress->AddDefine('HOST_TUPLE="i686-pc-win32vc"'); + $pgregress->AddDefine('FRONTEND'); + $pgregress->AddReference($libpgport); $solution->Save();