2121
2222
2323static void usage (void );
24- static void check_required_directory (char * * dirpath , char * * configpath ,
25- const char * envVarName , const char * cmdLineOption , const char * description );
24+ static void check_required_directory (char * * dirpath ,
25+ const char * envVarName , bool useCwd ,
26+ const char * cmdLineOption , const char * description );
2627#define FIX_DEFAULT_READ_ONLY "-c default_transaction_read_only=false"
2728
2829
@@ -52,6 +53,7 @@ parseCommandLine(int argc, char *argv[])
5253 {"link" , no_argument , NULL , 'k' },
5354 {"retain" , no_argument , NULL , 'r' },
5455 {"jobs" , required_argument , NULL , 'j' },
56+ {"socketdir" , required_argument , NULL , 's' },
5557 {"verbose" , no_argument , NULL , 'v' },
5658 {"clone" , no_argument , NULL , 1 },
5759
@@ -102,7 +104,7 @@ parseCommandLine(int argc, char *argv[])
102104 if ((log_opts .internal = fopen_priv (INTERNAL_LOG_FILE , "a" )) == NULL )
103105 pg_fatal ("could not write to log file \"%s\"\n" , INTERNAL_LOG_FILE );
104106
105- while ((option = getopt_long (argc , argv , "d:D:b:B:cj:ko:O:p:P:rU :v" ,
107+ while ((option = getopt_long (argc , argv , "d:D:b:B:cj:ko:O:p:P:rs:U :v" ,
106108 long_options , & optindex )) != -1 )
107109 {
108110 switch (option )
@@ -121,12 +123,10 @@ parseCommandLine(int argc, char *argv[])
121123
122124 case 'd' :
123125 old_cluster .pgdata = pg_strdup (optarg );
124- old_cluster .pgconfig = pg_strdup (optarg );
125126 break ;
126127
127128 case 'D' :
128129 new_cluster .pgdata = pg_strdup (optarg );
129- new_cluster .pgconfig = pg_strdup (optarg );
130130 break ;
131131
132132 case 'j' :
@@ -188,6 +188,10 @@ parseCommandLine(int argc, char *argv[])
188188 log_opts .retain = true;
189189 break ;
190190
191+ case 's' :
192+ user_opts .socketdir = pg_strdup (optarg );
193+ break ;
194+
191195 case 'U' :
192196 pg_free (os_info .user );
193197 os_info .user = pg_strdup (optarg );
@@ -244,14 +248,16 @@ parseCommandLine(int argc, char *argv[])
244248 pg_putenv ("PGOPTIONS" , FIX_DEFAULT_READ_ONLY );
245249
246250 /* Get values from env if not already set */
247- check_required_directory (& old_cluster .bindir , NULL , "PGBINOLD" , "-b" ,
248- _ ("old cluster binaries reside" ));
249- check_required_directory (& new_cluster .bindir , NULL , "PGBINNEW" , "-B" ,
250- _ ("new cluster binaries reside" ));
251- check_required_directory (& old_cluster .pgdata , & old_cluster .pgconfig ,
252- "PGDATAOLD" , "-d" , _ ("old cluster data resides" ));
253- check_required_directory (& new_cluster .pgdata , & new_cluster .pgconfig ,
254- "PGDATANEW" , "-D" , _ ("new cluster data resides" ));
251+ check_required_directory (& old_cluster .bindir , "PGBINOLD" , false,
252+ "-b" , _ ("old cluster binaries reside" ));
253+ check_required_directory (& new_cluster .bindir , "PGBINNEW" , false,
254+ "-B" , _ ("new cluster binaries reside" ));
255+ check_required_directory (& old_cluster .pgdata , "PGDATAOLD" , false,
256+ "-d" , _ ("old cluster data resides" ));
257+ check_required_directory (& new_cluster .pgdata , "PGDATANEW" , false,
258+ "-D" , _ ("new cluster data resides" ));
259+ check_required_directory (& user_opts .socketdir , "PGSOCKETDIR" , true,
260+ "-s" , _ ("sockets will be created" ));
255261
256262#ifdef WIN32
257263
@@ -296,6 +302,7 @@ usage(void)
296302 printf (_ (" -p, --old-port=PORT old cluster port number (default %d)\n" ), old_cluster .port );
297303 printf (_ (" -P, --new-port=PORT new cluster port number (default %d)\n" ), new_cluster .port );
298304 printf (_ (" -r, --retain retain SQL and log files after success\n" ));
305+ printf (_ (" -s, --socketdir=DIR socket directory to use (default CWD)\n" ));
299306 printf (_ (" -U, --username=NAME cluster superuser (default \"%s\")\n" ), os_info .user );
300307 printf (_ (" -v, --verbose enable verbose internal logging\n" ));
301308 printf (_ (" -V, --version display version information, then exit\n" ));
@@ -337,29 +344,32 @@ usage(void)
337344 * check_required_directory()
338345 *
339346 * Checks a directory option.
340- * dirpath - the directory name supplied on the command line
341- * configpath - optional configuration directory
347+ * dirpath - the directory name supplied on the command line, or NULL
342348 * envVarName - the name of an environment variable to get if dirpath is NULL
343- * cmdLineOption - the command line option corresponds to this directory (-o, -O, -n, -N)
349+ * useCwd - true if OK to default to CWD
350+ * cmdLineOption - the command line option for this directory
344351 * description - a description of this directory option
345352 *
346353 * We use the last two arguments to construct a meaningful error message if the
347354 * user hasn't provided the required directory name.
348355 */
349356static void
350- check_required_directory (char * * dirpath , char * * configpath ,
351- const char * envVarName , const char * cmdLineOption ,
352- const char * description )
357+ check_required_directory (char * * dirpath , const char * envVarName , bool useCwd ,
358+ const char * cmdLineOption , const char * description )
353359{
354360 if (* dirpath == NULL || strlen (* dirpath ) == 0 )
355361 {
356362 const char * envVar ;
357363
358364 if ((envVar = getenv (envVarName )) && strlen (envVar ))
359- {
360365 * dirpath = pg_strdup (envVar );
361- if (configpath )
362- * configpath = pg_strdup (envVar );
366+ else if (useCwd )
367+ {
368+ char cwd [MAXPGPATH ];
369+
370+ if (!getcwd (cwd , MAXPGPATH ))
371+ pg_fatal ("could not determine current directory\n" );
372+ * dirpath = pg_strdup (cwd );
363373 }
364374 else
365375 pg_fatal ("You must identify the directory where the %s.\n"
@@ -368,16 +378,10 @@ check_required_directory(char **dirpath, char **configpath,
368378 }
369379
370380 /*
371- * Trim off any trailing path separators because we construct paths by
372- * appending to this path.
381+ * Clean up the path, in particular trimming any trailing path separators,
382+ * because we construct paths by appending to this path.
373383 */
374- #ifndef WIN32
375- if ((* dirpath )[strlen (* dirpath ) - 1 ] == '/' )
376- #else
377- if ((* dirpath )[strlen (* dirpath ) - 1 ] == '/' ||
378- (* dirpath )[strlen (* dirpath ) - 1 ] == '\\' )
379- #endif
380- (* dirpath )[strlen (* dirpath ) - 1 ] = 0 ;
384+ canonicalize_path (* dirpath );
381385}
382386
383387/*
@@ -386,6 +390,10 @@ check_required_directory(char **dirpath, char **configpath,
386390 * If a configuration-only directory was specified, find the real data dir
387391 * by querying the running server. This has limited checking because we
388392 * can't check for a running server because we can't find postmaster.pid.
393+ *
394+ * On entry, cluster->pgdata has been set from command line or env variable,
395+ * but cluster->pgconfig isn't set. We fill both variables with corrected
396+ * values.
389397 */
390398void
391399adjust_data_dir (ClusterInfo * cluster )
@@ -396,6 +404,9 @@ adjust_data_dir(ClusterInfo *cluster)
396404 FILE * fp ,
397405 * output ;
398406
407+ /* Initially assume config dir and data dir are the same */
408+ cluster -> pgconfig = pg_strdup (cluster -> pgdata );
409+
399410 /* If there is no postgresql.conf, it can't be a config-only dir */
400411 snprintf (filename , sizeof (filename ), "%s/postgresql.conf" , cluster -> pgconfig );
401412 if ((fp = fopen (filename , "r" )) == NULL )
@@ -462,12 +473,7 @@ get_sock_dir(ClusterInfo *cluster, bool live_check)
462473 if (GET_MAJOR_VERSION (cluster -> major_version ) >= 901 )
463474 {
464475 if (!live_check )
465- {
466- /* Use the current directory for the socket */
467- cluster -> sockdir = pg_malloc (MAXPGPATH );
468- if (!getcwd (cluster -> sockdir , MAXPGPATH ))
469- pg_fatal ("could not determine current directory\n" );
470- }
476+ cluster -> sockdir = user_opts .socketdir ;
471477 else
472478 {
473479 /*
0 commit comments