LCOV - differential code coverage report
Current view: top level - src/test/regress - pg_regress.c (source / functions) Coverage Total Hit UNC LBC UIC UBC GBC GIC GNC CBC EUB ECB DUB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 73.1 % 888 649 79 44 100 16 50 379 70 150 142 360 31 95
Current Date: 2023-04-08 17:13:01 Functions: 85.4 % 41 35 3 3 31 4 5 30 1 5
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 [..60] days: 42.7 % 131 56 75 56 1
Legend: Lines: hit not hit (60,120] days: 100.0 % 2 2 2
(120,180] days: 100.0 % 1 1 1 6
(180,240] days: 73.3 % 15 11 4 11
(240..) days: 78.3 % 739 579 44 100 16 50 379 1 149 140 350
Function coverage date bins:
[..60] days: 66.7 % 6 4 2 4
(180,240] days: 0.0 % 1 0 1
(240..) days: 44.9 % 69 31 3 31 5 30

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*-------------------------------------------------------------------------
                                  2                 :  *
                                  3                 :  * pg_regress --- regression test driver
                                  4                 :  *
                                  5                 :  * This is a C implementation of the previous shell script for running
                                  6                 :  * the regression tests, and should be mostly compatible with it.
                                  7                 :  * Initial author of C translation: Magnus Hagander
                                  8                 :  *
                                  9                 :  * This code is released under the terms of the PostgreSQL License.
                                 10                 :  *
                                 11                 :  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
                                 12                 :  * Portions Copyright (c) 1994, Regents of the University of California
                                 13                 :  *
                                 14                 :  * src/test/regress/pg_regress.c
                                 15                 :  *
                                 16                 :  *-------------------------------------------------------------------------
                                 17                 :  */
                                 18                 : 
                                 19                 : #include "postgres_fe.h"
                                 20                 : 
                                 21                 : #include <ctype.h>
                                 22                 : #include <sys/resource.h>
                                 23                 : #include <sys/stat.h>
                                 24                 : #include <sys/time.h>
                                 25                 : #include <sys/wait.h>
                                 26                 : #include <signal.h>
                                 27                 : #include <unistd.h>
                                 28                 : 
                                 29                 : #include "common/logging.h"
                                 30                 : #include "common/restricted_token.h"
                                 31                 : #include "common/string.h"
                                 32                 : #include "common/username.h"
                                 33                 : #include "getopt_long.h"
                                 34                 : #include "lib/stringinfo.h"
                                 35                 : #include "libpq/pqcomm.h"     /* needed for UNIXSOCK_PATH() */
                                 36                 : #include "pg_config_paths.h"
                                 37                 : #include "pg_regress.h"
                                 38                 : #include "portability/instr_time.h"
                                 39                 : 
                                 40                 : /* for resultmap we need a list of pairs of strings */
                                 41                 : typedef struct _resultmap
                                 42                 : {
                                 43                 :     char       *test;
                                 44                 :     char       *type;
                                 45                 :     char       *resultfile;
                                 46                 :     struct _resultmap *next;
                                 47                 : } _resultmap;
                                 48                 : 
                                 49                 : /*
                                 50                 :  * Values obtained from Makefile.
                                 51                 :  */
                                 52                 : char       *host_platform = HOST_TUPLE;
                                 53                 : 
                                 54                 : #ifndef WIN32                   /* not used in WIN32 case */
                                 55                 : static char *shellprog = SHELLPROG;
                                 56                 : #endif
                                 57                 : 
                                 58                 : /*
                                 59                 :  * On Windows we use -w in diff switches to avoid problems with inconsistent
                                 60                 :  * newline representation.  The actual result files will generally have
                                 61                 :  * Windows-style newlines, but the comparison files might or might not.
                                 62                 :  */
                                 63                 : #ifndef WIN32
                                 64                 : const char *basic_diff_opts = "";
                                 65                 : const char *pretty_diff_opts = "-U3";
                                 66                 : #else
                                 67                 : const char *basic_diff_opts = "-w";
                                 68                 : const char *pretty_diff_opts = "-w -U3";
                                 69                 : #endif
                                 70                 : 
                                 71                 : /*
                                 72                 :  * The width of the testname field when printing to ensure vertical alignment
                                 73                 :  * of test runtimes. This number is somewhat arbitrarily chosen to match the
                                 74                 :  * older pre-TAP output format.
                                 75                 :  */
                                 76                 : #define TESTNAME_WIDTH 36
                                 77                 : 
                                 78                 : typedef enum TAPtype
                                 79                 : {
                                 80                 :     DIAG = 0,
                                 81                 :     BAIL,
                                 82                 :     NOTE,
                                 83                 :     NOTE_DETAIL,
                                 84                 :     NOTE_END,
                                 85                 :     TEST_STATUS,
                                 86                 :     PLAN,
                                 87                 :     NONE
                                 88                 : }           TAPtype;
                                 89                 : 
                                 90                 : /* options settable from command line */
                                 91                 : _stringlist *dblist = NULL;
                                 92                 : bool        debug = false;
                                 93                 : char       *inputdir = ".";
                                 94                 : char       *outputdir = ".";
                                 95                 : char       *expecteddir = ".";
                                 96                 : char       *bindir = PGBINDIR;
                                 97                 : char       *launcher = NULL;
                                 98                 : static _stringlist *loadextension = NULL;
                                 99                 : static int  max_connections = 0;
                                100                 : static int  max_concurrent_tests = 0;
                                101                 : static char *encoding = NULL;
                                102                 : static _stringlist *schedulelist = NULL;
                                103                 : static _stringlist *extra_tests = NULL;
                                104                 : static char *temp_instance = NULL;
                                105                 : static _stringlist *temp_configs = NULL;
                                106                 : static bool nolocale = false;
                                107                 : static bool use_existing = false;
                                108                 : static char *hostname = NULL;
                                109                 : static int  port = -1;
                                110                 : static bool port_specified_by_user = false;
                                111                 : static char *dlpath = PKGLIBDIR;
                                112                 : static char *user = NULL;
                                113                 : static _stringlist *extraroles = NULL;
                                114                 : static char *config_auth_datadir = NULL;
                                115                 : 
                                116                 : /* internal variables */
                                117                 : static const char *progname;
                                118                 : static char *logfilename;
                                119                 : static FILE *logfile;
                                120                 : static char *difffilename;
                                121                 : static const char *sockdir;
                                122                 : static const char *temp_sockdir;
                                123                 : static char sockself[MAXPGPATH];
                                124                 : static char socklock[MAXPGPATH];
                                125                 : static StringInfo failed_tests = NULL;
                                126                 : static bool in_note = false;
                                127                 : 
                                128                 : static _resultmap *resultmap = NULL;
                                129                 : 
                                130                 : static PID_TYPE postmaster_pid = INVALID_PID;
                                131                 : static bool postmaster_running = false;
                                132                 : 
                                133                 : static int  success_count = 0;
                                134                 : static int  fail_count = 0;
                                135                 : 
                                136                 : static bool directory_exists(const char *dir);
                                137                 : static void make_directory(const char *dir);
                                138                 : 
                                139                 : static void test_status_print(bool ok, const char *testname, double runtime, bool parallel);
                                140                 : static void test_status_ok(const char *testname, double runtime, bool parallel);
                                141                 : static void test_status_failed(const char *testname, double runtime, bool parallel);
                                142                 : static void bail_out(bool noatexit, const char *fmt,...) pg_attribute_printf(2, 3);
                                143                 : static void emit_tap_output(TAPtype type, const char *fmt,...) pg_attribute_printf(2, 3);
                                144                 : static void emit_tap_output_v(TAPtype type, const char *fmt, va_list argp) pg_attribute_printf(2, 0);
                                145                 : 
                                146                 : static StringInfo psql_start_command(void);
                                147                 : static void psql_add_command(StringInfo buf, const char *query,...) pg_attribute_printf(2, 3);
                                148                 : static void psql_end_command(StringInfo buf, const char *database);
                                149                 : 
                                150                 : /*
                                151                 :  * Convenience macros for printing TAP output with a more shorthand syntax
                                152                 :  * aimed at making the code more readable.
                                153                 :  */
                                154                 : #define plan(x)             emit_tap_output(PLAN, "1..%i", (x))
                                155                 : #define note(...)           emit_tap_output(NOTE, __VA_ARGS__)
                                156                 : #define note_detail(...)    emit_tap_output(NOTE_DETAIL, __VA_ARGS__)
                                157                 : #define diag(...)           emit_tap_output(DIAG, __VA_ARGS__)
                                158                 : #define note_end()          emit_tap_output(NOTE_END, "\n");
                                159                 : #define bail_noatexit(...)  bail_out(true, __VA_ARGS__)
                                160                 : #define bail(...)           bail_out(false, __VA_ARGS__)
                                161                 : 
                                162                 : /*
                                163                 :  * allow core files if possible.
                                164                 :  */
                                165                 : #if defined(HAVE_GETRLIMIT)
                                166                 : static void
 5938 andrew                    167 GIC          84 : unlimit_core_size(void)
                                168                 : {
                                169                 :     struct rlimit lim;
                                170                 : 
 5624 bruce                     171              84 :     getrlimit(RLIMIT_CORE, &lim);
 5938 andrew                    172              84 :     if (lim.rlim_max == 0)
                                173                 :     {
    9 dgustafsson               174 UNC           0 :         diag("could not set core size: disallowed by hard limit");
 5938 andrew                    175 UIC           0 :         return;
                                176                 :     }
 5938 andrew                    177 GIC          84 :     else if (lim.rlim_max == RLIM_INFINITY || lim.rlim_cur < lim.rlim_max)
                                178                 :     {
                                179              84 :         lim.rlim_cur = lim.rlim_max;
 5624 bruce                     180              84 :         setrlimit(RLIMIT_CORE, &lim);
                                181                 :     }
                                182                 : }
                                183                 : #endif
                                184                 : 
                                185                 : 
                                186                 : /*
                                187                 :  * Add an item at the end of a stringlist.
                                188                 :  */
                                189                 : void
 3260                           190            3382 : add_stringlist_item(_stringlist **listhead, const char *str)
                                191                 : {
 2413 tgl                       192            3382 :     _stringlist *newentry = pg_malloc(sizeof(_stringlist));
                                193                 :     _stringlist *oldentry;
                                194                 : 
                                195            3382 :     newentry->str = pg_strdup(str);
 6108                           196            3382 :     newentry->next = NULL;
                                197            3382 :     if (*listhead == NULL)
 6108 tgl                       198 CBC        2785 :         *listhead = newentry;
                                199                 :     else
                                200                 :     {
 6108 tgl                       201 GIC        2607 :         for (oldentry = *listhead; oldentry->next; oldentry = oldentry->next)
 6031 bruce                     202 ECB             :              /* skip */ ;
 6108 tgl                       203 CBC         597 :         oldentry->next = newentry;
                                204                 :     }
 6108 tgl                       205 GBC        3382 : }
 6108 tgl                       206 EUB             : 
                                207                 : /*
 5780 magnus                    208 ECB             :  * Free a stringlist.
                                209                 :  */
                                210                 : static void
 3260 bruce                     211 CBC        2900 : free_stringlist(_stringlist **listhead)
                                212                 : {
 5780 magnus                    213 GIC        2900 :     if (listhead == NULL || *listhead == NULL)
                                214             755 :         return;
                                215            2145 :     if ((*listhead)->next != NULL)
                                216             372 :         free_stringlist(&((*listhead)->next));
                                217            2145 :     free((*listhead)->str);
                                218            2145 :     free(*listhead);
                                219            2145 :     *listhead = NULL;
                                220                 : }
 5780 magnus                    221 ECB             : 
                                222                 : /*
                                223                 :  * Split a delimited string into a stringlist
                                224                 :  */
                                225                 : static void
 3260 bruce                     226 CBC         100 : split_to_stringlist(const char *s, const char *delim, _stringlist **listhead)
 5780 magnus                    227 ECB             : {
 2413 tgl                       228 CBC         100 :     char       *sc = pg_strdup(s);
 5624 bruce                     229             100 :     char       *token = strtok(sc, delim);
                                230                 : 
 5780 magnus                    231 GIC         205 :     while (token)
 5780 magnus                    232 ECB             :     {
 5780 magnus                    233 GIC         105 :         add_stringlist_item(listhead, token);
 5780 magnus                    234 CBC         105 :         token = strtok(NULL, delim);
                                235                 :     }
                                236             100 :     free(sc);
 5780 magnus                    237 GIC         100 : }
                                238                 : 
                                239                 : /*
                                240                 :  * Bailing out is for unrecoverable errors which prevents further testing to
                                241                 :  * occur and after which the test run should be aborted. By passing noatexit
                                242                 :  * as true the process will terminate with _exit(2) and skipping registered
                                243                 :  * exit handlers, thus avoid any risk of bottomless recursion calls to exit.
                                244                 :  */
 6108 tgl                       245 ECB             : static void
    9 dgustafsson               246 UNC           0 : bail_out(bool noatexit, const char *fmt,...)
 6108 tgl                       247 ECB             : {
                                248                 :     va_list     ap;
                                249                 : 
 6108 tgl                       250 LBC           0 :     va_start(ap, fmt);
    9 dgustafsson               251 UNC           0 :     emit_tap_output_v(BAIL, fmt, ap);
 6108 tgl                       252 LBC           0 :     va_end(ap);
                                253                 : 
    9 dgustafsson               254 UNC           0 :     if (noatexit)
                                255               0 :         _exit(2);
                                256                 : 
                                257               0 :     exit(2);
                                258                 : }
                                259                 : 
                                260                 : /*
                                261                 :  * Print the result of a test run and associated metadata like runtime. Care
                                262                 :  * is taken to align testnames and runtimes vertically to ensure the output
                                263                 :  * is human readable while still TAP compliant. Tests run in parallel are
                                264                 :  * prefixed with a '+' and sequential tests with a '-'. This distinction was
                                265                 :  * previously indicated by 'test' prefixing sequential tests while parallel
                                266                 :  * tests were indented by four leading spaces. The meson TAP parser consumes
                                267                 :  * leading space however, so a non-whitespace prefix of the same length is
                                268                 :  * required for both.
                                269                 :  */
 6108 tgl                       270 ECB             : static void
    9 dgustafsson               271 GNC        1110 : test_status_print(bool ok, const char *testname, double runtime, bool parallel)
                                272                 : {
                                273            1110 :     int         testnumber = fail_count + success_count;
                                274                 : 
                                275                 :     /*
                                276                 :      * Testnumbers are padded to 5 characters to ensure that testnames align
                                277                 :      * vertically (assuming at most 9999 tests).  Testnames are prefixed with
                                278                 :      * a leading character to indicate being run in parallel or not. A leading
                                279                 :      * '+' indicates a parellel test, '-' indicates a single test.
                                280                 :      */
                                281            1110 :     emit_tap_output(TEST_STATUS, "%sok %-5i%*s %c %-*s %8.0f ms",
                                282                 :                     (ok ? "" : "not "),
                                283                 :                     testnumber,
                                284                 :     /* If ok, indent with four spaces matching "not " */
                                285                 :                     (ok ? (int) strlen("not ") : 0), "",
                                286                 :     /* Prefix a parallel test '+' and a single test with '-' */
                                287                 :                     (parallel ? '+' : '-'),
                                288                 :     /* Testnames are padded to align runtimes */
                                289                 :                     TESTNAME_WIDTH, testname,
                                290                 :                     runtime);
                                291            1110 : }
 6108 tgl                       292 ECB             : 
                                293                 : static void
    9 dgustafsson               294 GNC        1110 : test_status_ok(const char *testname, double runtime, bool parallel)
                                295                 : {
                                296            1110 :     success_count++;
                                297                 : 
                                298            1110 :     test_status_print(true, testname, runtime, parallel);
 6108 tgl                       299            1110 : }
                                300                 : 
                                301                 : static void
    9 dgustafsson               302 UNC           0 : test_status_failed(const char *testname, double runtime, bool parallel)
                                303                 : {
                                304                 :     /*
                                305                 :      * Save failed tests in a buffer such that we can print a summary at the
                                306                 :      * end with diag() to ensure it's shown even under test harnesses.
                                307                 :      */
                                308               0 :     if (!failed_tests)
                                309               0 :         failed_tests = makeStringInfo();
                                310                 :     else
                                311               0 :         appendStringInfoChar(failed_tests, ',');
                                312                 : 
                                313               0 :     appendStringInfo(failed_tests, " %s", testname);
                                314                 : 
                                315               0 :     fail_count++;
                                316                 : 
                                317               0 :     test_status_print(false, testname, runtime, parallel);
                                318               0 : }
                                319                 : 
                                320                 : 
                                321                 : static void
    9 dgustafsson               322 GNC        2091 : emit_tap_output(TAPtype type, const char *fmt,...)
                                323                 : {
                                324                 :     va_list     argp;
                                325                 : 
                                326            2091 :     va_start(argp, fmt);
                                327            2091 :     emit_tap_output_v(type, fmt, argp);
                                328            2091 :     va_end(argp);
                                329            2091 : }
                                330                 : 
                                331                 : static void
                                332            2091 : emit_tap_output_v(TAPtype type, const char *fmt, va_list argp)
                                333                 : {
                                334                 :     va_list     argp_logfile;
                                335                 :     FILE       *fp;
                                336                 : 
                                337                 :     /*
                                338                 :      * Diagnostic output will be hidden by prove unless printed to stderr. The
                                339                 :      * Bail message is also printed to stderr to aid debugging under a harness
                                340                 :      * which might otherwise not emit such an important message.
                                341                 :      */
                                342            2091 :     if (type == DIAG || type == BAIL)
    9 dgustafsson               343 UNC           0 :         fp = stderr;
                                344                 :     else
    9 dgustafsson               345 GNC        2091 :         fp = stdout;
                                346                 : 
                                347                 :     /*
                                348                 :      * If we are ending a note_detail line we can avoid further processing and
                                349                 :      * immediately return following a newline.
                                350                 :      */
                                351            2091 :     if (type == NOTE_END)
                                352                 :     {
                                353              54 :         in_note = false;
                                354              54 :         fprintf(fp, "\n");
                                355              54 :         if (logfile)
                                356              54 :             fprintf(logfile, "\n");
                                357              54 :         return;
                                358                 :     }
                                359                 : 
                                360                 :     /* Make a copy of the va args for printing to the logfile */
                                361            2037 :     va_copy(argp_logfile, argp);
                                362                 : 
                                363                 :     /*
                                364                 :      * Non-protocol output such as diagnostics or notes must be prefixed by a
                                365                 :      * '#' character. We print the Bail message like this too.
                                366                 :      */
                                367            2037 :     if ((type == NOTE || type == DIAG || type == BAIL)
                                368            1869 :         || (type == NOTE_DETAIL && !in_note))
                                369                 :     {
                                370             222 :         fprintf(fp, "# ");
                                371             222 :         if (logfile)
                                372             222 :             fprintf(logfile, "# ");
                                373                 :     }
                                374            2037 :     vfprintf(fp, fmt, argp);
 6108 tgl                       375 GBC        2037 :     if (logfile)
    9 dgustafsson               376 GNC        2037 :         vfprintf(logfile, fmt, argp_logfile);
                                377                 : 
                                378                 :     /*
                                379                 :      * If we are entering into a note with more details to follow, register
                                380                 :      * that the leading '#' has been printed such that subsequent details
                                381                 :      * aren't prefixed as well.
                                382                 :      */
                                383            2037 :     if (type == NOTE_DETAIL)
                                384             675 :         in_note = true;
                                385                 : 
                                386                 :     /*
                                387                 :      * If this was a Bail message, the bail protocol message must go to stdout
                                388                 :      * separately.
                                389                 :      */
                                390            2037 :     if (type == BAIL)
                                391                 :     {
    9 dgustafsson               392 UNC           0 :         fprintf(stdout, "Bail out!");
                                393               0 :         if (logfile)
                                394               0 :             fprintf(logfile, "Bail out!");
                                395                 :     }
                                396                 : 
    9 dgustafsson               397 GNC        2037 :     va_end(argp_logfile);
                                398                 : 
                                399            2037 :     if (type != NOTE_DETAIL)
                                400                 :     {
                                401            1362 :         fprintf(fp, "\n");
                                402            1362 :         if (logfile)
                                403            1362 :             fprintf(logfile, "\n");
                                404                 :     }
                                405            2037 :     fflush(NULL);
                                406                 : }
 6108 tgl                       407 EUB             : 
                                408                 : /*
                                409                 :  * shut down temp postmaster
                                410                 :  */
                                411                 : static void
 6108 tgl                       412 GIC         385 : stop_postmaster(void)
                                413                 : {
                                414             385 :     if (postmaster_running)
                                415                 :     {
                                416                 :         /* We use pg_ctl to issue the kill and wait for stop */
                                417                 :         char        buf[MAXPGPATH * 2];
                                418                 :         int         r;
                                419                 : 
                                420             164 :         snprintf(buf, sizeof(buf),
                                421                 :                  "\"%s%spg_ctl\" stop -D \"%s/data\" -s",
 2908 peter_e                   422              82 :                  bindir ? bindir : "",
                                423              82 :                  bindir ? "/" : "",
                                424                 :                  temp_instance);
  223 tgl                       425 GNC          82 :         fflush(NULL);
 5248 peter_e                   426 GIC          82 :         r = system(buf);
                                427              82 :         if (r != 0)
 5248 peter_e                   428 ECB             :         {
                                429                 :             /* Not using the normal bail() as we want _exit */
    9 dgustafsson               430 UNC           0 :             bail_noatexit(_("could not stop postmaster: exit code was %d"), r);
                                431                 :         }
                                432                 : 
 6108 tgl                       433 GIC          82 :         postmaster_running = false;
                                434                 :     }
                                435             385 : }
                                436                 : 
                                437                 : /*
                                438                 :  * Remove the socket temporary directory.  pg_regress never waits for a
 3221 noah                      439 ECB             :  * postmaster exit, so it is indeterminate whether the postmaster has yet to
                                440                 :  * unlink the socket and lock file.  Unlink them here so we can proceed to
                                441                 :  * remove the directory.  Ignore errors; leaking a temporary directory is
                                442                 :  * unimportant.  This can run from a signal handler.  The code is not
                                443                 :  * acceptable in a Windows signal handler (see initdb.c:trapsig()), but
 1105 peter                     444                 :  * on Windows, pg_regress does not use Unix sockets by default.
                                445                 :  */
                                446                 : static void
 3221 noah                      447 GBC          82 : remove_temp(void)
                                448                 : {
 3221 noah                      449 GIC          82 :     Assert(temp_sockdir);
                                450              82 :     unlink(sockself);
                                451              82 :     unlink(socklock);
                                452              82 :     rmdir(temp_sockdir);
 3221 noah                      453 GBC          82 : }
 3221 noah                      454 EUB             : 
                                455                 : /*
                                456                 :  * Signal handler that calls remove_temp() and reraises the signal.
                                457                 :  */
                                458                 : static void
  207 tgl                       459 UNC           0 : signal_remove_temp(SIGNAL_ARGS)
 3221 noah                      460 EUB             : {
 3221 noah                      461 UIC           0 :     remove_temp();
 3221 noah                      462 EUB             : 
  207 tgl                       463 UNC           0 :     pqsignal(postgres_signal_arg, SIG_DFL);
                                464               0 :     raise(postgres_signal_arg);
 3221 noah                      465 UIC           0 : }
                                466                 : 
 3221 noah                      467 ECB             : /*
                                468                 :  * Create a temporary directory suitable for the server's Unix-domain socket.
                                469                 :  * The directory will have mode 0700 or stricter, so no other OS user can open
                                470                 :  * our socket to exploit our use of trust authentication.  Most systems
                                471                 :  * constrain the length of socket paths well below _POSIX_PATH_MAX, so we
                                472                 :  * place the directory under /tmp rather than relative to the possibly-deep
                                473                 :  * current working directory.
                                474                 :  *
                                475                 :  * Compared to using the compiled-in DEFAULT_PGSOCKET_DIR, this also permits
                                476                 :  * testing to work in builds that relocate it to a directory not writable to
                                477                 :  * the build/test user.
                                478                 :  */
                                479                 : static const char *
 3221 noah                      480 GIC          82 : make_temp_sockdir(void)
                                481                 : {
 1106 peter                     482              82 :     char       *template = psprintf("%s/pg_regress-XXXXXX",
                                483              82 :                                     getenv("TMPDIR") ? getenv("TMPDIR") : "/tmp");
                                484                 : 
 3221 noah                      485              82 :     temp_sockdir = mkdtemp(template);
                                486              82 :     if (temp_sockdir == NULL)
 3221 noah                      487 ECB             :     {
    9 dgustafsson               488 UNC           0 :         bail("could not create directory \"%s\": %s",
                                489                 :              template, strerror(errno));
                                490                 :     }
                                491                 : 
                                492                 :     /* Stage file names for remove_temp().  Unsafe in a signal handler. */
 3221 noah                      493 GIC          82 :     UNIXSOCK_PATH(sockself, port, temp_sockdir);
                                494              82 :     snprintf(socklock, sizeof(socklock), "%s.lock", sockself);
 3221 noah                      495 ECB             : 
                                496                 :     /* Remove the directory during clean exit. */
 3221 noah                      497 CBC          82 :     atexit(remove_temp);
 3221 noah                      498 ECB             : 
                                499                 :     /*
                                500                 :      * Remove the directory before dying to the usual signals.  Omit SIGQUIT,
                                501                 :      * preserving it as a quick, untidy exit.
                                502                 :      */
 3221 noah                      503 GIC          82 :     pqsignal(SIGHUP, signal_remove_temp);
                                504              82 :     pqsignal(SIGINT, signal_remove_temp);
 3221 noah                      505 CBC          82 :     pqsignal(SIGPIPE, signal_remove_temp);
 3221 noah                      506 GIC          82 :     pqsignal(SIGTERM, signal_remove_temp);
                                507                 : 
                                508              82 :     return temp_sockdir;
                                509                 : }
 3221 noah                      510 ECB             : 
 6108 tgl                       511                 : /*
                                512                 :  * Check whether string matches pattern
                                513                 :  *
                                514                 :  * In the original shell script, this function was implemented using expr(1),
                                515                 :  * which provides basic regular expressions restricted to match starting at
                                516                 :  * the string start (in conventional regex terms, there's an implicit "^"
                                517                 :  * at the start of the pattern --- but no implicit "$" at the end).
                                518                 :  *
                                519                 :  * For now, we only support "." and ".*" as non-literal metacharacters,
                                520                 :  * because that's all that anyone has found use for in resultmap.  This
                                521                 :  * code could be extended if more functionality is needed.
                                522                 :  */
                                523                 : static bool
 6108 tgl                       524 GIC          42 : string_matches_pattern(const char *str, const char *pattern)
                                525                 : {
 6108 tgl                       526 CBC          78 :     while (*str && *pattern)
 6108 tgl                       527 ECB             :     {
 6108 tgl                       528 GIC          78 :         if (*pattern == '.' && pattern[1] == '*')
                                529                 :         {
                                530              24 :             pattern += 2;
                                531                 :             /* Trailing .* matches everything. */
                                532              24 :             if (*pattern == '\0')
 6108 tgl                       533 LBC           0 :                 return true;
                                534                 : 
 6108 tgl                       535 EUB             :             /*
                                536                 :              * Otherwise, scan for a text position at which we can match the
                                537                 :              * rest of the pattern.
                                538                 :              */
 6108 tgl                       539 GIC         282 :             while (*str)
 6108 tgl                       540 ECB             :             {
                                541                 :                 /*
                                542                 :                  * Optimization to prevent most recursion: don't recurse
                                543                 :                  * unless first pattern char might match this text char.
                                544                 :                  */
 6108 tgl                       545 CBC         258 :                 if (*str == *pattern || *pattern == '.')
 6108 tgl                       546 ECB             :                 {
 6108 tgl                       547 GIC          36 :                     if (string_matches_pattern(str, pattern))
 6108 tgl                       548 LBC           0 :                         return true;
                                549                 :                 }
                                550                 : 
 6108 tgl                       551 GIC         258 :                 str++;
                                552                 :             }
                                553                 : 
                                554                 :             /*
 6108 tgl                       555 ECB             :              * End of text with no match.
                                556                 :              */
 6108 tgl                       557 CBC          24 :             return false;
                                558                 :         }
 6108 tgl                       559 GIC          54 :         else if (*pattern != '.' && *str != *pattern)
                                560                 :         {
                                561                 :             /*
                                562                 :              * Not the single-character wildcard and no explicit match? Then
 6108 tgl                       563 ECB             :              * time to quit...
                                564                 :              */
 6108 tgl                       565 CBC          18 :             return false;
 6108 tgl                       566 ECB             :         }
                                567                 : 
 6108 tgl                       568 CBC          36 :         str++;
                                569              36 :         pattern++;
 6108 tgl                       570 ECB             :     }
                                571                 : 
 6108 tgl                       572 UIC           0 :     if (*pattern == '\0')
 6108 tgl                       573 UBC           0 :         return true;            /* end of pattern, so declare match */
                                574                 : 
                                575                 :     /* End of input string.  Do we have matching pattern remaining? */
 6108 tgl                       576 LBC           0 :     while (*pattern == '.' && pattern[1] == '*')
 6108 tgl                       577 UIC           0 :         pattern += 2;
 6108 tgl                       578 LBC           0 :     if (*pattern == '\0')
 6108 tgl                       579 UIC           0 :         return true;            /* end of pattern, so declare match */
                                580                 : 
                                581               0 :     return false;
                                582                 : }
                                583                 : 
                                584                 : /*
                                585                 :  * Scan resultmap file to find which platform-specific expected files to use.
                                586                 :  *
                                587                 :  * The format of each line of the file is
                                588                 :  *         testname/hostplatformpattern=substitutefile
                                589                 :  * where the hostplatformpattern is evaluated per the rules of expr(1),
 6108 tgl                       590 ECB             :  * namely, it is a standard regular expression with an implicit ^ at the start.
                                591                 :  * (We currently support only a very limited subset of regular expressions,
                                592                 :  * see string_matches_pattern() above.)  What hostplatformpattern will be
 3260 bruce                     593                 :  * matched against is the config.guess output.  (In the shell-script version,
 6108 tgl                       594                 :  * we also provided an indication of whether gcc or another compiler was in
                                595                 :  * use, but that facility isn't used anymore.)
                                596                 :  */
                                597                 : static void
 6108 tgl                       598 GIC          84 : load_resultmap(void)
                                599                 : {
                                600                 :     char        buf[MAXPGPATH];
                                601                 :     FILE       *f;
 6108 tgl                       602 EUB             : 
                                603                 :     /* scan the file ... */
 6108 tgl                       604 GBC          84 :     snprintf(buf, sizeof(buf), "%s/resultmap", inputdir);
 6031 bruce                     605 GIC          84 :     f = fopen(buf, "r");
 6108 tgl                       606 GBC          84 :     if (!f)
 6108 tgl                       607 EUB             :     {
                                608                 :         /* OK if it doesn't exist, else complain */
 6108 tgl                       609 GIC          81 :         if (errno == ENOENT)
                                610              81 :             return;
    9 dgustafsson               611 UNC           0 :         bail("could not open file \"%s\" for reading: %s",
                                612                 :              buf, strerror(errno));
                                613                 :     }
                                614                 : 
 6108 tgl                       615 GIC          12 :     while (fgets(buf, sizeof(buf), f))
                                616                 :     {
                                617                 :         char       *platform;
                                618                 :         char       *file_type;
                                619                 :         char       *expected;
                                620                 :         int         i;
                                621                 : 
 6108 tgl                       622 ECB             :         /* strip trailing whitespace, especially the newline */
 6108 tgl                       623 GIC           6 :         i = strlen(buf);
 6031 bruce                     624 CBC          12 :         while (i > 0 && isspace((unsigned char) buf[i - 1]))
 6108 tgl                       625               6 :             buf[--i] = '\0';
                                626                 : 
 6108 tgl                       627 ECB             :         /* parse out the line fields */
 5780 magnus                    628 CBC           6 :         file_type = strchr(buf, ':');
 5780 magnus                    629 GIC           6 :         if (!file_type)
 5780 magnus                    630 EUB             :         {
    9 dgustafsson               631 UNC           0 :             bail("incorrectly formatted resultmap entry: %s", buf);
                                632                 :         }
 5780 magnus                    633 CBC           6 :         *file_type++ = '\0';
 5780 magnus                    634 ECB             : 
 5780 magnus                    635 GIC           6 :         platform = strchr(file_type, ':');
 6108 tgl                       636               6 :         if (!platform)
 6108 tgl                       637 ECB             :         {
    9 dgustafsson               638 UNC           0 :             bail("incorrectly formatted resultmap entry: %s", buf);
                                639                 :         }
 6108 tgl                       640 GIC           6 :         *platform++ = '\0';
 6108 tgl                       641 CBC           6 :         expected = strchr(platform, '=');
                                642               6 :         if (!expected)
 6108 tgl                       643 ECB             :         {
    9 dgustafsson               644 UNC           0 :             bail("incorrectly formatted resultmap entry: %s", buf);
                                645                 :         }
 6108 tgl                       646 GIC           6 :         *expected++ = '\0';
                                647                 : 
                                648                 :         /*
                                649                 :          * if it's for current platform, save it in resultmap list. Note: by
                                650                 :          * adding at the front of the list, we ensure that in ambiguous cases,
                                651                 :          * the last match in the resultmap file is used. This mimics the
                                652                 :          * behavior of the old shell script.
                                653                 :          */
                                654               6 :         if (string_matches_pattern(host_platform, platform))
                                655                 :         {
 2413 tgl                       656 UIC           0 :             _resultmap *entry = pg_malloc(sizeof(_resultmap));
                                657                 : 
                                658               0 :             entry->test = pg_strdup(buf);
                                659               0 :             entry->type = pg_strdup(file_type);
 2413 tgl                       660 LBC           0 :             entry->resultfile = pg_strdup(expected);
 6108 tgl                       661 UIC           0 :             entry->next = resultmap;
 6108 tgl                       662 LBC           0 :             resultmap = entry;
                                663                 :         }
 6108 tgl                       664 ECB             :     }
 6108 tgl                       665 GIC           3 :     fclose(f);
 6108 tgl                       666 ECB             : }
                                667                 : 
 5780 magnus                    668                 : /*
 5780 magnus                    669 EUB             :  * Check in resultmap if we should be looking at a different file
                                670                 :  */
                                671                 : static
                                672                 : const char *
 5624 bruce                     673 GIC        1236 : get_expectfile(const char *testname, const char *file)
                                674                 : {
 5624 bruce                     675 ECB             :     char       *file_type;
                                676                 :     _resultmap *rm;
                                677                 : 
                                678                 :     /*
                                679                 :      * Determine the file type from the file name. This is just what is
                                680                 :      * following the last dot in the file name.
 5780 magnus                    681                 :      */
 5780 magnus                    682 GIC        1236 :     if (!file || !(file_type = strrchr(file, '.')))
 5780 magnus                    683 LBC           0 :         return NULL;
 5780 magnus                    684 EUB             : 
 5780 magnus                    685 GIC        1236 :     file_type++;
                                686                 : 
 5780 magnus                    687 CBC        1236 :     for (rm = resultmap; rm != NULL; rm = rm->next)
                                688                 :     {
 5780 magnus                    689 UIC           0 :         if (strcmp(testname, rm->test) == 0 && strcmp(file_type, rm->type) == 0)
                                690                 :         {
                                691               0 :             return rm->resultfile;
                                692                 :         }
 5780 magnus                    693 ECB             :     }
                                694                 : 
 5780 magnus                    695 CBC        1236 :     return NULL;
                                696                 : }
                                697                 : 
                                698                 : /*
                                699                 :  * Prepare environment variables for running regression tests
                                700                 :  */
 6108 tgl                       701 ECB             : static void
 6108 tgl                       702 GIC          84 : initialize_environment(void)
                                703                 : {
 1321 tgl                       704 ECB             :     /*
  818                           705                 :      * Set default application_name.  (The test_start_function may choose to
                                706                 :      * override this, but if it doesn't, we have something useful in place.)
                                707                 :      */
  830 tgl                       708 GBC          84 :     setenv("PGAPPNAME", "pg_regress", 1);
 4065 peter_e                   709 EUB             : 
                                710                 :     /*
                                711                 :      * Set variables that the test scripts may need to refer to.
  475 tgl                       712                 :      */
  475 tgl                       713 GBC          84 :     setenv("PG_ABS_SRCDIR", inputdir, 1);
                                714              84 :     setenv("PG_ABS_BUILDDIR", outputdir, 1);
                                715              84 :     setenv("PG_LIBDIR", dlpath, 1);
  475 tgl                       716 GIC          84 :     setenv("PG_DLSUFFIX", DLSUFFIX, 1);
  475 tgl                       717 EUB             : 
 5170 peter_e                   718 GIC          84 :     if (nolocale)
                                719                 :     {
                                720                 :         /*
                                721                 :          * Clear out any non-C locale settings
                                722                 :          */
                                723               3 :         unsetenv("LC_COLLATE");
                                724               3 :         unsetenv("LC_CTYPE");
                                725               3 :         unsetenv("LC_MONETARY");
                                726               3 :         unsetenv("LC_NUMERIC");
                                727               3 :         unsetenv("LC_TIME");
                                728               3 :         unsetenv("LANG");
                                729                 : 
                                730                 :         /*
                                731                 :          * Most platforms have adopted the POSIX locale as their
                                732                 :          * implementation-defined default locale.  Exceptions include native
                                733                 :          * Windows, macOS with --enable-nls, and Cygwin with --enable-nls.
 3005 noah                      734 ECB             :          * (Use of --enable-nls matters because libintl replaces setlocale().)
                                735                 :          * Also, PostgreSQL does not support macOS with locale environment
                                736                 :          * variables unset; see PostmasterMain().
                                737                 :          */
                                738                 : #if defined(WIN32) || defined(__CYGWIN__) || defined(__darwin__)
                                739                 :         setenv("LANG", "C", 1);
 6108 tgl                       740                 : #endif
 5170 peter_e                   741                 :     }
 6108 tgl                       742                 : 
                                743                 :     /*
                                744                 :      * Set translation-related settings to English; otherwise psql will
 5050 bruce                     745                 :      * produce translated messages and produce diffs.  (XXX If we ever support
                                746                 :      * translation of pg_regress, this needs to be moved elsewhere, where psql
 5050 bruce                     747 EUB             :      * is actually called.)
                                748                 :      */
 5169 peter_e                   749 GIC          84 :     unsetenv("LANGUAGE");
                                750              84 :     unsetenv("LC_ALL");
  830 tgl                       751 CBC          84 :     setenv("LC_MESSAGES", "C", 1);
                                752                 : 
                                753                 :     /*
                                754                 :      * Set encoding as requested
                                755                 :      */
 6108 tgl                       756 GIC          84 :     if (encoding)
  830                           757               2 :         setenv("PGCLIENTENCODING", encoding, 1);
                                758                 :     else
 6108 tgl                       759 CBC          82 :         unsetenv("PGCLIENTENCODING");
 6108 tgl                       760 ECB             : 
                                761                 :     /*
                                762                 :      * Set timezone and datestyle for datetime-related tests
                                763                 :      */
  830 tgl                       764 CBC          84 :     setenv("PGTZ", "PST8PDT", 1);
                                765              84 :     setenv("PGDATESTYLE", "Postgres, MDY", 1);
                                766                 : 
 5248 tgl                       767 EUB             :     /*
                                768                 :      * Likewise set intervalstyle to ensure consistent results.  This is a bit
 5050 bruce                     769 ECB             :      * more painful because we must use PGOPTIONS, and we want to preserve the
                                770                 :      * user's ability to set other variables through that.
 5248 tgl                       771                 :      */
                                772                 :     {
 5247 tgl                       773 GIC          84 :         const char *my_pgoptions = "-c intervalstyle=postgres_verbose";
 5248 tgl                       774 GBC          84 :         const char *old_pgoptions = getenv("PGOPTIONS");
                                775                 :         char       *new_pgoptions;
 5248 tgl                       776 ECB             : 
 5248 tgl                       777 CBC          84 :         if (!old_pgoptions)
                                778              84 :             old_pgoptions = "";
  830 tgl                       779 GIC          84 :         new_pgoptions = psprintf("%s %s",
 3456 tgl                       780 EUB             :                                  old_pgoptions, my_pgoptions);
  830 tgl                       781 GIC          84 :         setenv("PGOPTIONS", new_pgoptions, 1);
  830 tgl                       782 CBC          84 :         free(new_pgoptions);
                                783                 :     }
                                784                 : 
 2908 peter_e                   785 GIC          84 :     if (temp_instance)
                                786                 :     {
                                787                 :         /*
                                788                 :          * Clear out any environment vars that might cause psql to connect to
                                789                 :          * the wrong postmaster, or otherwise behave in nondefault ways. (Note
 6031 bruce                     790 ECB             :          * we also use psql's -X switch consistently, so that ~/.psqlrc files
                                791                 :          * won't mess things up.)  Also, set PGPORT to the temp port, and set
 3221 noah                      792 EUB             :          * PGHOST depending on whether we are using TCP or Unix sockets.
                                793                 :          *
  532 andrew                    794                 :          * This list should be kept in sync with PostgreSQL/Test/Utils.pm.
 6108 tgl                       795                 :          */
  665 michael                   796 GBC          82 :         unsetenv("PGCHANNELBINDING");
  665 michael                   797 EUB             :         /* PGCLIENTENCODING, see above */
  665 michael                   798 GBC          82 :         unsetenv("PGCONNECT_TIMEOUT");
  665 michael                   799 GIC          82 :         unsetenv("PGDATA");
 6108 tgl                       800              82 :         unsetenv("PGDATABASE");
  665 michael                   801 CBC          82 :         unsetenv("PGGSSENCMODE");
  665 michael                   802 GIC          82 :         unsetenv("PGGSSLIB");
                                803                 :         /* PGHOSTADDR, see below */
                                804              82 :         unsetenv("PGKRBSRVNAME");
                                805              82 :         unsetenv("PGPASSFILE");
                                806              82 :         unsetenv("PGPASSWORD");
                                807              82 :         unsetenv("PGREQUIREPEER");
                                808              82 :         unsetenv("PGREQUIRESSL");
 6108 tgl                       809 CBC          82 :         unsetenv("PGSERVICE");
  665 michael                   810 GIC          82 :         unsetenv("PGSERVICEFILE");
                                811              82 :         unsetenv("PGSSLCERT");
                                812              82 :         unsetenv("PGSSLCRL");
                                813              82 :         unsetenv("PGSSLCRLDIR");
                                814              82 :         unsetenv("PGSSLKEY");
                                815              82 :         unsetenv("PGSSLMAXPROTOCOLVERSION");
                                816              82 :         unsetenv("PGSSLMINPROTOCOLVERSION");
 6108 tgl                       817              82 :         unsetenv("PGSSLMODE");
  665 michael                   818 CBC          82 :         unsetenv("PGSSLROOTCERT");
  665 michael                   819 GBC          82 :         unsetenv("PGSSLSNI");
  665 michael                   820 GIC          82 :         unsetenv("PGTARGETSESSIONATTRS");
  665 michael                   821 CBC          82 :         unsetenv("PGUSER");
                                822                 :         /* PGPORT, see below */
  665 michael                   823 ECB             :         /* PGHOST, see below */
                                824                 : 
 6108 tgl                       825 GIC          82 :         if (hostname != NULL)
  830 tgl                       826 UBC           0 :             setenv("PGHOST", hostname, 1);
                                827                 :         else
                                828                 :         {
 3221 noah                      829 GIC          82 :             sockdir = getenv("PG_REGRESS_SOCK_DIR");
 3221 noah                      830 CBC          82 :             if (!sockdir)
 3221 noah                      831 GIC          82 :                 sockdir = make_temp_sockdir();
  830 tgl                       832              82 :             setenv("PGHOST", sockdir, 1);
                                833                 :         }
 6108                           834              82 :         unsetenv("PGHOSTADDR");
                                835              82 :         if (port != -1)
                                836                 :         {
                                837                 :             char        s[16];
                                838                 : 
 6031 bruce                     839 CBC          82 :             sprintf(s, "%d", port);
  830 tgl                       840 GIC          82 :             setenv("PGPORT", s, 1);
                                841                 :         }
                                842                 :     }
                                843                 :     else
 6108 tgl                       844 ECB             :     {
                                845                 :         const char *pghost;
                                846                 :         const char *pgport;
                                847                 : 
                                848                 :         /*
                                849                 :          * When testing an existing install, we honor existing environment
                                850                 :          * variables, except if they're overridden by command line options.
                                851                 :          */
 6108 tgl                       852 GIC           2 :         if (hostname != NULL)
                                853                 :         {
  830 tgl                       854 CBC           2 :             setenv("PGHOST", hostname, 1);
 6108                           855               2 :             unsetenv("PGHOSTADDR");
 6108 tgl                       856 ECB             :         }
 6108 tgl                       857 CBC           2 :         if (port != -1)
 6108 tgl                       858 ECB             :         {
 6031 bruce                     859                 :             char        s[16];
                                860                 : 
 6031 bruce                     861 GIC           2 :             sprintf(s, "%d", port);
  830 tgl                       862               2 :             setenv("PGPORT", s, 1);
                                863                 :         }
 6108                           864               2 :         if (user != NULL)
  830 tgl                       865 UIC           0 :             setenv("PGUSER", user, 1);
                                866                 : 
                                867                 :         /*
                                868                 :          * However, we *don't* honor PGDATABASE, since we certainly don't wish
                                869                 :          * to connect to whatever database the user might like as default.
                                870                 :          * (Most tests override PGDATABASE anyway, but there are some ECPG
                                871                 :          * test cases that don't.)
                                872                 :          */
 1290 tgl                       873 GIC           2 :         unsetenv("PGDATABASE");
                                874                 : 
                                875                 :         /*
                                876                 :          * Report what we're connecting to
                                877                 :          */
 6108                           878               2 :         pghost = getenv("PGHOST");
                                879               2 :         pgport = getenv("PGPORT");
 6108 tgl                       880 CBC           2 :         if (!pghost)
  401 tgl                       881 ECB             :         {
                                882                 :             /* Keep this bit in sync with libpq's default host location: */
  401 tgl                       883 UIC           0 :             if (DEFAULT_PGSOCKET_DIR[0])
                                884                 :                  /* do nothing, we'll print "Unix socket" below */ ;
                                885                 :             else
  401 tgl                       886 LBC           0 :                 pghost = "localhost"; /* DefaultHost in fe-connect.c */
                                887                 :         }
 6108 tgl                       888 ECB             : 
 6108 tgl                       889 GIC           2 :         if (pghost && pgport)
    9 dgustafsson               890 GNC           2 :             note("using postmaster on %s, port %s", pghost, pgport);
 6108 tgl                       891 GIC           2 :         if (pghost && !pgport)
    9 dgustafsson               892 UNC           0 :             note("using postmaster on %s, default port", pghost);
 6108 tgl                       893 CBC           2 :         if (!pghost && pgport)
    9 dgustafsson               894 UNC           0 :             note("using postmaster on Unix socket, port %s", pgport);
 6108 tgl                       895 GIC           2 :         if (!pghost && !pgport)
    9 dgustafsson               896 UNC           0 :             note("using postmaster on Unix socket, default port");
                                897                 :     }
                                898                 : 
 6108 tgl                       899 GIC          84 :     load_resultmap();
                                900              84 : }
                                901                 : 
 1442 tgl                       902 ECB             : #ifdef ENABLE_SSPI
                                903                 : 
                                904                 : /* support for config_sspi_auth() */
                                905                 : static const char *
 2439 peter_e                   906                 : fmtHba(const char *raw)
                                907                 : {
                                908                 :     static char *ret;
                                909                 :     const char *rp;
                                910                 :     char       *wp;
                                911                 : 
                                912                 :     wp = ret = pg_realloc(ret, 3 + strlen(raw) * 2);
                                913                 : 
                                914                 :     *wp++ = '"';
                                915                 :     for (rp = raw; *rp; rp++)
                                916                 :     {
                                917                 :         if (*rp == '"')
                                918                 :             *wp++ = '"';
                                919                 :         *wp++ = *rp;
                                920                 :     }
                                921                 :     *wp++ = '"';
                                922                 :     *wp++ = '\0';
                                923                 : 
                                924                 :     return ret;
                                925                 : }
                                926                 : 
 3035 noah                      927                 : /*
                                928                 :  * Get account and domain/realm names for the current user.  This is based on
                                929                 :  * pg_SSPI_recvauth().  The returned strings use static storage.
                                930                 :  */
                                931                 : static void
                                932                 : current_windows_user(const char **acct, const char **dom)
                                933                 : {
                                934                 :     static char accountname[MAXPGPATH];
                                935                 :     static char domainname[MAXPGPATH];
                                936                 :     HANDLE      token;
                                937                 :     TOKEN_USER *tokenuser;
                                938                 :     DWORD       retlen;
                                939                 :     DWORD       accountnamesize = sizeof(accountname);
                                940                 :     DWORD       domainnamesize = sizeof(domainname);
                                941                 :     SID_NAME_USE accountnameuse;
                                942                 : 
                                943                 :     if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token))
                                944                 :     {
                                945                 :         bail("could not open process token: error code %lu", GetLastError());
                                946                 :     }
                                947                 : 
                                948                 :     if (!GetTokenInformation(token, TokenUser, NULL, 0, &retlen) && GetLastError() != 122)
                                949                 :     {
                                950                 :         bail("could not get token information buffer size: error code %lu",
                                951                 :              GetLastError());
                                952                 :     }
 2413 tgl                       953                 :     tokenuser = pg_malloc(retlen);
 3035 noah                      954                 :     if (!GetTokenInformation(token, TokenUser, tokenuser, retlen, &retlen))
                                955                 :     {
                                956                 :         bail("could not get token information: error code %lu",
                                957                 :              GetLastError());
                                958                 :     }
                                959                 : 
                                960                 :     if (!LookupAccountSid(NULL, tokenuser->User.Sid, accountname, &accountnamesize,
                                961                 :                           domainname, &domainnamesize, &accountnameuse))
                                962                 :     {
                                963                 :         bail("could not look up account SID: error code %lu",
                                964                 :              GetLastError());
                                965                 :     }
                                966                 : 
                                967                 :     free(tokenuser);
                                968                 : 
                                969                 :     *acct = accountname;
                                970                 :     *dom = domainname;
                                971                 : }
                                972                 : 
                                973                 : /*
                                974                 :  * Rewrite pg_hba.conf and pg_ident.conf to use SSPI authentication.  Permit
                                975                 :  * the current OS user to authenticate as the bootstrap superuser and as any
                                976                 :  * user named in a --create-role option.
 1379 tgl                       977                 :  *
                                978                 :  * In --config-auth mode, the --user switch can be used to specify the
                                979                 :  * bootstrap superuser's name, otherwise we assume it is the default.
                                980                 :  */
 3035 noah                      981                 : static void
 1379 tgl                       982                 : config_sspi_auth(const char *pgdata, const char *superuser_name)
                                983                 : {
 3035 noah                      984                 :     const char *accountname,
 3035 noah                      985 EUB             :                *domainname;
                                986                 :     char       *errstr;
                                987                 :     bool        have_ipv6;
                                988                 :     char        fname[MAXPGPATH];
                                989                 :     int         res;
                                990                 :     FILE       *hba,
                                991                 :                *ident;
                                992                 :     _stringlist *sl;
 3035 noah                      993 ECB             : 
                                994                 :     /* Find out the name of the current OS user */
                                995                 :     current_windows_user(&accountname, &domainname);
                                996                 : 
                                997                 :     /* Determine the bootstrap superuser's name */
 1379 tgl                       998                 :     if (superuser_name == NULL)
 3035 noah                      999                 :     {
 1379 tgl                      1000                 :         /*
                               1001                 :          * Compute the default superuser name the same way initdb does.
                               1002                 :          *
 1379 tgl                      1003 EUB             :          * It's possible that this result always matches "accountname", the
                               1004                 :          * value SSPI authentication discovers.  But the underlying system
                               1005                 :          * functions do not clearly guarantee that.
                               1006                 :          */
                               1007                 :         superuser_name = get_user_name(&errstr);
                               1008                 :         if (superuser_name == NULL)
 1379 tgl                      1009 ECB             :         {
                               1010                 :             bail("%s", errstr);
 1379 tgl                      1011 EUB             :         }
 3035 noah                     1012 ECB             :     }
 3035 noah                     1013 EUB             : 
 3027 noah                     1014 ECB             :     /*
 3027 noah                     1015 EUB             :      * Like initdb.c:setup_config(), determine whether the platform recognizes
                               1016                 :      * ::1 (IPv6 loopback) as a numeric host address string.
                               1017                 :      */
 3027 noah                     1018 ECB             :     {
                               1019                 :         struct addrinfo *gai_result;
                               1020                 :         struct addrinfo hints;
                               1021                 :         WSADATA     wsaData;
                               1022                 : 
                               1023                 :         hints.ai_flags = AI_NUMERICHOST;
                               1024                 :         hints.ai_family = AF_UNSPEC;
                               1025                 :         hints.ai_socktype = 0;
                               1026                 :         hints.ai_protocol = 0;
                               1027                 :         hints.ai_addrlen = 0;
                               1028                 :         hints.ai_canonname = NULL;
                               1029                 :         hints.ai_addr = NULL;
                               1030                 :         hints.ai_next = NULL;
                               1031                 : 
                               1032                 :         have_ipv6 = (WSAStartup(MAKEWORD(2, 2), &wsaData) == 0 &&
                               1033                 :                      getaddrinfo("::1", NULL, &hints, &gai_result) == 0);
                               1034                 :     }
                               1035                 : 
                               1036                 :     /* Check a Write outcome and report any error. */
                               1037                 : #define CW(cond)    \
                               1038                 :     do { \
                               1039                 :         if (!(cond)) \
                               1040                 :         { \
                               1041                 :             bail("could not write to file \"%s\": %s", \
                               1042                 :                  fname, strerror(errno)); \
                               1043                 :         } \
                               1044                 :     } while (0)
                               1045                 : 
                               1046                 :     res = snprintf(fname, sizeof(fname), "%s/pg_hba.conf", pgdata);
                               1047                 :     if (res < 0 || res >= sizeof(fname))
                               1048                 :     {
                               1049                 :         /*
                               1050                 :          * Truncating this name is a fatal error, because we must not fail to
                               1051                 :          * overwrite an original trust-authentication pg_hba.conf.
                               1052                 :          */
                               1053                 :         bail("directory name too long");
                               1054                 :     }
                               1055                 :     hba = fopen(fname, "w");
                               1056                 :     if (hba == NULL)
                               1057                 :     {
                               1058                 :         bail("could not open file \"%s\" for writing: %s",
                               1059                 :              fname, strerror(errno));
                               1060                 :     }
                               1061                 :     CW(fputs("# Configuration written by config_sspi_auth()\n", hba) >= 0);
                               1062                 :     CW(fputs("host all all 127.0.0.1/32  sspi include_realm=1 map=regress\n",
                               1063                 :              hba) >= 0);
                               1064                 :     if (have_ipv6)
                               1065                 :         CW(fputs("host all all ::1/128  sspi include_realm=1 map=regress\n",
                               1066                 :                  hba) >= 0);
                               1067                 :     CW(fclose(hba) == 0);
                               1068                 : 
                               1069                 :     snprintf(fname, sizeof(fname), "%s/pg_ident.conf", pgdata);
                               1070                 :     ident = fopen(fname, "w");
                               1071                 :     if (ident == NULL)
                               1072                 :     {
                               1073                 :         bail("could not open file \"%s\" for writing: %s",
                               1074                 :              fname, strerror(errno));
                               1075                 :     }
                               1076                 :     CW(fputs("# Configuration written by config_sspi_auth()\n", ident) >= 0);
                               1077                 : 
                               1078                 :     /*
                               1079                 :      * Double-quote for the benefit of account names containing whitespace or
                               1080                 :      * '#'.  Windows forbids the double-quote character itself, so don't
                               1081                 :      * bother escaping embedded double-quote characters.
                               1082                 :      */
                               1083                 :     CW(fprintf(ident, "regress  \"%s@%s\"  %s\n",
                               1084                 :                accountname, domainname, fmtHba(superuser_name)) >= 0);
                               1085                 :     for (sl = extraroles; sl; sl = sl->next)
                               1086                 :         CW(fprintf(ident, "regress  \"%s@%s\"  %s\n",
                               1087                 :                    accountname, domainname, fmtHba(sl->str)) >= 0);
                               1088                 :     CW(fclose(ident) == 0);
                               1089                 : }
                               1090                 : 
                               1091                 : #endif                          /* ENABLE_SSPI */
                               1092                 : 
                               1093                 : /*
                               1094                 :  * psql_start_command, psql_add_command, psql_end_command
                               1095                 :  *
                               1096                 :  * Issue one or more commands within one psql call.
                               1097                 :  * Set up with psql_start_command, then add commands one at a time
                               1098                 :  * with psql_add_command, and finally execute with psql_end_command.
                               1099                 :  *
                               1100                 :  * Since we use system(), this doesn't return until the operation finishes
                               1101                 :  */
                               1102                 : static StringInfo
  536 tgl                      1103 GIC          94 : psql_start_command(void)
                               1104                 : {
                               1105              94 :     StringInfo  buf = makeStringInfo();
                               1106                 : 
                               1107             188 :     appendStringInfo(buf,
                               1108                 :                      "\"%s%spsql\" -X -q",
                               1109              94 :                      bindir ? bindir : "",
                               1110              94 :                      bindir ? "/" : "");
                               1111              94 :     return buf;
                               1112                 : }
                               1113                 : 
                               1114                 : static void
                               1115             185 : psql_add_command(StringInfo buf, const char *query,...)
                               1116                 : {
                               1117                 :     StringInfoData cmdbuf;
                               1118                 :     const char *cmdptr;
                               1119                 : 
                               1120                 :     /* Add each command as a -c argument in the psql call */
                               1121             185 :     appendStringInfoString(buf, " -c \"");
                               1122                 : 
                               1123                 :     /* Generate the query with insertion of sprintf arguments */
                               1124             185 :     initStringInfo(&cmdbuf);
                               1125                 :     for (;;)
  536 tgl                      1126 UIC           0 :     {
                               1127                 :         va_list     args;
                               1128                 :         int         needed;
                               1129                 : 
  536 tgl                      1130 GIC         185 :         va_start(args, query);
                               1131             185 :         needed = appendStringInfoVA(&cmdbuf, query, args);
                               1132             185 :         va_end(args);
                               1133             185 :         if (needed == 0)
                               1134             185 :             break;              /* success */
  536 tgl                      1135 UIC           0 :         enlargeStringInfo(&cmdbuf, needed);
                               1136                 :     }
                               1137                 : 
                               1138                 :     /* Now escape any shell double-quote metacharacters */
  536 tgl                      1139 GIC       36777 :     for (cmdptr = cmdbuf.data; *cmdptr; cmdptr++)
                               1140                 :     {
                               1141           36592 :         if (strchr("\\\"$`", *cmdptr))
                               1142            1224 :             appendStringInfoChar(buf, '\\');
                               1143           36592 :         appendStringInfoChar(buf, *cmdptr);
                               1144                 :     }
                               1145                 : 
                               1146             185 :     appendStringInfoChar(buf, '"');
                               1147                 : 
                               1148             185 :     pfree(cmdbuf.data);
                               1149             185 : }
                               1150                 : 
                               1151                 : static void
                               1152              94 : psql_end_command(StringInfo buf, const char *database)
                               1153                 : {
                               1154                 :     /* Add the database name --- assume it needs no extra escaping */
                               1155              94 :     appendStringInfo(buf,
                               1156                 :                      " \"%s\"",
                               1157                 :                      database);
                               1158                 : 
                               1159                 :     /* And now we can execute the shell command */
  223 tgl                      1160 GNC          94 :     fflush(NULL);
  536 tgl                      1161 GIC          94 :     if (system(buf->data) != 0)
                               1162                 :     {
                               1163                 :         /* psql probably already reported the error */
    9 dgustafsson              1164 UNC           0 :         bail("command failed: %s", buf->data);
                               1165                 :     }
                               1166                 : 
                               1167                 :     /* Clean up */
  536 tgl                      1168 GIC          94 :     pfree(buf->data);
                               1169              94 :     pfree(buf);
 6108                          1170              94 : }
                               1171                 : 
                               1172                 : /*
                               1173                 :  * Shorthand macro for the common case of a single command
                               1174                 :  */
                               1175                 : #define psql_command(database, ...) \
                               1176                 :     do { \
                               1177                 :         StringInfo cmdbuf = psql_start_command(); \
                               1178                 :         psql_add_command(cmdbuf, __VA_ARGS__); \
                               1179                 :         psql_end_command(cmdbuf, database); \
                               1180                 :     } while (0)
                               1181                 : 
                               1182                 : /*
                               1183                 :  * Spawn a process to execute the given shell command; don't wait for it
                               1184                 :  *
                               1185                 :  * Returns the process ID (or HANDLE) so we can wait for it later
                               1186                 :  */
                               1187                 : PID_TYPE
                               1188            1192 : spawn_process(const char *cmdline)
                               1189                 : {
                               1190                 : #ifndef WIN32
                               1191                 :     pid_t       pid;
                               1192                 : 
                               1193                 :     /*
                               1194                 :      * Must flush I/O buffers before fork.
                               1195                 :      */
  223 tgl                      1196 GNC        1192 :     fflush(NULL);
                               1197                 : 
                               1198                 : #ifdef EXEC_BACKEND
                               1199                 :     pg_disable_aslr();
                               1200                 : #endif
                               1201                 : 
 6108 tgl                      1202 GIC        1192 :     pid = fork();
                               1203            2384 :     if (pid == -1)
                               1204                 :     {
    9 dgustafsson              1205 UNC           0 :         bail("could not fork: %s", strerror(errno));
                               1206                 :     }
 6108 tgl                      1207 GIC        2384 :     if (pid == 0)
                               1208                 :     {
                               1209                 :         /*
                               1210                 :          * In child
                               1211                 :          *
 6031 bruce                    1212 ECB             :          * Instead of using system(), exec the shell directly, and tell it to
                               1213                 :          * "exec" the command too.  This saves two useless processes per
                               1214                 :          * parallel test case.
                               1215                 :          */
 3465 peter_e                  1216                 :         char       *cmdline2;
                               1217                 : 
 3456 tgl                      1218 CBC        1192 :         cmdline2 = psprintf("exec %s", cmdline);
 5744 alvherre                 1219            1192 :         execl(shellprog, shellprog, "-c", cmdline2, (char *) NULL);
                               1220                 :         /* Not using the normal bail() here as we want _exit */
    9 dgustafsson              1221 GNC        1192 :         bail_noatexit("could not exec \"%s\": %s", shellprog, strerror(errno));
                               1222                 :     }
 6108 tgl                      1223 ECB             :     /* in parent */
 6108 tgl                      1224 GIC        1192 :     return pid;
                               1225                 : #else
                               1226                 :     PROCESS_INFORMATION pi;
                               1227                 :     char       *cmdline2;
                               1228                 :     HANDLE      restrictedToken;
 1259 tgl                      1229 ECB             :     const char *comspec;
                               1230                 : 
                               1231                 :     /* Find CMD.EXE location using COMSPEC, if it's set */
                               1232                 :     comspec = getenv("COMSPEC");
                               1233                 :     if (comspec == NULL)
 1259 tgl                      1234 EUB             :         comspec = "CMD";
                               1235                 : 
                               1236                 :     memset(&pi, 0, sizeof(pi));
                               1237                 :     cmdline2 = psprintf("\"%s\" /c \"%s\"", comspec, cmdline);
 6108 tgl                      1238 ECB             : 
 2878 bruce                    1239                 :     if ((restrictedToken =
 1469 peter                    1240                 :          CreateRestrictedProcess(cmdline2, &pi)) == 0)
 4115 peter_e                  1241                 :         exit(2);
 6108 tgl                      1242                 : 
 6108 tgl                      1243 EUB             :     CloseHandle(pi.hThread);
                               1244                 :     return pi.hProcess;
                               1245                 : #endif
                               1246                 : }
 6108 tgl                      1247 ECB             : 
                               1248                 : /*
                               1249                 :  * Count bytes in file
                               1250                 :  */
                               1251                 : static long
 6108 tgl                      1252 GIC          84 : file_size(const char *file)
                               1253                 : {
 6031 bruce                    1254 ECB             :     long        r;
 6031 bruce                    1255 GIC          84 :     FILE       *f = fopen(file, "r");
 6108 tgl                      1256 ECB             : 
 6108 tgl                      1257 CBC          84 :     if (!f)
                               1258                 :     {
    9 dgustafsson              1259 UNC           0 :         diag("could not open file \"%s\" for reading: %s",
                               1260                 :              file, strerror(errno));
 6108 tgl                      1261 UIC           0 :         return -1;
                               1262                 :     }
 6108 tgl                      1263 CBC          84 :     fseek(f, 0, SEEK_END);
 6108 tgl                      1264 GIC          84 :     r = ftell(f);
                               1265              84 :     fclose(f);
                               1266              84 :     return r;
                               1267                 : }
 6108 tgl                      1268 ECB             : 
                               1269                 : /*
                               1270                 :  * Count lines in file
                               1271                 :  */
 6108 tgl                      1272 EUB             : static int
 6108 tgl                      1273 GIC          21 : file_line_count(const char *file)
                               1274                 : {
                               1275                 :     int         c;
 6031 bruce                    1276 CBC          21 :     int         l = 0;
                               1277              21 :     FILE       *f = fopen(file, "r");
 6108 tgl                      1278 ECB             : 
 6108 tgl                      1279 GIC          21 :     if (!f)
                               1280                 :     {
    9 dgustafsson              1281 UNC           0 :         diag("could not open file \"%s\" for reading: %s",
                               1282                 :              file, strerror(errno));
 6108 tgl                      1283 UIC           0 :         return -1;
                               1284                 :     }
 6108 tgl                      1285 GIC       98692 :     while ((c = fgetc(f)) != EOF)
                               1286                 :     {
                               1287           98671 :         if (c == '\n')
                               1288            3721 :             l++;
                               1289                 :     }
                               1290              21 :     fclose(f);
                               1291              21 :     return l;
                               1292                 : }
                               1293                 : 
                               1294                 : bool
                               1295            2141 : file_exists(const char *file)
 6108 tgl                      1296 ECB             : {
 6031 bruce                    1297 GIC        2141 :     FILE       *f = fopen(file, "r");
                               1298                 : 
 6108 tgl                      1299            2141 :     if (!f)
                               1300            2120 :         return false;
                               1301              21 :     fclose(f);
                               1302              21 :     return true;
                               1303                 : }
 6108 tgl                      1304 ECB             : 
                               1305                 : static bool
 6108 tgl                      1306 GIC         332 : directory_exists(const char *dir)
                               1307                 : {
                               1308                 :     struct stat st;
                               1309                 : 
 6108 tgl                      1310 CBC         332 :     if (stat(dir, &st) != 0)
                               1311             255 :         return false;
 5487 tgl                      1312 GIC          77 :     if (S_ISDIR(st.st_mode))
 6108 tgl                      1313 GBC          77 :         return true;
 6108 tgl                      1314 UIC           0 :     return false;
 6108 tgl                      1315 ECB             : }
                               1316                 : 
                               1317                 : /* Create a directory */
                               1318                 : static void
 6108 tgl                      1319 GIC         255 : make_directory(const char *dir)
                               1320                 : {
 6100                          1321             255 :     if (mkdir(dir, S_IRWXU | S_IRWXG | S_IRWXO) < 0)
                               1322                 :     {
    9 dgustafsson              1323 UNC           0 :         bail("could not create directory \"%s\": %s", dir, strerror(errno));
 6108 tgl                      1324 ECB             :     }
 6108 tgl                      1325 CBC         255 : }
                               1326                 : 
 5780 magnus                   1327 ECB             : /*
                               1328                 :  * In: filename.ext, Return: filename_i.ext, where 0 < i <= 9
                               1329                 :  */
                               1330                 : static char *
 5780 magnus                   1331 GIC          47 : get_alternative_expectfile(const char *expectfile, int i)
                               1332                 : {
                               1333                 :     char       *last_dot;
 5624 bruce                    1334              47 :     int         ssize = strlen(expectfile) + 2 + 1;
                               1335                 :     char       *tmp;
                               1336                 :     char       *s;
                               1337                 : 
 3260                          1338              47 :     if (!(tmp = (char *) malloc(ssize)))
 3326 sfrost                   1339 UIC           0 :         return NULL;
                               1340                 : 
 3260 bruce                    1341 GIC          47 :     if (!(s = (char *) malloc(ssize)))
                               1342                 :     {
 3324 sfrost                   1343 UIC           0 :         free(tmp);
                               1344               0 :         return NULL;
                               1345                 :     }
                               1346                 : 
 5780 magnus                   1347 GIC          47 :     strcpy(tmp, expectfile);
 5624 bruce                    1348              47 :     last_dot = strrchr(tmp, '.');
 5780 magnus                   1349              47 :     if (!last_dot)
                               1350                 :     {
 5204 bruce                    1351 UIC           0 :         free(tmp);
                               1352               0 :         free(s);
 5780 magnus                   1353               0 :         return NULL;
                               1354                 :     }
 5780 magnus                   1355 GIC          47 :     *last_dot = '\0';
 5624 bruce                    1356              47 :     snprintf(s, ssize, "%s_%d.%s", tmp, i, last_dot + 1);
 5780 magnus                   1357              47 :     free(tmp);
 5780 magnus                   1358 CBC          47 :     return s;
                               1359                 : }
                               1360                 : 
 6107 tgl                      1361 ECB             : /*
                               1362                 :  * Run a "diff" command and also check that it didn't crash
                               1363                 :  */
                               1364                 : static int
 6097 bruce                    1365 GBC        1257 : run_diff(const char *cmd, const char *filename)
                               1366                 : {
 6031 bruce                    1367 EUB             :     int         r;
                               1368                 : 
  223 tgl                      1369 GNC        1257 :     fflush(NULL);
 6107 tgl                      1370 CBC        1257 :     r = system(cmd);
                               1371            1257 :     if (!WIFEXITED(r) || WEXITSTATUS(r) > 1)
 6107 tgl                      1372 ECB             :     {
    9 dgustafsson              1373 UNC           0 :         bail("diff command failed with status %d: %s", r, cmd);
                               1374                 :     }
                               1375                 : #ifdef WIN32
                               1376                 : 
                               1377                 :     /*
                               1378                 :      * On WIN32, if the 'diff' command cannot be found, system() returns 1,
 6031 bruce                    1379 ECB             :      * but produces nothing to stdout, so we check for that here.
                               1380                 :      */
                               1381                 :     if (WEXITSTATUS(r) == 1 && file_size(filename) <= 0)
 6097                          1382                 :     {
                               1383                 :         bail("diff command not found: %s", cmd);
                               1384                 :     }
                               1385                 : #endif
 6031 bruce                    1386 EUB             : 
 6097 bruce                    1387 GIC        1257 :     return WEXITSTATUS(r);
 6107 tgl                      1388 EUB             : }
                               1389                 : 
 6108 tgl                      1390 ECB             : /*
                               1391                 :  * Check the actual result file for the given test against expected results
                               1392                 :  *
                               1393                 :  * Returns true if different (failure), false if correct match found.
                               1394                 :  * In the true case, the diff is appended to the diffs file.
                               1395                 :  */
                               1396                 : static bool
 5780 magnus                   1397 GIC        1236 : results_differ(const char *testname, const char *resultsfile, const char *default_expectfile)
                               1398                 : {
                               1399                 :     char        expectfile[MAXPGPATH];
 6031 bruce                    1400 ECB             :     char        diff[MAXPGPATH];
                               1401                 :     char        cmd[MAXPGPATH * 3];
                               1402                 :     char        best_expect_file[MAXPGPATH];
                               1403                 :     FILE       *difffile;
                               1404                 :     int         best_line_count;
                               1405                 :     int         i;
                               1406                 :     int         l;
 5780 magnus                   1407                 :     const char *platform_expectfile;
                               1408                 : 
                               1409                 :     /*
                               1410                 :      * We can pass either the resultsfile or the expectfile, they should have
 5624 bruce                    1411                 :      * the same type (filename.type) anyway.
                               1412                 :      */
 5780 magnus                   1413 GIC        1236 :     platform_expectfile = get_expectfile(testname, resultsfile);
                               1414                 : 
 3338 tgl                      1415 CBC        1236 :     strlcpy(expectfile, default_expectfile, sizeof(expectfile));
 5624 bruce                    1416            1236 :     if (platform_expectfile)
 6108 tgl                      1417 ECB             :     {
 5780 magnus                   1418                 :         /*
 2563 sfrost                   1419 EUB             :          * Replace everything after the last slash in expectfile with what the
                               1420                 :          * platform_expectfile contains.
                               1421                 :          */
 5624 bruce                    1422 UIC           0 :         char       *p = strrchr(expectfile, '/');
                               1423                 : 
 5780 magnus                   1424 LBC           0 :         if (p)
 5780 magnus                   1425 UIC           0 :             strcpy(++p, platform_expectfile);
 6108 tgl                      1426 ECB             :     }
                               1427                 : 
 6108 tgl                      1428 EUB             :     /* Name to use for temporary diff file */
 5780 magnus                   1429 GIC        1236 :     snprintf(diff, sizeof(diff), "%s.diff", resultsfile);
 6108 tgl                      1430 ECB             : 
                               1431                 :     /* OK, run the diff */
 6108 tgl                      1432 GIC        1236 :     snprintf(cmd, sizeof(cmd),
                               1433                 :              "diff %s \"%s\" \"%s\" > \"%s\"",
                               1434                 :              basic_diff_opts, expectfile, resultsfile, diff);
                               1435                 : 
 6108 tgl                      1436 ECB             :     /* Is the diff file empty? */
 6097 bruce                    1437 GIC        1236 :     if (run_diff(cmd, diff) == 0)
                               1438                 :     {
 6108 tgl                      1439 CBC        1217 :         unlink(diff);
 6108 tgl                      1440 GIC        1217 :         return false;
                               1441                 :     }
                               1442                 : 
 6108 tgl                      1443 ECB             :     /* There may be secondary comparison files that match better */
 6108 tgl                      1444 GBC          19 :     best_line_count = file_line_count(diff);
 6108 tgl                      1445 GIC          19 :     strcpy(best_expect_file, expectfile);
 6108 tgl                      1446 ECB             : 
 6108 tgl                      1447 GIC          47 :     for (i = 0; i <= 9; i++)
 6108 tgl                      1448 EUB             :     {
 5624 bruce                    1449                 :         char       *alt_expectfile;
                               1450                 : 
 5780 magnus                   1451 GIC          47 :         alt_expectfile = get_alternative_expectfile(expectfile, i);
 3326 sfrost                   1452 CBC          47 :         if (!alt_expectfile)
 3326 sfrost                   1453 ECB             :         {
    9 dgustafsson              1454 UNC           0 :             bail("Unable to check secondary comparison files: %s",
                               1455                 :                  strerror(errno));
 3326 sfrost                   1456 EUB             :         }
                               1457                 : 
 5780 magnus                   1458 GIC          47 :         if (!file_exists(alt_expectfile))
 3326 sfrost                   1459 ECB             :         {
 3326 sfrost                   1460 CBC          26 :             free(alt_expectfile);
 6108 tgl                      1461              26 :             continue;
 3326 sfrost                   1462 ECB             :         }
                               1463                 : 
 6108 tgl                      1464 GIC          21 :         snprintf(cmd, sizeof(cmd),
                               1465                 :                  "diff %s \"%s\" \"%s\" > \"%s\"",
                               1466                 :                  basic_diff_opts, alt_expectfile, resultsfile, diff);
                               1467                 : 
 6097 bruce                    1468              21 :         if (run_diff(cmd, diff) == 0)
 6108 tgl                      1469 ECB             :         {
 6108 tgl                      1470 GIC          19 :             unlink(diff);
 3326 sfrost                   1471              19 :             free(alt_expectfile);
 6108 tgl                      1472              19 :             return false;
 6108 tgl                      1473 ECB             :         }
                               1474                 : 
 6108 tgl                      1475 CBC           2 :         l = file_line_count(diff);
 6108 tgl                      1476 GIC           2 :         if (l < best_line_count)
 6108 tgl                      1477 EUB             :         {
                               1478                 :             /* This diff was a better match than the last one */
 6108 tgl                      1479 GIC           2 :             best_line_count = l;
 3338                          1480               2 :             strlcpy(best_expect_file, alt_expectfile, sizeof(best_expect_file));
                               1481                 :         }
 5780 magnus                   1482               2 :         free(alt_expectfile);
                               1483                 :     }
                               1484                 : 
                               1485                 :     /*
                               1486                 :      * fall back on the canonical results file if we haven't tried it yet and
                               1487                 :      * haven't found a complete match yet.
                               1488                 :      */
                               1489                 : 
 5780 magnus                   1490 UIC           0 :     if (platform_expectfile)
 6095 andrew                   1491 ECB             :     {
 6095 andrew                   1492 UIC           0 :         snprintf(cmd, sizeof(cmd),
                               1493                 :                  "diff %s \"%s\" \"%s\" > \"%s\"",
                               1494                 :                  basic_diff_opts, default_expectfile, resultsfile, diff);
                               1495                 : 
                               1496               0 :         if (run_diff(cmd, diff) == 0)
                               1497                 :         {
                               1498                 :             /* No diff = no changes = good */
                               1499               0 :             unlink(diff);
                               1500               0 :             return false;
 6095 andrew                   1501 ECB             :         }
                               1502                 : 
 6095 andrew                   1503 UIC           0 :         l = file_line_count(diff);
                               1504               0 :         if (l < best_line_count)
                               1505                 :         {
                               1506                 :             /* This diff was a better match than the last one */
                               1507               0 :             best_line_count = l;
 3338 tgl                      1508               0 :             strlcpy(best_expect_file, default_expectfile, sizeof(best_expect_file));
                               1509                 :         }
                               1510                 :     }
                               1511                 : 
                               1512                 :     /*
                               1513                 :      * Use the best comparison file to generate the "pretty" diff, which we
                               1514                 :      * append to the diffs summary file.
                               1515                 :      */
                               1516                 : 
 1558 peter                    1517 ECB             :     /* Write diff header */
 6108 tgl                      1518 UIC           0 :     difffile = fopen(difffilename, "a");
 6108 tgl                      1519 LBC           0 :     if (difffile)
 6108 tgl                      1520 ECB             :     {
 6108 tgl                      1521 UIC           0 :         fprintf(difffile,
                               1522                 :                 "diff %s %s %s\n",
                               1523                 :                 pretty_diff_opts, best_expect_file, resultsfile);
                               1524               0 :         fclose(difffile);
                               1525                 :     }
 6108 tgl                      1526 EUB             : 
                               1527                 :     /* Run diff */
 1558 peter                    1528 UBC           0 :     snprintf(cmd, sizeof(cmd),
 1558 peter                    1529 EUB             :              "diff %s \"%s\" \"%s\" >> \"%s\"",
                               1530                 :              pretty_diff_opts, best_expect_file, resultsfile, difffilename);
 1558 peter                    1531 UIC           0 :     run_diff(cmd, difffilename);
                               1532                 : 
 6108 tgl                      1533 LBC           0 :     unlink(diff);
 6108 tgl                      1534 UIC           0 :     return true;
                               1535                 : }
 6108 tgl                      1536 ECB             : 
                               1537                 : /*
                               1538                 :  * Wait for specified subprocesses to finish, and return their exit
                               1539                 :  * statuses into statuses[] and stop times into stoptimes[]
                               1540                 :  *
 5440                          1541                 :  * If names isn't NULL, print each subprocess's name as it finishes
                               1542                 :  *
 6107                          1543                 :  * Note: it's OK to scribble on the pids array, but not on the names array
 6108                          1544                 :  */
                               1545                 : static void
 1519 tgl                      1546 GIC         543 : wait_for_tests(PID_TYPE * pids, int *statuses, instr_time *stoptimes,
                               1547                 :                char **names, int num_tests)
 6108 tgl                      1548 ECB             : {
 6031 bruce                    1549                 :     int         tests_left;
                               1550                 :     int         i;
 6108 tgl                      1551                 : 
                               1552                 : #ifdef WIN32
                               1553                 :     PID_TYPE   *active_pids = pg_malloc(num_tests * sizeof(PID_TYPE));
                               1554                 : 
 6107                          1555                 :     memcpy(active_pids, pids, num_tests * sizeof(PID_TYPE));
                               1556                 : #endif
                               1557                 : 
 6108 tgl                      1558 GBC         543 :     tests_left = num_tests;
 6108 tgl                      1559 GIC        1653 :     while (tests_left > 0)
                               1560                 :     {
                               1561                 :         PID_TYPE    p;
 6107 tgl                      1562 ECB             : 
                               1563                 : #ifndef WIN32
 5184 magnus                   1564                 :         int         exit_status;
 5050 bruce                    1565                 : 
 5440 tgl                      1566 GIC        1110 :         p = wait(&exit_status);
                               1567                 : 
 6107 tgl                      1568 CBC        1110 :         if (p == INVALID_PID)
                               1569                 :         {
    9 dgustafsson              1570 UNC           0 :             bail("failed to wait for subprocesses: %s", strerror(errno));
                               1571                 :         }
 6107 tgl                      1572 ECB             : #else
 5184 magnus                   1573                 :         DWORD       exit_status;
 6031 bruce                    1574                 :         int         r;
                               1575                 : 
                               1576                 :         r = WaitForMultipleObjects(tests_left, active_pids, FALSE, INFINITE);
 6107 tgl                      1577                 :         if (r < WAIT_OBJECT_0 || r >= WAIT_OBJECT_0 + tests_left)
 6108                          1578                 :         {
                               1579                 :             bail("failed to wait for subprocesses: error code %lu",
                               1580                 :                  GetLastError());
                               1581                 :         }
                               1582                 :         p = active_pids[r - WAIT_OBJECT_0];
 6107                          1583                 :         /* compact the active_pids array */
                               1584                 :         active_pids[r - WAIT_OBJECT_0] = active_pids[tests_left - 1];
                               1585                 : #endif                          /* WIN32 */
                               1586                 : 
 6031 bruce                    1587 GIC        5613 :         for (i = 0; i < num_tests; i++)
                               1588                 :         {
 6108 tgl                      1589            5613 :             if (p == pids[i])
                               1590                 :             {
 6107 tgl                      1591 EUB             : #ifdef WIN32
                               1592                 :                 GetExitCodeProcess(pids[i], &exit_status);
                               1593                 :                 CloseHandle(pids[i]);
                               1594                 : #endif
 6107 tgl                      1595 GIC        1110 :                 pids[i] = INVALID_PID;
 5184 magnus                   1596            1110 :                 statuses[i] = (int) exit_status;
 1519 tgl                      1597 GBC        1110 :                 INSTR_TIME_SET_CURRENT(stoptimes[i]);
 6107 tgl                      1598 GIC        1110 :                 if (names)
    9 dgustafsson              1599 GNC         621 :                     note_detail(" %s", names[i]);
 6108 tgl                      1600 GBC        1110 :                 tests_left--;
 6107                          1601            1110 :                 break;
                               1602                 :             }
                               1603                 :         }
 6108 tgl                      1604 EUB             :     }
                               1605                 : 
                               1606                 : #ifdef WIN32
                               1607                 :     free(active_pids);
                               1608                 : #endif
 6108 tgl                      1609 GBC         543 : }
                               1610                 : 
                               1611                 : /*
                               1612                 :  * report nonzero exit code from a test process
                               1613                 :  */
                               1614                 : static void
 5440 tgl                      1615 UIC           0 : log_child_failure(int exitstatus)
                               1616                 : {
                               1617               0 :     if (WIFEXITED(exitstatus))
    9 dgustafsson              1618 UNC           0 :         diag("(test process exited with exit code %d)",
                               1619                 :              WEXITSTATUS(exitstatus));
 5440 tgl                      1620 UBC           0 :     else if (WIFSIGNALED(exitstatus))
                               1621                 :     {
 5440 tgl                      1622 EUB             : #if defined(WIN32)
                               1623                 :         diag("(test process was terminated by exception 0x%X)",
                               1624                 :              WTERMSIG(exitstatus));
                               1625                 : #else
    9 dgustafsson              1626 UNC           0 :         diag("(test process was terminated by signal %d: %s)",
                               1627                 :              WTERMSIG(exitstatus), pg_strsignal(WTERMSIG(exitstatus)));
                               1628                 : #endif
 5440 tgl                      1629 EUB             :     }
                               1630                 :     else
    9 dgustafsson              1631 UNC           0 :         diag("(test process exited with unrecognized status %d)", exitstatus);
 5440 tgl                      1632 UIC           0 : }
 5440 tgl                      1633 EUB             : 
 6108                          1634                 : /*
                               1635                 :  * Run all the tests specified in one schedule file
                               1636                 :  */
                               1637                 : static void
  818 tgl                      1638 GIC           5 : run_schedule(const char *schedule, test_start_function startfunc,
                               1639                 :              postprocess_result_function postfunc)
                               1640                 : {
                               1641                 : #define MAX_PARALLEL_TESTS 100
                               1642                 :     char       *tests[MAX_PARALLEL_TESTS];
                               1643                 :     _stringlist *resultfiles[MAX_PARALLEL_TESTS];
                               1644                 :     _stringlist *expectfiles[MAX_PARALLEL_TESTS];
                               1645                 :     _stringlist *tags[MAX_PARALLEL_TESTS];
 6031 bruce                    1646 ECB             :     PID_TYPE    pids[MAX_PARALLEL_TESTS];
                               1647                 :     instr_time  starttimes[MAX_PARALLEL_TESTS];
                               1648                 :     instr_time  stoptimes[MAX_PARALLEL_TESTS];
                               1649                 :     int         statuses[MAX_PARALLEL_TESTS];
                               1650                 :     char        scbuf[1024];
                               1651                 :     FILE       *scf;
 6031 bruce                    1652 GIC           5 :     int         line_num = 0;
                               1653                 : 
 2010 tgl                      1654               5 :     memset(tests, 0, sizeof(tests));
                               1655               5 :     memset(resultfiles, 0, sizeof(resultfiles));
                               1656               5 :     memset(expectfiles, 0, sizeof(expectfiles));
 2010 tgl                      1657 CBC           5 :     memset(tags, 0, sizeof(tags));
 5780 magnus                   1658 ECB             : 
 6108 tgl                      1659 GIC           5 :     scf = fopen(schedule, "r");
                               1660               5 :     if (!scf)
                               1661                 :     {
    9 dgustafsson              1662 UNC           0 :         bail("could not open file \"%s\" for reading: %s",
                               1663                 :              schedule, strerror(errno));
 6108 tgl                      1664 ECB             :     }
                               1665                 : 
 6108 tgl                      1666 CBC         581 :     while (fgets(scbuf, sizeof(scbuf), scf))
                               1667                 :     {
 6031 bruce                    1668 GBC         576 :         char       *test = NULL;
                               1669                 :         char       *c;
                               1670                 :         int         num_tests;
                               1671                 :         bool        inword;
                               1672                 :         int         i;
                               1673                 : 
 6108 tgl                      1674 GIC         576 :         line_num++;
                               1675                 : 
                               1676                 :         /* strip trailing whitespace, especially the newline */
                               1677             576 :         i = strlen(scbuf);
 6031 bruce                    1678            1152 :         while (i > 0 && isspace((unsigned char) scbuf[i - 1]))
 6108 tgl                      1679             576 :             scbuf[--i] = '\0';
                               1680                 : 
                               1681             576 :         if (scbuf[0] == '\0' || scbuf[0] == '#')
                               1682             327 :             continue;
                               1683             249 :         if (strncmp(scbuf, "test: ", 6) == 0)
                               1684             249 :             test = scbuf + 6;
 6108 tgl                      1685 ECB             :         else
                               1686                 :         {
    9 dgustafsson              1687 UNC           0 :             bail("syntax error in schedule file \"%s\" line %d: %s",
                               1688                 :                  schedule, line_num, scbuf);
                               1689                 :         }
                               1690                 : 
 6108 tgl                      1691 GIC         249 :         num_tests = 0;
 6108 tgl                      1692 CBC         249 :         inword = false;
 2010 tgl                      1693 GIC        9612 :         for (c = test;; c++)
                               1694                 :         {
                               1695            9612 :             if (*c == '\0' || isspace((unsigned char) *c))
                               1696                 :             {
                               1697             816 :                 if (inword)
 2010 tgl                      1698 EUB             :                 {
                               1699                 :                     /* Reached end of a test name */
                               1700                 :                     char        sav;
                               1701                 : 
 2010 tgl                      1702 GIC         816 :                     if (num_tests >= MAX_PARALLEL_TESTS)
 2010 tgl                      1703 EUB             :                     {
    9 dgustafsson              1704 UNC           0 :                         bail("too many parallel tests (more than %d) in schedule file \"%s\" line %d: %s",
                               1705                 :                              MAX_PARALLEL_TESTS, schedule, line_num, scbuf);
                               1706                 :                     }
 2010 tgl                      1707 GIC         816 :                     sav = *c;
 2010 tgl                      1708 GBC         816 :                     *c = '\0';
 2010 tgl                      1709 GIC         816 :                     tests[num_tests] = pg_strdup(test);
                               1710             816 :                     num_tests++;
                               1711             816 :                     *c = sav;
                               1712             816 :                     inword = false;
 2010 tgl                      1713 EUB             :                 }
 2010 tgl                      1714 GBC         816 :                 if (*c == '\0')
 2010 tgl                      1715 GIC         249 :                     break;      /* loop exit is here */
                               1716                 :             }
 6108                          1717            8796 :             else if (!inword)
                               1718                 :             {
                               1719                 :                 /* Start of a test name */
 2010 tgl                      1720 CBC         816 :                 test = c;
 6108 tgl                      1721 GIC         816 :                 inword = true;
                               1722                 :             }
                               1723                 :         }
                               1724                 : 
                               1725             249 :         if (num_tests == 0)
                               1726                 :         {
    9 dgustafsson              1727 UNC           0 :             bail("syntax error in schedule file \"%s\" line %d: %s",
                               1728                 :                  schedule, line_num, scbuf);
                               1729                 :         }
                               1730                 : 
 6108 tgl                      1731 GIC         249 :         if (num_tests == 1)
                               1732                 :         {
  818                          1733             195 :             pids[0] = (startfunc) (tests[0], &resultfiles[0], &expectfiles[0], &tags[0]);
 1519 tgl                      1734 CBC         195 :             INSTR_TIME_SET_CURRENT(starttimes[0]);
                               1735             195 :             wait_for_tests(pids, statuses, stoptimes, NULL, 1);
 6108 tgl                      1736 ECB             :             /* status line is finished below */
                               1737                 :         }
 2010 tgl                      1738 GIC          54 :         else if (max_concurrent_tests > 0 && max_concurrent_tests < num_tests)
 2010 tgl                      1739 ECB             :         {
    9 dgustafsson              1740 UNC           0 :             bail("too many parallel tests (more than %d) in schedule file \"%s\" line %d: %s",
                               1741                 :                  max_concurrent_tests, schedule, line_num, scbuf);
                               1742                 :         }
 6108 tgl                      1743 GIC          54 :         else if (max_connections > 0 && max_connections < num_tests)
 6108 tgl                      1744 UIC           0 :         {
 6031 bruce                    1745 LBC           0 :             int         oldest = 0;
                               1746                 : 
    9 dgustafsson              1747 UNC           0 :             note_detail("parallel group (%d tests, in groups of %d): ",
                               1748                 :                         num_tests, max_connections);
 6108 tgl                      1749 UIC           0 :             for (i = 0; i < num_tests; i++)
                               1750                 :             {
                               1751               0 :                 if (i - oldest >= max_connections)
                               1752                 :                 {
 5440 tgl                      1753 LBC           0 :                     wait_for_tests(pids + oldest, statuses + oldest,
 1519 tgl                      1754 UIC           0 :                                    stoptimes + oldest,
 5440                          1755               0 :                                    tests + oldest, i - oldest);
 6108 tgl                      1756 LBC           0 :                     oldest = i;
 6108 tgl                      1757 ECB             :                 }
  818 tgl                      1758 LBC           0 :                 pids[i] = (startfunc) (tests[i], &resultfiles[i], &expectfiles[i], &tags[i]);
 1519 tgl                      1759 UIC           0 :                 INSTR_TIME_SET_CURRENT(starttimes[i]);
 6108 tgl                      1760 ECB             :             }
 5440 tgl                      1761 LBC           0 :             wait_for_tests(pids + oldest, statuses + oldest,
 1519                          1762               0 :                            stoptimes + oldest,
 5440                          1763               0 :                            tests + oldest, i - oldest);
    9 dgustafsson              1764 UNC           0 :             note_end();
                               1765                 :         }
 6108 tgl                      1766 EUB             :         else
                               1767                 :         {
    9 dgustafsson              1768 GNC          54 :             note_detail("parallel group (%d tests): ", num_tests);
 6108 tgl                      1769 GIC         675 :             for (i = 0; i < num_tests; i++)
 6108 tgl                      1770 ECB             :             {
  818 tgl                      1771 CBC         621 :                 pids[i] = (startfunc) (tests[i], &resultfiles[i], &expectfiles[i], &tags[i]);
 1519                          1772             621 :                 INSTR_TIME_SET_CURRENT(starttimes[i]);
                               1773                 :             }
                               1774              54 :             wait_for_tests(pids, statuses, stoptimes, tests, num_tests);
    9 dgustafsson              1775 GNC          54 :             note_end();
 6108 tgl                      1776 ECB             :         }
                               1777                 : 
                               1778                 :         /* Check results for all tests */
 6108 tgl                      1779 GIC        1065 :         for (i = 0; i < num_tests; i++)
                               1780                 :         {
 5624 bruce                    1781 ECB             :             _stringlist *rl,
                               1782                 :                        *el,
 5624 bruce                    1783 EUB             :                        *tl;
 5624 bruce                    1784 GIC         816 :             bool        differ = false;
                               1785                 : 
    9 dgustafsson              1786 GNC         816 :             INSTR_TIME_SUBTRACT(stoptimes[i], starttimes[i]);
 6108 tgl                      1787 ECB             : 
 5780 magnus                   1788                 :             /*
                               1789                 :              * Advance over all three lists simultaneously.
                               1790                 :              *
                               1791                 :              * Compare resultfiles[j] with expectfiles[j] always. Tags are
 5624 bruce                    1792                 :              * optional but if there are tags, the tag list has the same
                               1793                 :              * length as the other two lists.
                               1794                 :              */
 5780 magnus                   1795 CBC         816 :             for (rl = resultfiles[i], el = expectfiles[i], tl = tags[i];
 5624 bruce                    1796 GIC        1756 :                  rl != NULL;    /* rl and el have the same length */
 1806 tgl                      1797             940 :                  rl = rl->next, el = el->next,
 1806 tgl                      1798 CBC         940 :                  tl = tl ? tl->next : NULL)
 5780 magnus                   1799 ECB             :             {
                               1800                 :                 bool        newdiff;
                               1801                 : 
  818 tgl                      1802 GIC         940 :                 if (postfunc)
  818 tgl                      1803 CBC         186 :                     (*postfunc) (rl->str);
 5780 magnus                   1804 GIC         940 :                 newdiff = results_differ(tests[i], rl->str, el->str);
 5624 bruce                    1805 GBC         940 :                 if (newdiff && tl)
                               1806                 :                 {
    9 dgustafsson              1807 UNC           0 :                     diag("tag: %s", tl->str);
                               1808                 :                 }
 5780 magnus                   1809 CBC         940 :                 differ |= newdiff;
                               1810                 :             }
 5780 magnus                   1811 ECB             : 
   45 dgustafsson              1812 GNC         816 :             if (statuses[i] != 0)
 6108 tgl                      1813 ECB             :             {
    9 dgustafsson              1814 UNC           0 :                 test_status_failed(tests[i], INSTR_TIME_GET_MILLISEC(stoptimes[i]), (num_tests > 1));
   45                          1815               0 :                 log_child_failure(statuses[i]);
                               1816                 :             }
 6108 tgl                      1817 EUB             :             else
                               1818                 :             {
   45 dgustafsson              1819 GNC         816 :                 if (differ)
                               1820                 :                 {
    9 dgustafsson              1821 UNC           0 :                     test_status_failed(tests[i], INSTR_TIME_GET_MILLISEC(stoptimes[i]), (num_tests > 1));
                               1822                 :                 }
                               1823                 :                 else
                               1824                 :                 {
    9 dgustafsson              1825 GNC         816 :                     test_status_ok(tests[i], INSTR_TIME_GET_MILLISEC(stoptimes[i]), (num_tests > 1));
                               1826                 :                 }
   45 dgustafsson              1827 EUB             :             }
 6108 tgl                      1828 ECB             :         }
 2010                          1829                 : 
 2010 tgl                      1830 GIC        1065 :         for (i = 0; i < num_tests; i++)
 2010 tgl                      1831 ECB             :         {
 2010 tgl                      1832 CBC         816 :             pg_free(tests[i]);
 2010 tgl                      1833 GIC         816 :             tests[i] = NULL;
                               1834             816 :             free_stringlist(&resultfiles[i]);
                               1835             816 :             free_stringlist(&expectfiles[i]);
 2010 tgl                      1836 CBC         816 :             free_stringlist(&tags[i]);
                               1837                 :         }
                               1838                 :     }
                               1839                 : 
 6108 tgl                      1840 GIC           5 :     fclose(scf);
 6108 tgl                      1841 CBC           5 : }
                               1842                 : 
                               1843                 : /*
                               1844                 :  * Run a single test
                               1845                 :  */
                               1846                 : static void
  818 tgl                      1847 GIC         294 : run_single_test(const char *test, test_start_function startfunc,
                               1848                 :                 postprocess_result_function postfunc)
                               1849                 : {
 6031 bruce                    1850 ECB             :     PID_TYPE    pid;
 1519 tgl                      1851                 :     instr_time  starttime;
                               1852                 :     instr_time  stoptime;
 5440                          1853                 :     int         exit_status;
 5780 magnus                   1854 GIC         294 :     _stringlist *resultfiles = NULL;
                               1855             294 :     _stringlist *expectfiles = NULL;
                               1856             294 :     _stringlist *tags = NULL;
 5624 bruce                    1857 ECB             :     _stringlist *rl,
                               1858                 :                *el,
                               1859                 :                *tl;
 5780 magnus                   1860 CBC         294 :     bool        differ = false;
                               1861                 : 
  818 tgl                      1862 GIC         294 :     pid = (startfunc) (test, &resultfiles, &expectfiles, &tags);
 1519 tgl                      1863 CBC         294 :     INSTR_TIME_SET_CURRENT(starttime);
 1519 tgl                      1864 GIC         294 :     wait_for_tests(&pid, &exit_status, &stoptime, NULL, 1);
                               1865                 : 
 5780 magnus                   1866 ECB             :     /*
                               1867                 :      * Advance over all three lists simultaneously.
 5780 magnus                   1868 EUB             :      *
 5624 bruce                    1869                 :      * Compare resultfiles[j] with expectfiles[j] always. Tags are optional
                               1870                 :      * but if there are tags, the tag list has the same length as the other
                               1871                 :      * two lists.
                               1872                 :      */
 5780 magnus                   1873 CBC         294 :     for (rl = resultfiles, el = expectfiles, tl = tags;
 5624 bruce                    1874 GIC         590 :          rl != NULL;            /* rl and el have the same length */
 1806 tgl                      1875 GBC         296 :          rl = rl->next, el = el->next,
 1806 tgl                      1876 GIC         296 :          tl = tl ? tl->next : NULL)
                               1877                 :     {
                               1878                 :         bool        newdiff;
 5624 bruce                    1879 ECB             : 
  818 tgl                      1880 GIC         296 :         if (postfunc)
                               1881               3 :             (*postfunc) (rl->str);
 5780 magnus                   1882             296 :         newdiff = results_differ(test, rl->str, el->str);
 5624 bruce                    1883             296 :         if (newdiff && tl)
 5780 magnus                   1884 ECB             :         {
    9 dgustafsson              1885 UNC           0 :             diag("tag: %s", tl->str);
 5780 magnus                   1886 ECB             :         }
 5780 magnus                   1887 CBC         296 :         differ |= newdiff;
 5780 magnus                   1888 ECB             :     }
                               1889                 : 
    9 dgustafsson              1890 GNC         294 :     INSTR_TIME_SUBTRACT(stoptime, starttime);
                               1891                 : 
   45                          1892             294 :     if (exit_status != 0)
                               1893                 :     {
    9 dgustafsson              1894 UNC           0 :         test_status_failed(test, false, INSTR_TIME_GET_MILLISEC(stoptime));
   45                          1895               0 :         log_child_failure(exit_status);
 6108 tgl                      1896 ECB             :     }
                               1897                 :     else
                               1898                 :     {
   45 dgustafsson              1899 GNC         294 :         if (differ)
                               1900                 :         {
    9 dgustafsson              1901 UNC           0 :             test_status_failed(test, false, INSTR_TIME_GET_MILLISEC(stoptime));
                               1902                 :         }
                               1903                 :         else
                               1904                 :         {
    9 dgustafsson              1905 GNC         294 :             test_status_ok(test, INSTR_TIME_GET_MILLISEC(stoptime), false);
                               1906                 :         }
                               1907                 :     }
 6108 tgl                      1908 CBC         294 : }
 6108 tgl                      1909 ECB             : 
                               1910                 : /*
                               1911                 :  * Create the summary-output files (making them empty if already existing)
                               1912                 :  */
                               1913                 : static void
 6108 tgl                      1914 CBC          84 : open_result_files(void)
                               1915                 : {
 6031 bruce                    1916 ECB             :     char        file[MAXPGPATH];
                               1917                 :     FILE       *difffile;
 6108 tgl                      1918                 : 
                               1919                 :     /* create outputdir directory if not present */
 2217 andres                   1920 GIC          84 :     if (!directory_exists(outputdir))
                               1921               7 :         make_directory(outputdir);
                               1922                 : 
                               1923                 :     /* create the log file (copy of running status output) */
 6108 tgl                      1924              84 :     snprintf(file, sizeof(file), "%s/regression.out", outputdir);
 2413                          1925              84 :     logfilename = pg_strdup(file);
 6108                          1926              84 :     logfile = fopen(logfilename, "w");
 6108 tgl                      1927 CBC          84 :     if (!logfile)
 6108 tgl                      1928 ECB             :     {
    9 dgustafsson              1929 UNC           0 :         bail("could not open file \"%s\" for writing: %s",
                               1930                 :              logfilename, strerror(errno));
                               1931                 :     }
                               1932                 : 
 6108 tgl                      1933 ECB             :     /* create the diffs file as empty */
 6108 tgl                      1934 CBC          84 :     snprintf(file, sizeof(file), "%s/regression.diffs", outputdir);
 2413                          1935              84 :     difffilename = pg_strdup(file);
 6108                          1936              84 :     difffile = fopen(difffilename, "w");
 6108 tgl                      1937 GIC          84 :     if (!difffile)
 6108 tgl                      1938 EUB             :     {
    9 dgustafsson              1939 UNC           0 :         bail("could not open file \"%s\" for writing: %s",
                               1940                 :              difffilename, strerror(errno));
                               1941                 :     }
 6108 tgl                      1942 ECB             :     /* we don't keep the diffs file open continuously */
 6108 tgl                      1943 GIC          84 :     fclose(difffile);
 6108 tgl                      1944 ECB             : 
                               1945                 :     /* also create the results directory if not present */
 6108 tgl                      1946 GBC          84 :     snprintf(file, sizeof(file), "%s/results", outputdir);
                               1947              84 :     if (!directory_exists(file))
 6108 tgl                      1948 GIC          84 :         make_directory(file);
                               1949              84 : }
                               1950                 : 
 5780 magnus                   1951 ECB             : static void
 5780 magnus                   1952 GIC           2 : drop_database_if_exists(const char *dbname)
 5780 magnus                   1953 EUB             : {
  536 tgl                      1954 GIC           2 :     StringInfo  buf = psql_start_command();
                               1955                 : 
  536 tgl                      1956 ECB             :     /* Set warning level so we don't see chatter about nonexistent DB */
  536 tgl                      1957 GIC           2 :     psql_add_command(buf, "SET client_min_messages = warning");
                               1958               2 :     psql_add_command(buf, "DROP DATABASE IF EXISTS \"%s\"", dbname);
  536 tgl                      1959 CBC           2 :     psql_end_command(buf, "postgres");
 5780 magnus                   1960 GIC           2 : }
                               1961                 : 
                               1962                 : static void
                               1963              85 : create_database(const char *dbname)
                               1964                 : {
  536 tgl                      1965 CBC          85 :     StringInfo  buf = psql_start_command();
                               1966                 :     _stringlist *sl;
                               1967                 : 
                               1968                 :     /*
                               1969                 :      * We use template0 so that any installation-local cruft in template1 will
                               1970                 :      * not mess up the tests.
 5780 magnus                   1971 ECB             :      */
 5780 magnus                   1972 GIC          85 :     if (encoding)
  536 tgl                      1973               2 :         psql_add_command(buf, "CREATE DATABASE \"%s\" TEMPLATE=template0 ENCODING='%s'%s", dbname, encoding,
  536 tgl                      1974 CBC           2 :                          (nolocale) ? " LC_COLLATE='C' LC_CTYPE='C'" : "");
 5780 magnus                   1975 ECB             :     else
  536 tgl                      1976 CBC          83 :         psql_add_command(buf, "CREATE DATABASE \"%s\" TEMPLATE=template0%s", dbname,
                               1977              83 :                          (nolocale) ? " LC_COLLATE='C' LC_CTYPE='C'" : "");
  536 tgl                      1978 GIC          85 :     psql_add_command(buf,
  536 tgl                      1979 EUB             :                      "ALTER DATABASE \"%s\" SET lc_messages TO 'C';"
                               1980                 :                      "ALTER DATABASE \"%s\" SET lc_monetary TO 'C';"
                               1981                 :                      "ALTER DATABASE \"%s\" SET lc_numeric TO 'C';"
                               1982                 :                      "ALTER DATABASE \"%s\" SET lc_time TO 'C';"
                               1983                 :                      "ALTER DATABASE \"%s\" SET bytea_output TO 'hex';"
  536 tgl                      1984 ECB             :                      "ALTER DATABASE \"%s\" SET timezone_abbreviations TO 'Default';",
                               1985                 :                      dbname, dbname, dbname, dbname, dbname, dbname);
  536 tgl                      1986 CBC          85 :     psql_end_command(buf, "postgres");
 5780 magnus                   1987 ECB             : 
                               1988                 :     /*
 4382 bruce                    1989 EUB             :      * Install any requested extensions.  We use CREATE IF NOT EXISTS so that
                               1990                 :      * this will work whether or not the extension is preinstalled.
                               1991                 :      */
 4419 tgl                      1992 GIC          90 :     for (sl = loadextension; sl != NULL; sl = sl->next)
                               1993               5 :         psql_command(dbname, "CREATE EXTENSION IF NOT EXISTS \"%s\"", sl->str);
 5780 magnus                   1994 CBC          85 : }
 5780 magnus                   1995 ECB             : 
                               1996                 : static void
 5780 magnus                   1997 UIC           0 : drop_role_if_exists(const char *rolename)
                               1998                 : {
  536 tgl                      1999 LBC           0 :     StringInfo  buf = psql_start_command();
                               2000                 : 
                               2001                 :     /* Set warning level so we don't see chatter about nonexistent role */
  536 tgl                      2002 UIC           0 :     psql_add_command(buf, "SET client_min_messages = warning");
  536 tgl                      2003 LBC           0 :     psql_add_command(buf, "DROP ROLE IF EXISTS \"%s\"", rolename);
                               2004               0 :     psql_end_command(buf, "postgres");
 5780 magnus                   2005               0 : }
 5780 magnus                   2006 ECB             : 
                               2007                 : static void
 3260 bruce                    2008 GIC           2 : create_role(const char *rolename, const _stringlist *granted_dbs)
 5780 magnus                   2009 ECB             : {
  536 tgl                      2010 GIC           2 :     StringInfo  buf = psql_start_command();
  536 tgl                      2011 ECB             : 
  536 tgl                      2012 GIC           2 :     psql_add_command(buf, "CREATE ROLE \"%s\" WITH LOGIN", rolename);
 5780 magnus                   2013               6 :     for (; granted_dbs != NULL; granted_dbs = granted_dbs->next)
                               2014                 :     {
  536 tgl                      2015               4 :         psql_add_command(buf, "GRANT ALL ON DATABASE \"%s\" TO \"%s\"",
                               2016               4 :                          granted_dbs->str, rolename);
 5780 magnus                   2017 ECB             :     }
  536 tgl                      2018 CBC           2 :     psql_end_command(buf, "postgres");
 5780 magnus                   2019               2 : }
                               2020                 : 
 6108 tgl                      2021 ECB             : static void
 6108 tgl                      2022 LBC           0 : help(void)
 6108 tgl                      2023 ECB             : {
 6108 tgl                      2024 UIC           0 :     printf(_("PostgreSQL regression test driver\n"));
                               2025               0 :     printf(_("\n"));
 4240 peter_e                  2026               0 :     printf(_("Usage:\n  %s [OPTION]... [EXTRA-TEST]...\n"), progname);
 6108 tgl                      2027               0 :     printf(_("\n"));
                               2028               0 :     printf(_("Options:\n"));
 2004 mail                     2029               0 :     printf(_("      --bindir=BINPATH          use BINPATH for programs that are run;\n"));
                               2030               0 :     printf(_("                                if empty, use PATH from the environment\n"));
 2004 mail                     2031 LBC           0 :     printf(_("      --config-auth=DATADIR     update authentication settings for DATADIR\n"));
 2004 mail                     2032 UIC           0 :     printf(_("      --create-role=ROLE        create the specified role before testing\n"));
                               2033               0 :     printf(_("      --dbname=DB               use database DB (default \"regression\")\n"));
                               2034               0 :     printf(_("      --debug                   turn on debug mode in programs that are run\n"));
                               2035               0 :     printf(_("      --dlpath=DIR              look for dynamic libraries in DIR\n"));
                               2036               0 :     printf(_("      --encoding=ENCODING       use ENCODING as the encoding\n"));
  232 andres                   2037 UNC           0 :     printf(_("      --expecteddir=DIR         take expected files from DIR (default \".\")\n"));
 2004 mail                     2038 LBC           0 :     printf(_("  -h, --help                    show this help, then exit\n"));
                               2039               0 :     printf(_("      --inputdir=DIR            take input files from DIR (default \".\")\n"));
                               2040               0 :     printf(_("      --launcher=CMD            use CMD as launcher of psql\n"));
 2004 mail                     2041 UIC           0 :     printf(_("      --load-extension=EXT      load the named extension before running the\n"));
                               2042               0 :     printf(_("                                tests; can appear multiple times\n"));
 2004 mail                     2043 UBC           0 :     printf(_("      --max-connections=N       maximum number of concurrent connections\n"));
 2004 mail                     2044 UIC           0 :     printf(_("                                (default is 0, meaning unlimited)\n"));
 2004 mail                     2045 UBC           0 :     printf(_("      --max-concurrent-tests=N  maximum number of concurrent tests in schedule\n"));
 2004 mail                     2046 UIC           0 :     printf(_("                                (default is 0, meaning unlimited)\n"));
                               2047               0 :     printf(_("      --outputdir=DIR           place output files in DIR (default \".\")\n"));
 2004 mail                     2048 UBC           0 :     printf(_("      --schedule=FILE           use test ordering schedule from FILE\n"));
                               2049               0 :     printf(_("                                (can be used multiple times to concatenate)\n"));
                               2050               0 :     printf(_("      --temp-instance=DIR       create a temporary instance in DIR\n"));
                               2051               0 :     printf(_("      --use-existing            use an existing installation\n"));
 2004 mail                     2052 UIC           0 :     printf(_("  -V, --version                 output version information, then exit\n"));
 2865 tgl                      2053               0 :     printf(_("\n"));
 2908 peter_e                  2054 LBC           0 :     printf(_("Options for \"temp-instance\" mode:\n"));
 2004 mail                     2055 UIC           0 :     printf(_("      --no-locale               use C locale\n"));
 2004 mail                     2056 LBC           0 :     printf(_("      --port=PORT               start postmaster on PORT\n"));
 2004 mail                     2057 UIC           0 :     printf(_("      --temp-config=FILE        append contents of FILE to temporary config\n"));
 6108 tgl                      2058 LBC           0 :     printf(_("\n"));
                               2059               0 :     printf(_("Options for using an existing installation:\n"));
 2004 mail                     2060 UIC           0 :     printf(_("      --host=HOST               use postmaster running on HOST\n"));
 2004 mail                     2061 LBC           0 :     printf(_("      --port=PORT               use postmaster running at PORT\n"));
                               2062               0 :     printf(_("      --user=USER               connect as USER\n"));
 6108 tgl                      2063 UIC           0 :     printf(_("\n"));
 6108 tgl                      2064 LBC           0 :     printf(_("The exit status is 0 if all tests passed, 1 if some tests failed, and 2\n"));
                               2065               0 :     printf(_("if the tests could not be run for some reason.\n"));
 6108 tgl                      2066 UIC           0 :     printf(_("\n"));
 1136 peter                    2067               0 :     printf(_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT);
 1136 peter                    2068 UBC           0 :     printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
 6108 tgl                      2069 UIC           0 : }
 6108 tgl                      2070 EUB             : 
                               2071                 : int
  818 tgl                      2072 GBC         303 : regression_main(int argc, char *argv[],
  818 tgl                      2073 EUB             :                 init_function ifunc,
                               2074                 :                 test_start_function startfunc,
                               2075                 :                 postprocess_result_function postfunc)
 6108                          2076                 : {
                               2077                 :     static struct option long_options[] = {
                               2078                 :         {"help", no_argument, NULL, 'h'},
                               2079                 :         {"version", no_argument, NULL, 'V'},
                               2080                 :         {"dbname", required_argument, NULL, 1},
                               2081                 :         {"debug", no_argument, NULL, 2},
                               2082                 :         {"inputdir", required_argument, NULL, 3},
                               2083                 :         {"max-connections", required_argument, NULL, 5},
 4377 peter_e                  2084                 :         {"encoding", required_argument, NULL, 6},
 6108 tgl                      2085                 :         {"outputdir", required_argument, NULL, 7},
                               2086                 :         {"schedule", required_argument, NULL, 8},
 2908 peter_e                  2087                 :         {"temp-instance", required_argument, NULL, 9},
 6108 tgl                      2088                 :         {"no-locale", no_argument, NULL, 10},
                               2089                 :         {"host", required_argument, NULL, 13},
                               2090                 :         {"port", required_argument, NULL, 14},
                               2091                 :         {"user", required_argument, NULL, 15},
 2908 peter_e                  2092                 :         {"bindir", required_argument, NULL, 16},
 5303                          2093                 :         {"dlpath", required_argument, NULL, 17},
 5780 magnus                   2094                 :         {"create-role", required_argument, NULL, 18},
 5691 andrew                   2095                 :         {"temp-config", required_argument, NULL, 19},
 4859 simon                    2096                 :         {"use-existing", no_argument, NULL, 20},
 4459 rhaas                    2097                 :         {"launcher", required_argument, NULL, 21},
 4419 tgl                      2098                 :         {"load-extension", required_argument, NULL, 22},
 3035 noah                     2099                 :         {"config-auth", required_argument, NULL, 24},
 2010 tgl                      2100                 :         {"max-concurrent-tests", required_argument, NULL, 25},
                               2101                 :         {"expecteddir", required_argument, NULL, 26},
 6108                          2102                 :         {NULL, 0, NULL, 0}
                               2103                 :     };
                               2104                 : 
 1105 peter                    2105                 :     bool        use_unix_sockets;
 3782 bruce                    2106                 :     _stringlist *sl;
                               2107                 :     int         c;
                               2108                 :     int         i;
                               2109                 :     int         option_index;
                               2110                 :     char        buf[MAXPGPATH * 4];
                               2111                 :     char        buf2[MAXPGPATH * 4];
                               2112                 : 
 1469 peter                    2113 GBC         303 :     pg_logging_init(argv[0]);
 6108 tgl                      2114             303 :     progname = get_progname(argv[0]);
 5232 peter_e                  2115             303 :     set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_regress"));
 6108 tgl                      2116 EUB             : 
 1469 peter                    2117 GIC         303 :     get_restricted_token();
                               2118                 : 
 4115 peter_e                  2119 CBC         303 :     atexit(stop_postmaster);
                               2120                 : 
                               2121                 : #if defined(WIN32)
                               2122                 : 
                               2123                 :     /*
                               2124                 :      * We don't use Unix-domain sockets on Windows by default (see comment at
                               2125                 :      * remove_temp() for a reason).  Override at your own risk.
                               2126                 :      */
                               2127                 :     use_unix_sockets = getenv("PG_TEST_USE_UNIX_SOCKETS") ? true : false;
                               2128                 : #else
 1105 peter                    2129 GIC         303 :     use_unix_sockets = true;
                               2130                 : #endif
                               2131                 : 
                               2132             303 :     if (!use_unix_sockets)
 1105 peter                    2133 UIC           0 :         hostname = "localhost";
                               2134                 : 
                               2135                 :     /*
                               2136                 :      * We call the initialization function here because that way we can set
                               2137                 :      * default parameters and let them be overwritten by the commandline.
                               2138                 :      */
 3439 rhaas                    2139 GIC         303 :     ifunc(argc, argv);
                               2140                 : 
 3722 peter_e                  2141             303 :     if (getenv("PG_REGRESS_DIFF_OPTS"))
                               2142             303 :         pretty_diff_opts = getenv("PG_REGRESS_DIFF_OPTS");
                               2143                 : 
 6108 tgl                      2144             920 :     while ((c = getopt_long(argc, argv, "hV", long_options, &option_index)) != -1)
                               2145                 :     {
                               2146             617 :         switch (c)
                               2147                 :         {
 6108 tgl                      2148 UIC           0 :             case 'h':
                               2149               0 :                 help();
 4115 peter_e                  2150               0 :                 exit(0);
 6108 tgl                      2151               0 :             case 'V':
 5527                          2152               0 :                 puts("pg_regress (PostgreSQL) " PG_VERSION);
 4115 peter_e                  2153               0 :                 exit(0);
 6108 tgl                      2154 GIC          80 :             case 1:
                               2155                 : 
                               2156                 :                 /*
 5624 bruce                    2157 ECB             :                  * If a default database was specified, we need to remove it
                               2158                 :                  * before we add the specified one.
 5780 magnus                   2159                 :                  */
 5780 magnus                   2160 GIC          80 :                 free_stringlist(&dblist);
 2439 peter_e                  2161 CBC          80 :                 split_to_stringlist(optarg, ",", &dblist);
 6108 tgl                      2162 GIC          80 :                 break;
 6108 tgl                      2163 LBC           0 :             case 2:
 6108 tgl                      2164 UIC           0 :                 debug = true;
                               2165               0 :                 break;
 6108 tgl                      2166 GIC          83 :             case 3:
 2413                          2167              83 :                 inputdir = pg_strdup(optarg);
 6108                          2168              83 :                 break;
 6108 tgl                      2169 UIC           0 :             case 5:
                               2170               0 :                 max_connections = atoi(optarg);
                               2171               0 :                 break;
 6108 tgl                      2172 GIC           2 :             case 6:
 2413 tgl                      2173 CBC           2 :                 encoding = pg_strdup(optarg);
 6108 tgl                      2174 GIC           2 :                 break;
                               2175               9 :             case 7:
 2413 tgl                      2176 CBC           9 :                 outputdir = pg_strdup(optarg);
 6108 tgl                      2177 GBC           9 :                 break;
 6108 tgl                      2178 GIC           5 :             case 8:
                               2179               5 :                 add_stringlist_item(&schedulelist, optarg);
                               2180               5 :                 break;
                               2181              82 :             case 9:
 2908 peter_e                  2182              82 :                 temp_instance = make_absolute_path(optarg);
 6108 tgl                      2183 CBC          82 :                 break;
 6108 tgl                      2184 GIC           3 :             case 10:
 6108 tgl                      2185 CBC           3 :                 nolocale = true;
                               2186               3 :                 break;
 6108 tgl                      2187 GIC           2 :             case 13:
 2413 tgl                      2188 CBC           2 :                 hostname = pg_strdup(optarg);
 6108 tgl                      2189 GIC           2 :                 break;
 6108 tgl                      2190 CBC           2 :             case 14:
 6108 tgl                      2191 GIC           2 :                 port = atoi(optarg);
 5245 peter_e                  2192 GBC           2 :                 port_specified_by_user = true;
 6108 tgl                      2193               2 :                 break;
                               2194               3 :             case 15:
 2413                          2195               3 :                 user = pg_strdup(optarg);
 6108                          2196               3 :                 break;
 6106                          2197              84 :             case 16:
 2908 peter_e                  2198 ECB             :                 /* "--bindir=" means to use PATH */
 6106 tgl                      2199 GIC          84 :                 if (strlen(optarg))
 2413 tgl                      2200 UIC           0 :                     bindir = pg_strdup(optarg);
                               2201                 :                 else
 2908 peter_e                  2202 GIC          84 :                     bindir = NULL;
 6106 tgl                      2203              84 :                 break;
 5924 alvherre                 2204 CBC           4 :             case 17:
 2413 tgl                      2205               4 :                 dlpath = pg_strdup(optarg);
 5924 alvherre                 2206               4 :                 break;
 5780 magnus                   2207 GBC          20 :             case 18:
 2439 peter_e                  2208              20 :                 split_to_stringlist(optarg, ",", &extraroles);
 5780 magnus                   2209              20 :                 break;
 5691 andrew                   2210 CBC          10 :             case 19:
 2597                          2211              10 :                 add_stringlist_item(&temp_configs, optarg);
 5691                          2212              10 :                 break;
 4859 simon                    2213 UBC           0 :             case 20:
                               2214               0 :                 use_existing = true;
                               2215               0 :                 break;
 4459 rhaas                    2216 LBC           0 :             case 21:
 2413 tgl                      2217               0 :                 launcher = pg_strdup(optarg);
 4459 rhaas                    2218               0 :                 break;
 4419 tgl                      2219 CBC           5 :             case 22:
                               2220               5 :                 add_stringlist_item(&loadextension, optarg);
                               2221               5 :                 break;
 3035 noah                     2222             219 :             case 24:
 2413 tgl                      2223             219 :                 config_auth_datadir = pg_strdup(optarg);
 3035 noah                     2224             219 :                 break;
 2010 tgl                      2225               3 :             case 25:
                               2226               3 :                 max_concurrent_tests = atoi(optarg);
                               2227               3 :                 break;
  232 andres                   2228 GNC           1 :             case 26:
                               2229               1 :                 expecteddir = pg_strdup(optarg);
                               2230               1 :                 break;
 6108 tgl                      2231 LBC           0 :             default:
 6108 tgl                      2232 ECB             :                 /* getopt_long already emitted a complaint */
    9 dgustafsson              2233 UNC           0 :                 pg_log_error_hint("Try \"%s --help\" for more information.",
                               2234                 :                                   progname);
 4115 peter_e                  2235 LBC           0 :                 exit(2);
 6108 tgl                      2236 ECB             :         }
                               2237                 :     }
                               2238                 : 
                               2239                 :     /*
                               2240                 :      * if we still have arguments, they are extra tests to run
                               2241                 :      */
 6108 tgl                      2242 CBC         597 :     while (argc - optind >= 1)
 6108 tgl                      2243 ECB             :     {
 6108 tgl                      2244 CBC         294 :         add_stringlist_item(&extra_tests, argv[optind]);
 6108 tgl                      2245 GIC         294 :         optind++;
 6108 tgl                      2246 ECB             :     }
 6108 tgl                      2247 EUB             : 
                               2248                 :     /*
  130 tgl                      2249 ECB             :      * We must have a database to run the tests in; either a default name, or
                               2250                 :      * one supplied by the --dbname switch.
                               2251                 :      */
  130 tgl                      2252 CBC         303 :     if (!(dblist && dblist->str && dblist->str[0]))
  130 tgl                      2253 ECB             :     {
    9 dgustafsson              2254 UNC           0 :         bail("no database name was specified");
  130 tgl                      2255 ECB             :     }
                               2256                 : 
 3035 noah                     2257 CBC         303 :     if (config_auth_datadir)
 3035 noah                     2258 EUB             :     {
                               2259                 : #ifdef ENABLE_SSPI
 1105 peter                    2260                 :         if (!use_unix_sockets)
                               2261                 :             config_sspi_auth(config_auth_datadir, user);
 3035 noah                     2262                 : #endif
 3035 noah                     2263 GBC         219 :         exit(0);
 3035 noah                     2264 ECB             :     }
                               2265                 : 
 2908 peter_e                  2266 CBC          84 :     if (temp_instance && !port_specified_by_user)
 5050 bruce                    2267 ECB             : 
 5245 peter_e                  2268                 :         /*
 5050 bruce                    2269                 :          * To reduce chances of interference with parallel installations, use
                               2270                 :          * a port number starting in the private range (49152-65535)
                               2271                 :          * calculated from the version number.  This aids non-Unix socket mode
 3221 noah                     2272                 :          * systems; elsewhere, the use of a private socket directory already
                               2273                 :          * prevents interference.
 5245 peter_e                  2274                 :          */
 5245 peter_e                  2275 CBC          82 :         port = 0xC000 | (PG_VERSION_NUM & 0x3FFF);
 6108 tgl                      2276 EUB             : 
 1506 peter                    2277 GIC          84 :     inputdir = make_absolute_path(inputdir);
 1506 peter                    2278 GBC          84 :     outputdir = make_absolute_path(outputdir);
  232 andres                   2279 GNC          84 :     expecteddir = make_absolute_path(expecteddir);
 1506 peter                    2280 GIC          84 :     dlpath = make_absolute_path(dlpath);
 1506 peter                    2281 EUB             : 
                               2282                 :     /*
                               2283                 :      * Initialization
                               2284                 :      */
 6108 tgl                      2285 GIC          84 :     open_result_files();
                               2286                 : 
                               2287              84 :     initialize_environment();
 6108 tgl                      2288 ECB             : 
                               2289                 : #if defined(HAVE_GETRLIMIT)
 5938 andrew                   2290 CBC          84 :     unlimit_core_size();
 5938 andrew                   2291 ECB             : #endif
                               2292                 : 
 2908 peter_e                  2293 GIC          84 :     if (temp_instance)
                               2294                 :     {
                               2295                 :         FILE       *pg_conf;
                               2296                 :         const char *env_wait;
                               2297                 :         int         wait_seconds;
 5099 tgl                      2298 ECB             : 
                               2299                 :         /*
 2908 peter_e                  2300 EUB             :          * Prepare the temp instance
                               2301                 :          */
                               2302                 : 
 2908 peter_e                  2303 CBC          82 :         if (directory_exists(temp_instance))
                               2304                 :         {
 2908 peter_e                  2305 UIC           0 :             if (!rmtree(temp_instance, true))
                               2306                 :             {
    9 dgustafsson              2307 UNC           0 :                 bail("could not remove temp instance \"%s\"", temp_instance);
                               2308                 :             }
 6108 tgl                      2309 ECB             :         }
                               2310                 : 
                               2311                 :         /* make the temp instance top directory */
 2908 peter_e                  2312 GIC          82 :         make_directory(temp_instance);
                               2313                 : 
                               2314                 :         /* and a directory for log files */
 2819 andrew                   2315              82 :         snprintf(buf, sizeof(buf), "%s/log", outputdir);
 6108 tgl                      2316 CBC          82 :         if (!directory_exists(buf))
 6108 tgl                      2317 GIC          82 :             make_directory(buf);
 6108 tgl                      2318 ECB             : 
                               2319                 :         /* initdb */
 6108 tgl                      2320 CBC         328 :         snprintf(buf, sizeof(buf),
                               2321                 :                  "\"%s%sinitdb\" -D \"%s/data\" --no-clean --no-sync%s%s > \"%s/log/initdb.log\" 2>&1",
 2908 peter_e                  2322 GIC          82 :                  bindir ? bindir : "",
                               2323              82 :                  bindir ? "/" : "",
                               2324                 :                  temp_instance,
 6107 tgl                      2325 CBC          82 :                  debug ? " --debug" : "",
 6107 tgl                      2326 GIC          82 :                  nolocale ? " --no-locale" : "",
 2819 andrew                   2327 ECB             :                  outputdir);
  223 tgl                      2328 GNC          82 :         fflush(NULL);
 6108 tgl                      2329 GIC          82 :         if (system(buf))
                               2330                 :         {
    9 dgustafsson              2331 UNC           0 :             bail("initdb failed\n"
                               2332                 :                  "# Examine \"%s/log/initdb.log\" for the reason.\n"
                               2333                 :                  "# Command was: %s",
                               2334                 :                  outputdir, buf);
                               2335                 :         }
 6108 tgl                      2336 ECB             : 
                               2337                 :         /*
                               2338                 :          * Adjust the default postgresql.conf for regression testing. The user
                               2339                 :          * can specify a file to be appended; in any case we expand logging
                               2340                 :          * and set max_prepared_transactions to enable testing of prepared
                               2341                 :          * xacts.  (Note: to reduce the probability of unexpected shmmax
                               2342                 :          * failures, don't set max_prepared_transactions any higher than
                               2343                 :          * actually needed by the prepared_xacts regression test.)
                               2344                 :          */
 2908 peter_e                  2345 GIC          82 :         snprintf(buf, sizeof(buf), "%s/data/postgresql.conf", temp_instance);
 5099 tgl                      2346 CBC          82 :         pg_conf = fopen(buf, "a");
 5099 tgl                      2347 GIC          82 :         if (pg_conf == NULL)
 5099 tgl                      2348 EUB             :         {
    9 dgustafsson              2349 UNC           0 :             bail("could not open \"%s\" for adding extra config: %s",
                               2350                 :                  buf, strerror(errno));
                               2351                 :         }
 5099 tgl                      2352 GIC          82 :         fputs("\n# Configuration added by pg_regress\n\n", pg_conf);
 3003 noah                     2353              82 :         fputs("log_autovacuum_min_duration = 0\n", pg_conf);
                               2354              82 :         fputs("log_checkpoints = on\n", pg_conf);
 1120 peter                    2355 CBC          82 :         fputs("log_line_prefix = '%m %b[%p] %q%a '\n", pg_conf);
 3003 noah                     2356 GIC          82 :         fputs("log_lock_waits = on\n", pg_conf);
                               2357              82 :         fputs("log_temp_files = 128kB\n", pg_conf);
 5099 tgl                      2358 CBC          82 :         fputs("max_prepared_transactions = 2\n", pg_conf);
 5099 tgl                      2359 ECB             : 
 2597 andrew                   2360 CBC          92 :         for (sl = temp_configs; sl != NULL; sl = sl->next)
                               2361                 :         {
 2597 andrew                   2362 GIC          10 :             char       *temp_config = sl->str;
 5624 bruce                    2363 ECB             :             FILE       *extra_conf;
                               2364                 :             char        line_buf[1024];
 5691 andrew                   2365                 : 
 5624 bruce                    2366 CBC          10 :             extra_conf = fopen(temp_config, "r");
 5691 andrew                   2367 GIC          10 :             if (extra_conf == NULL)
 5691 andrew                   2368 ECB             :             {
    9 dgustafsson              2369 UNC           0 :                 bail("could not open \"%s\" to read extra config: %s",
                               2370                 :                      temp_config, strerror(errno));
 5691 andrew                   2371 ECB             :             }
 5624 bruce                    2372 CBC          32 :             while (fgets(line_buf, sizeof(line_buf), extra_conf) != NULL)
 5691 andrew                   2373 GIC          22 :                 fputs(line_buf, pg_conf);
 5691 andrew                   2374 GBC          10 :             fclose(extra_conf);
                               2375                 :         }
                               2376                 : 
 5099 tgl                      2377 GIC          82 :         fclose(pg_conf);
                               2378                 : 
                               2379                 : #ifdef ENABLE_SSPI
                               2380                 :         if (!use_unix_sockets)
                               2381                 :         {
                               2382                 :             /*
                               2383                 :              * Since we successfully used the same buffer for the much-longer
                               2384                 :              * "initdb" command, this can't truncate.
                               2385                 :              */
                               2386                 :             snprintf(buf, sizeof(buf), "%s/data", temp_instance);
                               2387                 :             config_sspi_auth(buf, NULL);
 1105 peter                    2388 ECB             :         }
                               2389                 : #endif
 3035 noah                     2390 EUB             : 
                               2391                 :         /*
                               2392                 :          * Check if there is a postmaster running already.
 5245 peter_e                  2393 ECB             :          */
 5245 peter_e                  2394 CBC         164 :         snprintf(buf2, sizeof(buf2),
 2908 peter_e                  2395 ECB             :                  "\"%s%spsql\" -X postgres <%s 2>%s",
 2908 peter_e                  2396 CBC          82 :                  bindir ? bindir : "",
                               2397              82 :                  bindir ? "/" : "",
 2908 peter_e                  2398 ECB             :                  DEVNULL, DEVNULL);
 5245                          2399                 : 
 5245 peter_e                  2400 GIC          82 :         for (i = 0; i < 16; i++)
 5245 peter_e                  2401 ECB             :         {
  223 tgl                      2402 GNC          82 :             fflush(NULL);
 5245 peter_e                  2403 GIC          82 :             if (system(buf2) == 0)
 5245 peter_e                  2404 ECB             :             {
                               2405                 :                 char        s[16];
                               2406                 : 
 5245 peter_e                  2407 UIC           0 :                 if (port_specified_by_user || i == 15)
 5245 peter_e                  2408 ECB             :                 {
    9 dgustafsson              2409 UNC           0 :                     note("port %d apparently in use", port);
 5245 peter_e                  2410 UIC           0 :                     if (!port_specified_by_user)
    9 dgustafsson              2411 UNC           0 :                         note("could not determine an available port");
                               2412               0 :                     bail("Specify an unused port using the --port option or shut down any conflicting PostgreSQL servers.");
 5245 peter_e                  2413 ECB             :                 }
                               2414                 : 
    9 dgustafsson              2415 UNC           0 :                 note("port %d apparently in use, trying %d", port, port + 1);
 5245 peter_e                  2416 UIC           0 :                 port++;
                               2417               0 :                 sprintf(s, "%d", port);
  830 tgl                      2418 LBC           0 :                 setenv("PGPORT", s, 1);
                               2419                 :             }
                               2420                 :             else
 5245 peter_e                  2421 GIC          82 :                 break;
                               2422                 :         }
                               2423                 : 
                               2424                 :         /*
                               2425                 :          * Start the temp postmaster
                               2426                 :          */
 6108 tgl                      2427             410 :         snprintf(buf, sizeof(buf),
                               2428                 :                  "\"%s%spostgres\" -D \"%s/data\" -F%s "
                               2429                 :                  "-c \"listen_addresses=%s\" -k \"%s\" "
                               2430                 :                  "> \"%s/log/postmaster.log\" 2>&1",
 2908 peter_e                  2431              82 :                  bindir ? bindir : "",
                               2432              82 :                  bindir ? "/" : "",
                               2433              82 :                  temp_instance, debug ? " -d 5" : "",
 3221 noah                     2434 CBC         164 :                  hostname ? hostname : "", sockdir ? sockdir : "",
                               2435                 :                  outputdir);
 6108 tgl                      2436              82 :         postmaster_pid = spawn_process(buf);
                               2437              82 :         if (postmaster_pid == INVALID_PID)
    9 dgustafsson              2438 UNC           0 :             bail("could not spawn postmaster: %s", strerror(errno));
 6108 tgl                      2439 ECB             : 
                               2440                 :         /*
                               2441                 :          * Wait till postmaster is able to accept connections; normally this
                               2442                 :          * is only a second or so, but Cygwin is reportedly *much* slower, and
 2545 tgl                      2443 EUB             :          * test builds using Valgrind or similar tools might be too.  Hence,
                               2444                 :          * allow the default timeout of 60 seconds to be overridden from the
                               2445                 :          * PGCTLTIMEOUT environment variable.
 6108                          2446                 :          */
 2545 tgl                      2447 GBC          82 :         env_wait = getenv("PGCTLTIMEOUT");
                               2448              82 :         if (env_wait != NULL)
                               2449                 :         {
 2545 tgl                      2450 UIC           0 :             wait_seconds = atoi(env_wait);
 2545 tgl                      2451 UBC           0 :             if (wait_seconds <= 0)
                               2452               0 :                 wait_seconds = 60;
 2545 tgl                      2453 EUB             :         }
                               2454                 :         else
 2545 tgl                      2455 GIC          82 :             wait_seconds = 60;
                               2456                 : 
 2545 tgl                      2457 CBC         164 :         for (i = 0; i < wait_seconds; i++)
                               2458                 :         {
                               2459                 :             /* Done if psql succeeds */
  223 tgl                      2460 GNC         164 :             fflush(NULL);
 5245 peter_e                  2461 GIC         164 :             if (system(buf2) == 0)
 6108 tgl                      2462              82 :                 break;
                               2463                 : 
 6108 tgl                      2464 ECB             :             /*
                               2465                 :              * Fail immediately if postmaster has exited
                               2466                 :              */
                               2467                 : #ifndef WIN32
 1560 noah                     2468 CBC          82 :             if (waitpid(postmaster_pid, NULL, WNOHANG) == postmaster_pid)
 6041 tgl                      2469 ECB             : #else
                               2470                 :             if (WaitForSingleObject(postmaster_pid, 0) == WAIT_OBJECT_0)
                               2471                 : #endif
                               2472                 :             {
    9 dgustafsson              2473 UNC           0 :                 bail("postmaster failed, examine \"%s/log/postmaster.log\" for the reason",
                               2474                 :                      outputdir);
 6108 tgl                      2475 EUB             :             }
                               2476                 : 
 6108 tgl                      2477 GIC          82 :             pg_usleep(1000000L);
                               2478                 :         }
 2545                          2479              82 :         if (i >= wait_seconds)
                               2480                 :         {
    9 dgustafsson              2481 UNC           0 :             diag("postmaster did not respond within %d seconds, examine \"%s/log/postmaster.log\" for the reason",
                               2482                 :                  wait_seconds, outputdir);
                               2483                 : 
 6083 tgl                      2484 ECB             :             /*
 6031 bruce                    2485                 :              * If we get here, the postmaster is probably wedged somewhere in
                               2486                 :              * startup.  Try to kill it ungracefully rather than leaving a
 6031 bruce                    2487 EUB             :              * stuck postmaster that might interfere with subsequent test
 6083 tgl                      2488                 :              * attempts.
                               2489                 :              */
                               2490                 : #ifndef WIN32
    9 dgustafsson              2491 UNC           0 :             if (kill(postmaster_pid, SIGKILL) != 0 && errno != ESRCH)
                               2492               0 :                 bail("could not kill failed postmaster: %s", strerror(errno));
                               2493                 : #else
                               2494                 :             if (TerminateProcess(postmaster_pid, 255) == 0)
                               2495                 :                 bail("could not kill failed postmaster: error code %lu",
                               2496                 :                      GetLastError());
 6083 tgl                      2497 ECB             : #endif
    9 dgustafsson              2498 UNC           0 :             bail("postmaster failed");
                               2499                 :         }
                               2500                 : 
 6108 tgl                      2501 GIC          82 :         postmaster_running = true;
 6108 tgl                      2502 ECB             : 
                               2503                 : #ifdef _WIN64
                               2504                 : /* need a series of two casts to convert HANDLE without compiler warning */
                               2505                 : #define ULONGPID(x) (unsigned long) (unsigned long long) (x)
                               2506                 : #else
 4373 andrew                   2507 EUB             : #define ULONGPID(x) (unsigned long) (x)
                               2508                 : #endif
    9 dgustafsson              2509 GNC          82 :         note("using temp instance on port %d with PID %lu",
                               2510                 :              port, ULONGPID(postmaster_pid));
 6108 tgl                      2511 ECB             :     }
                               2512                 :     else
                               2513                 :     {
                               2514                 :         /*
 6108 tgl                      2515 EUB             :          * Using an existing installation, so may need to get rid of
                               2516                 :          * pre-existing database(s) and role(s)
                               2517                 :          */
 4859 simon                    2518 GIC           2 :         if (!use_existing)
                               2519                 :         {
                               2520               4 :             for (sl = dblist; sl; sl = sl->next)
                               2521               2 :                 drop_database_if_exists(sl->str);
                               2522               2 :             for (sl = extraroles; sl; sl = sl->next)
 4859 simon                    2523 UIC           0 :                 drop_role_if_exists(sl->str);
                               2524                 :         }
 6108 tgl                      2525 EUB             :     }
                               2526                 : 
                               2527                 :     /*
                               2528                 :      * Create the test database(s) and role(s)
                               2529                 :      */
 4859 simon                    2530 GIC          84 :     if (!use_existing)
                               2531                 :     {
 4859 simon                    2532 GBC         169 :         for (sl = dblist; sl; sl = sl->next)
 4859 simon                    2533 GIC          85 :             create_database(sl->str);
                               2534              86 :         for (sl = extraroles; sl; sl = sl->next)
 4859 simon                    2535 CBC           2 :             create_role(sl->str, dblist);
                               2536                 :     }
                               2537                 : 
                               2538                 :     /*
                               2539                 :      * Ready to run the tests
                               2540                 :      */
 6108 tgl                      2541              89 :     for (sl = schedulelist; sl != NULL; sl = sl->next)
                               2542                 :     {
  818 tgl                      2543 GIC           5 :         run_schedule(sl->str, startfunc, postfunc);
                               2544                 :     }
                               2545                 : 
 6108                          2546             378 :     for (sl = extra_tests; sl != NULL; sl = sl->next)
                               2547                 :     {
  818                          2548             294 :         run_single_test(sl->str, startfunc, postfunc);
                               2549                 :     }
 6108 tgl                      2550 ECB             : 
                               2551                 :     /*
                               2552                 :      * Shut down temp installation's postmaster
                               2553                 :      */
 2908 peter_e                  2554 CBC          84 :     if (temp_instance)
 6108 tgl                      2555 EUB             :     {
 6108 tgl                      2556 GIC          82 :         stop_postmaster();
                               2557                 :     }
                               2558                 : 
                               2559                 :     /*
                               2560                 :      * If there were no errors, remove the temp instance immediately to
 2878 bruce                    2561 ECB             :      * conserve disk space.  (If there were errors, we leave the instance in
                               2562                 :      * place for possible manual investigation.)
 3002 tgl                      2563                 :      */
   90 tgl                      2564 GNC          84 :     if (temp_instance && fail_count == 0)
 3002 tgl                      2565 ECB             :     {
 2908 peter_e                  2566 GIC          82 :         if (!rmtree(temp_instance, true))
    9 dgustafsson              2567 UNC           0 :             diag("could not remove temp instance \"%s\"",
                               2568                 :                  temp_instance);
                               2569                 :     }
                               2570                 : 
                               2571                 :     /*
                               2572                 :      * Emit a TAP compliant Plan
                               2573                 :      */
    9 dgustafsson              2574 GNC          84 :     plan(fail_count + success_count);
                               2575                 : 
 6108 tgl                      2576 ECB             :     /*
                               2577                 :      * Emit nice-looking summary message
                               2578                 :      */
   90 tgl                      2579 GNC          84 :     if (fail_count == 0)
    9 dgustafsson              2580              84 :         note("All %d tests passed.", success_count);
                               2581                 :     else
    9 dgustafsson              2582 UNC           0 :         diag("%d of %d tests failed.", fail_count, success_count + fail_count);
                               2583                 : 
 6108 tgl                      2584 GIC          84 :     if (file_size(difffilename) > 0)
 6108 tgl                      2585 ECB             :     {
    9 dgustafsson              2586 UNC           0 :         diag("The differences that caused some tests to fail can be viewed in the file \"%s\".",
                               2587                 :              difffilename);
                               2588               0 :         diag("A copy of the test summary that you see above is saved in the file \"%s\".",
                               2589                 :              logfilename);
 6108 tgl                      2590 ECB             :     }
                               2591                 :     else
 6108 tgl                      2592 EUB             :     {
 6108 tgl                      2593 GIC          84 :         unlink(difffilename);
 6108 tgl                      2594 GBC          84 :         unlink(logfilename);
                               2595                 :     }
                               2596                 : 
    9 dgustafsson              2597 GNC          84 :     fclose(logfile);
                               2598              84 :     logfile = NULL;
                               2599                 : 
 6108 tgl                      2600 GIC          84 :     if (fail_count != 0)
 4115 peter_e                  2601 UIC           0 :         exit(1);
 6108 tgl                      2602 ECB             : 
 6108 tgl                      2603 CBC          84 :     return 0;
                               2604                 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a