LCOV - code coverage report
Current view: top level - src/bin/pg_upgrade - option.c (source / functions) Coverage Total Hit
Test: Code coverage Lines: 0.0 % 240 0
Test Date: 2026-01-26 10:56:24 Functions: 0.0 % 5 0
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*
       2              :  *      option.c
       3              :  *
       4              :  *      options functions
       5              :  *
       6              :  *      Copyright (c) 2010-2026, PostgreSQL Global Development Group
       7              :  *      src/bin/pg_upgrade/option.c
       8              :  */
       9              : 
      10              : #include "postgres_fe.h"
      11              : 
      12              : #ifdef WIN32
      13              : #include <io.h>
      14              : #endif
      15              : 
      16              : #include "common/string.h"
      17              : #include "fe_utils/option_utils.h"
      18              : #include "getopt_long.h"
      19              : #include "pg_upgrade.h"
      20              : #include "utils/pidfile.h"
      21              : 
      22              : static void usage(void);
      23              : static void check_required_directory(char **dirpath,
      24              :                                                                          const char *envVarName, bool useCwd,
      25              :                                                                          const char *cmdLineOption, const char *description,
      26              :                                                                          bool missingOk);
      27              : #define FIX_DEFAULT_READ_ONLY "-c default_transaction_read_only=false"
      28              : 
      29              : 
      30              : UserOpts        user_opts;
      31              : 
      32              : 
      33              : /*
      34              :  * parseCommandLine()
      35              :  *
      36              :  *      Parses the command line (argc, argv[]) and loads structures
      37              :  */
      38              : void
      39            0 : parseCommandLine(int argc, char *argv[])
      40              : {
      41              :         static struct option long_options[] = {
      42              :                 {"old-datadir", required_argument, NULL, 'd'},
      43              :                 {"new-datadir", required_argument, NULL, 'D'},
      44              :                 {"old-bindir", required_argument, NULL, 'b'},
      45              :                 {"new-bindir", required_argument, NULL, 'B'},
      46              :                 {"no-sync", no_argument, NULL, 'N'},
      47              :                 {"old-options", required_argument, NULL, 'o'},
      48              :                 {"new-options", required_argument, NULL, 'O'},
      49              :                 {"old-port", required_argument, NULL, 'p'},
      50              :                 {"new-port", required_argument, NULL, 'P'},
      51              : 
      52              :                 {"username", required_argument, NULL, 'U'},
      53              :                 {"check", no_argument, NULL, 'c'},
      54              :                 {"link", no_argument, NULL, 'k'},
      55              :                 {"retain", no_argument, NULL, 'r'},
      56              :                 {"jobs", required_argument, NULL, 'j'},
      57              :                 {"socketdir", required_argument, NULL, 's'},
      58              :                 {"verbose", no_argument, NULL, 'v'},
      59              :                 {"clone", no_argument, NULL, 1},
      60              :                 {"copy", no_argument, NULL, 2},
      61              :                 {"copy-file-range", no_argument, NULL, 3},
      62              :                 {"sync-method", required_argument, NULL, 4},
      63              :                 {"no-statistics", no_argument, NULL, 5},
      64              :                 {"set-char-signedness", required_argument, NULL, 6},
      65              :                 {"swap", no_argument, NULL, 7},
      66              : 
      67              :                 {NULL, 0, NULL, 0}
      68              :         };
      69            0 :         int                     option;                 /* Command line option */
      70            0 :         int                     optindex = 0;   /* used by getopt_long */
      71            0 :         int                     os_user_effective_id;
      72            0 :         DataDirSyncMethod unused;
      73              : 
      74            0 :         user_opts.do_sync = true;
      75            0 :         user_opts.transfer_mode = TRANSFER_MODE_COPY;
      76            0 :         user_opts.do_statistics = true;
      77            0 :         user_opts.char_signedness = -1;
      78              : 
      79            0 :         os_info.progname = get_progname(argv[0]);
      80              : 
      81              :         /* Process libpq env. variables; load values here for usage() output */
      82            0 :         old_cluster.port = getenv("PGPORTOLD") ? atoi(getenv("PGPORTOLD")) : DEF_PGUPORT;
      83            0 :         new_cluster.port = getenv("PGPORTNEW") ? atoi(getenv("PGPORTNEW")) : DEF_PGUPORT;
      84              : 
      85            0 :         os_user_effective_id = get_user_info(&os_info.user);
      86              :         /* we override just the database user name;  we got the OS id above */
      87            0 :         if (getenv("PGUSER"))
      88              :         {
      89            0 :                 pg_free(os_info.user);
      90              :                 /* must save value, getenv()'s pointer is not stable */
      91            0 :                 os_info.user = pg_strdup(getenv("PGUSER"));
      92            0 :         }
      93              : 
      94            0 :         if (argc > 1)
      95              :         {
      96            0 :                 if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
      97              :                 {
      98            0 :                         usage();
      99            0 :                         exit(0);
     100              :                 }
     101            0 :                 if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
     102              :                 {
     103            0 :                         puts("pg_upgrade (PostgreSQL) " PG_VERSION);
     104            0 :                         exit(0);
     105              :                 }
     106            0 :         }
     107              : 
     108              :         /* Allow help and version to be run as root, so do the test here. */
     109            0 :         if (os_user_effective_id == 0)
     110            0 :                 pg_fatal("%s: cannot be run as root", os_info.progname);
     111              : 
     112            0 :         while ((option = getopt_long(argc, argv, "b:B:cd:D:j:kNo:O:p:P:rs:U:v",
     113            0 :                                                                  long_options, &optindex)) != -1)
     114              :         {
     115            0 :                 switch (option)
     116              :                 {
     117              :                         case 'b':
     118            0 :                                 old_cluster.bindir = pg_strdup(optarg);
     119            0 :                                 break;
     120              : 
     121              :                         case 'B':
     122            0 :                                 new_cluster.bindir = pg_strdup(optarg);
     123            0 :                                 break;
     124              : 
     125              :                         case 'c':
     126            0 :                                 user_opts.check = true;
     127            0 :                                 break;
     128              : 
     129              :                         case 'd':
     130            0 :                                 old_cluster.pgdata = pg_strdup(optarg);
     131            0 :                                 break;
     132              : 
     133              :                         case 'D':
     134            0 :                                 new_cluster.pgdata = pg_strdup(optarg);
     135            0 :                                 break;
     136              : 
     137              :                         case 'j':
     138            0 :                                 user_opts.jobs = atoi(optarg);
     139            0 :                                 break;
     140              : 
     141              :                         case 'k':
     142            0 :                                 user_opts.transfer_mode = TRANSFER_MODE_LINK;
     143            0 :                                 break;
     144              : 
     145              :                         case 'N':
     146            0 :                                 user_opts.do_sync = false;
     147            0 :                                 break;
     148              : 
     149              :                         case 'o':
     150              :                                 /* append option? */
     151            0 :                                 if (!old_cluster.pgopts)
     152            0 :                                         old_cluster.pgopts = pg_strdup(optarg);
     153              :                                 else
     154              :                                 {
     155            0 :                                         char       *old_pgopts = old_cluster.pgopts;
     156              : 
     157            0 :                                         old_cluster.pgopts = psprintf("%s %s", old_pgopts, optarg);
     158            0 :                                         free(old_pgopts);
     159            0 :                                 }
     160            0 :                                 break;
     161              : 
     162              :                         case 'O':
     163              :                                 /* append option? */
     164            0 :                                 if (!new_cluster.pgopts)
     165            0 :                                         new_cluster.pgopts = pg_strdup(optarg);
     166              :                                 else
     167              :                                 {
     168            0 :                                         char       *new_pgopts = new_cluster.pgopts;
     169              : 
     170            0 :                                         new_cluster.pgopts = psprintf("%s %s", new_pgopts, optarg);
     171            0 :                                         free(new_pgopts);
     172            0 :                                 }
     173            0 :                                 break;
     174              : 
     175              :                         case 'p':
     176            0 :                                 if ((old_cluster.port = atoi(optarg)) <= 0)
     177            0 :                                         pg_fatal("invalid old port number");
     178            0 :                                 break;
     179              : 
     180              :                         case 'P':
     181            0 :                                 if ((new_cluster.port = atoi(optarg)) <= 0)
     182            0 :                                         pg_fatal("invalid new port number");
     183            0 :                                 break;
     184              : 
     185              :                         case 'r':
     186            0 :                                 log_opts.retain = true;
     187            0 :                                 break;
     188              : 
     189              :                         case 's':
     190            0 :                                 user_opts.socketdir = pg_strdup(optarg);
     191            0 :                                 break;
     192              : 
     193              :                         case 'U':
     194            0 :                                 pg_free(os_info.user);
     195            0 :                                 os_info.user = pg_strdup(optarg);
     196            0 :                                 os_info.user_specified = true;
     197            0 :                                 break;
     198              : 
     199              :                         case 'v':
     200            0 :                                 log_opts.verbose = true;
     201            0 :                                 break;
     202              : 
     203              :                         case 1:
     204            0 :                                 user_opts.transfer_mode = TRANSFER_MODE_CLONE;
     205            0 :                                 break;
     206              : 
     207              :                         case 2:
     208            0 :                                 user_opts.transfer_mode = TRANSFER_MODE_COPY;
     209            0 :                                 break;
     210              : 
     211              :                         case 3:
     212            0 :                                 user_opts.transfer_mode = TRANSFER_MODE_COPY_FILE_RANGE;
     213            0 :                                 break;
     214              :                         case 4:
     215            0 :                                 if (!parse_sync_method(optarg, &unused))
     216            0 :                                         exit(1);
     217            0 :                                 user_opts.sync_method = pg_strdup(optarg);
     218            0 :                                 break;
     219              : 
     220              :                         case 5:
     221            0 :                                 user_opts.do_statistics = false;
     222            0 :                                 break;
     223              : 
     224              :                         case 6:
     225            0 :                                 if (pg_strcasecmp(optarg, "signed") == 0)
     226            0 :                                         user_opts.char_signedness = 1;
     227            0 :                                 else if (pg_strcasecmp(optarg, "unsigned") == 0)
     228            0 :                                         user_opts.char_signedness = 0;
     229              :                                 else
     230            0 :                                         pg_fatal("invalid argument for option %s", "--set-char-signedness");
     231            0 :                                 break;
     232              : 
     233              :                         case 7:
     234            0 :                                 user_opts.transfer_mode = TRANSFER_MODE_SWAP;
     235            0 :                                 break;
     236              : 
     237              :                         default:
     238            0 :                                 fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
     239            0 :                                                 os_info.progname);
     240            0 :                                 exit(1);
     241              :                 }
     242              :         }
     243              : 
     244            0 :         if (optind < argc)
     245            0 :                 pg_fatal("too many command-line arguments (first is \"%s\")", argv[optind]);
     246              : 
     247            0 :         if (!user_opts.sync_method)
     248            0 :                 user_opts.sync_method = pg_strdup("fsync");
     249              : 
     250            0 :         if (log_opts.verbose)
     251            0 :                 pg_log(PG_REPORT, "Running in verbose mode");
     252              : 
     253            0 :         log_opts.isatty = isatty(fileno(stdout));
     254              : 
     255              :         /* Turn off read-only mode;  add prefix to PGOPTIONS? */
     256            0 :         if (getenv("PGOPTIONS"))
     257              :         {
     258            0 :                 char       *pgoptions = psprintf("%s %s", FIX_DEFAULT_READ_ONLY,
     259            0 :                                                                                  getenv("PGOPTIONS"));
     260              : 
     261            0 :                 setenv("PGOPTIONS", pgoptions, 1);
     262            0 :                 pfree(pgoptions);
     263            0 :         }
     264              :         else
     265            0 :                 setenv("PGOPTIONS", FIX_DEFAULT_READ_ONLY, 1);
     266              : 
     267              :         /* Get values from env if not already set */
     268            0 :         check_required_directory(&old_cluster.bindir, "PGBINOLD", false,
     269            0 :                                                          "-b", _("old cluster binaries reside"), false);
     270            0 :         check_required_directory(&new_cluster.bindir, "PGBINNEW", false,
     271            0 :                                                          "-B", _("new cluster binaries reside"), true);
     272            0 :         check_required_directory(&old_cluster.pgdata, "PGDATAOLD", false,
     273            0 :                                                          "-d", _("old cluster data resides"), false);
     274            0 :         check_required_directory(&new_cluster.pgdata, "PGDATANEW", false,
     275            0 :                                                          "-D", _("new cluster data resides"), false);
     276            0 :         check_required_directory(&user_opts.socketdir, "PGSOCKETDIR", true,
     277            0 :                                                          "-s", _("sockets will be created"), false);
     278              : 
     279              : #ifdef WIN32
     280              : 
     281              :         /*
     282              :          * On Windows, initdb --sync-only will fail with a "Permission denied"
     283              :          * error on file pg_upgrade_utility.log if pg_upgrade is run inside the
     284              :          * new cluster directory, so we do a check here.
     285              :          */
     286              :         {
     287              :                 char            cwd[MAXPGPATH],
     288              :                                         new_cluster_pgdata[MAXPGPATH];
     289              : 
     290              :                 strlcpy(new_cluster_pgdata, new_cluster.pgdata, MAXPGPATH);
     291              :                 canonicalize_path(new_cluster_pgdata);
     292              : 
     293              :                 if (!getcwd(cwd, MAXPGPATH))
     294              :                         pg_fatal("could not determine current directory");
     295              :                 canonicalize_path(cwd);
     296              :                 if (path_is_prefix_of_path(new_cluster_pgdata, cwd))
     297              :                         pg_fatal("cannot run pg_upgrade from inside the new cluster data directory on Windows");
     298              :         }
     299              : #endif
     300            0 : }
     301              : 
     302              : 
     303              : static void
     304            0 : usage(void)
     305              : {
     306            0 :         printf(_("pg_upgrade upgrades a PostgreSQL cluster to a different major version.\n\n"));
     307            0 :         printf(_("Usage:\n"));
     308            0 :         printf(_("  pg_upgrade [OPTION]...\n\n"));
     309            0 :         printf(_("Options:\n"));
     310            0 :         printf(_("  -b, --old-bindir=BINDIR       old cluster executable directory\n"));
     311            0 :         printf(_("  -B, --new-bindir=BINDIR       new cluster executable directory (default\n"
     312              :                          "                                same directory as pg_upgrade)\n"));
     313            0 :         printf(_("  -c, --check                   check clusters only, don't change any data\n"));
     314            0 :         printf(_("  -d, --old-datadir=DATADIR     old cluster data directory\n"));
     315            0 :         printf(_("  -D, --new-datadir=DATADIR     new cluster data directory\n"));
     316            0 :         printf(_("  -j, --jobs=NUM                number of simultaneous processes or threads to use\n"));
     317            0 :         printf(_("  -k, --link                    link instead of copying files to new cluster\n"));
     318            0 :         printf(_("  -N, --no-sync                 do not wait for changes to be written safely to disk\n"));
     319            0 :         printf(_("  -o, --old-options=OPTIONS     old cluster options to pass to the server\n"));
     320            0 :         printf(_("  -O, --new-options=OPTIONS     new cluster options to pass to the server\n"));
     321            0 :         printf(_("  -p, --old-port=PORT           old cluster port number (default %d)\n"), old_cluster.port);
     322            0 :         printf(_("  -P, --new-port=PORT           new cluster port number (default %d)\n"), new_cluster.port);
     323            0 :         printf(_("  -r, --retain                  retain SQL and log files after success\n"));
     324            0 :         printf(_("  -s, --socketdir=DIR           socket directory to use (default current dir.)\n"));
     325            0 :         printf(_("  -U, --username=NAME           cluster superuser (default \"%s\")\n"), os_info.user);
     326            0 :         printf(_("  -v, --verbose                 enable verbose internal logging\n"));
     327            0 :         printf(_("  -V, --version                 display version information, then exit\n"));
     328            0 :         printf(_("  --clone                       clone instead of copying files to new cluster\n"));
     329            0 :         printf(_("  --copy                        copy files to new cluster (default)\n"));
     330            0 :         printf(_("  --copy-file-range             copy files to new cluster with copy_file_range\n"));
     331            0 :         printf(_("  --no-statistics               do not import statistics from old cluster\n"));
     332            0 :         printf(_("  --set-char-signedness=OPTION  set new cluster char signedness to \"signed\" or\n"
     333              :                          "                                \"unsigned\"\n"));
     334            0 :         printf(_("  --swap                        move data directories to new cluster\n"));
     335            0 :         printf(_("  --sync-method=METHOD          set method for syncing files to disk\n"));
     336            0 :         printf(_("  -?, --help                    show this help, then exit\n"));
     337            0 :         printf(_("\n"
     338              :                          "Before running pg_upgrade you must:\n"
     339              :                          "  create a new database cluster (using the new version of initdb)\n"
     340              :                          "  shutdown the postmaster servicing the old cluster\n"
     341              :                          "  shutdown the postmaster servicing the new cluster\n"));
     342            0 :         printf(_("\n"
     343              :                          "When you run pg_upgrade, you must provide the following information:\n"
     344              :                          "  the data directory for the old cluster  (-d DATADIR)\n"
     345              :                          "  the data directory for the new cluster  (-D DATADIR)\n"
     346              :                          "  the \"bin\" directory for the old version (-b BINDIR)\n"
     347              :                          "  the \"bin\" directory for the new version (-B BINDIR)\n"));
     348            0 :         printf(_("\n"
     349              :                          "For example:\n"
     350              :                          "  pg_upgrade -d oldCluster/data -D newCluster/data -b oldCluster/bin -B newCluster/bin\n"
     351              :                          "or\n"));
     352              : #ifndef WIN32
     353            0 :         printf(_("  $ export PGDATAOLD=oldCluster/data\n"
     354              :                          "  $ export PGDATANEW=newCluster/data\n"
     355              :                          "  $ export PGBINOLD=oldCluster/bin\n"
     356              :                          "  $ export PGBINNEW=newCluster/bin\n"
     357              :                          "  $ pg_upgrade\n"));
     358              : #else
     359              :         printf(_("  C:\\> set PGDATAOLD=oldCluster/data\n"
     360              :                          "  C:\\> set PGDATANEW=newCluster/data\n"
     361              :                          "  C:\\> set PGBINOLD=oldCluster/bin\n"
     362              :                          "  C:\\> set PGBINNEW=newCluster/bin\n"
     363              :                          "  C:\\> pg_upgrade\n"));
     364              : #endif
     365            0 :         printf(_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
     366            0 :         printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
     367            0 : }
     368              : 
     369              : 
     370              : /*
     371              :  * check_required_directory()
     372              :  *
     373              :  * Checks a directory option.
     374              :  *      dirpath           - the directory name supplied on the command line, or NULL
     375              :  *      envVarName        - the name of an environment variable to get if dirpath is NULL
     376              :  *      useCwd            - true if OK to default to CWD
     377              :  *      cmdLineOption - the command line option for this directory
     378              :  *      description   - a description of this directory option
     379              :  *      missingOk         - true if OK that both dirpath and envVarName are not existing
     380              :  *
     381              :  * We use the last two arguments to construct a meaningful error message if the
     382              :  * user hasn't provided the required directory name.
     383              :  */
     384              : static void
     385            0 : check_required_directory(char **dirpath, const char *envVarName, bool useCwd,
     386              :                                                  const char *cmdLineOption, const char *description,
     387              :                                                  bool missingOk)
     388              : {
     389            0 :         if (*dirpath == NULL || strlen(*dirpath) == 0)
     390              :         {
     391            0 :                 const char *envVar;
     392              : 
     393            0 :                 if ((envVar = getenv(envVarName)) && strlen(envVar))
     394            0 :                         *dirpath = pg_strdup(envVar);
     395            0 :                 else if (useCwd)
     396              :                 {
     397            0 :                         char            cwd[MAXPGPATH];
     398              : 
     399            0 :                         if (!getcwd(cwd, MAXPGPATH))
     400            0 :                                 pg_fatal("could not determine current directory");
     401            0 :                         *dirpath = pg_strdup(cwd);
     402            0 :                 }
     403            0 :                 else if (missingOk)
     404            0 :                         return;
     405              :                 else
     406            0 :                         pg_fatal("You must identify the directory where the %s.\n"
     407              :                                          "Please use the %s command-line option or the %s environment variable.",
     408            0 :                                          description, cmdLineOption, envVarName);
     409            0 :         }
     410              : 
     411              :         /*
     412              :          * Clean up the path, in particular trimming any trailing path separators,
     413              :          * because we construct paths by appending to this path.
     414              :          */
     415            0 :         canonicalize_path(*dirpath);
     416            0 : }
     417              : 
     418              : /*
     419              :  * adjust_data_dir
     420              :  *
     421              :  * If a configuration-only directory was specified, find the real data dir
     422              :  * by querying the running server.  This has limited checking because we
     423              :  * can't check for a running server because we can't find postmaster.pid.
     424              :  *
     425              :  * On entry, cluster->pgdata has been set from command line or env variable,
     426              :  * but cluster->pgconfig isn't set.  We fill both variables with corrected
     427              :  * values.
     428              :  */
     429              : void
     430            0 : adjust_data_dir(ClusterInfo *cluster)
     431              : {
     432            0 :         char            filename[MAXPGPATH];
     433            0 :         char            cmd[MAXPGPATH],
     434              :                                 cmd_output[MAX_STRING];
     435            0 :         FILE       *fp,
     436              :                            *output;
     437            0 :         int                     rc;
     438              : 
     439              :         /* Initially assume config dir and data dir are the same */
     440            0 :         cluster->pgconfig = pg_strdup(cluster->pgdata);
     441              : 
     442              :         /* If there is no postgresql.conf, it can't be a config-only dir */
     443            0 :         snprintf(filename, sizeof(filename), "%s/postgresql.conf", cluster->pgconfig);
     444            0 :         if ((fp = fopen(filename, "r")) == NULL)
     445            0 :                 return;
     446            0 :         fclose(fp);
     447              : 
     448              :         /* If PG_VERSION exists, it can't be a config-only dir */
     449            0 :         snprintf(filename, sizeof(filename), "%s/PG_VERSION", cluster->pgconfig);
     450            0 :         if ((fp = fopen(filename, "r")) != NULL)
     451              :         {
     452            0 :                 fclose(fp);
     453            0 :                 return;
     454              :         }
     455              : 
     456              :         /* Must be a configuration directory, so find the real data directory. */
     457              : 
     458            0 :         if (cluster == &old_cluster)
     459            0 :                 prep_status("Finding the real data directory for the source cluster");
     460              :         else
     461            0 :                 prep_status("Finding the real data directory for the target cluster");
     462              : 
     463              :         /*
     464              :          * We don't have a data directory yet, so we can't check the PG version,
     465              :          * so this might fail --- only works for PG 9.2+.   If this fails,
     466              :          * pg_upgrade will fail anyway because the data files will not be found.
     467              :          */
     468            0 :         snprintf(cmd, sizeof(cmd), "\"%s/postgres\" -D \"%s\" -C data_directory",
     469            0 :                          cluster->bindir, cluster->pgconfig);
     470            0 :         fflush(NULL);
     471              : 
     472            0 :         if ((output = popen(cmd, "r")) == NULL ||
     473            0 :                 fgets(cmd_output, sizeof(cmd_output), output) == NULL)
     474            0 :                 pg_fatal("could not get data directory using %s: %m", cmd);
     475              : 
     476            0 :         rc = pclose(output);
     477            0 :         if (rc != 0)
     478            0 :                 pg_fatal("could not get data directory using %s: %s",
     479            0 :                                  cmd, wait_result_to_str(rc));
     480              : 
     481              :         /* strip trailing newline and carriage return */
     482            0 :         (void) pg_strip_crlf(cmd_output);
     483              : 
     484            0 :         cluster->pgdata = pg_strdup(cmd_output);
     485              : 
     486            0 :         check_ok();
     487            0 : }
     488              : 
     489              : 
     490              : /*
     491              :  * get_sock_dir
     492              :  *
     493              :  * Identify the socket directory to use for this cluster.  If we're doing
     494              :  * a live check (old cluster only), we need to find out where the postmaster
     495              :  * is listening.  Otherwise, we're going to put the socket into the current
     496              :  * directory.
     497              :  */
     498              : void
     499            0 : get_sock_dir(ClusterInfo *cluster)
     500              : {
     501              : #if !defined(WIN32)
     502            0 :         if (!user_opts.live_check || cluster == &new_cluster)
     503            0 :                 cluster->sockdir = user_opts.socketdir;
     504              :         else
     505              :         {
     506              :                 /*
     507              :                  * If we are doing a live check, we will use the old cluster's Unix
     508              :                  * domain socket directory so we can connect to the live server.
     509              :                  */
     510            0 :                 unsigned short orig_port = cluster->port;
     511            0 :                 char            filename[MAXPGPATH],
     512              :                                         line[MAXPGPATH];
     513            0 :                 FILE       *fp;
     514            0 :                 int                     lineno;
     515              : 
     516            0 :                 snprintf(filename, sizeof(filename), "%s/postmaster.pid",
     517            0 :                                  cluster->pgdata);
     518            0 :                 if ((fp = fopen(filename, "r")) == NULL)
     519            0 :                         pg_fatal("could not open file \"%s\": %m", filename);
     520              : 
     521            0 :                 for (lineno = 1;
     522            0 :                          lineno <= Max(LOCK_FILE_LINE_PORT, LOCK_FILE_LINE_SOCKET_DIR);
     523            0 :                          lineno++)
     524              :                 {
     525            0 :                         if (fgets(line, sizeof(line), fp) == NULL)
     526            0 :                                 pg_fatal("could not read line %d from file \"%s\": %m",
     527            0 :                                                  lineno, filename);
     528              : 
     529              :                         /* potentially overwrite user-supplied value */
     530            0 :                         if (lineno == LOCK_FILE_LINE_PORT)
     531            0 :                                 sscanf(line, "%hu", &old_cluster.port);
     532            0 :                         if (lineno == LOCK_FILE_LINE_SOCKET_DIR)
     533              :                         {
     534              :                                 /* strip trailing newline and carriage return */
     535            0 :                                 cluster->sockdir = pg_strdup(line);
     536            0 :                                 (void) pg_strip_crlf(cluster->sockdir);
     537            0 :                         }
     538            0 :                 }
     539            0 :                 fclose(fp);
     540              : 
     541              :                 /* warn of port number correction */
     542            0 :                 if (orig_port != DEF_PGUPORT && old_cluster.port != orig_port)
     543            0 :                         pg_log(PG_WARNING, "user-supplied old port number %hu corrected to %hu",
     544            0 :                                    orig_port, cluster->port);
     545            0 :         }
     546              : #else                                                   /* WIN32 */
     547              :         cluster->sockdir = NULL;
     548              : #endif
     549            0 : }
        

Generated by: LCOV version 2.3.2-1