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