11
11
12
12
#include <fcntl.h>
13
13
14
+ #include "common/string.h"
14
15
#include "pg_upgrade.h"
15
16
16
17
static void check_data_dir (ClusterInfo * cluster );
17
18
static void check_bin_dir (ClusterInfo * cluster );
18
19
static void get_bin_version (ClusterInfo * cluster );
19
- static void validate_exec (const char * dir , const char * cmdName );
20
+ static void check_exec (const char * dir , const char * program );
20
21
21
22
#ifdef WIN32
22
23
static int win32_check_directory_write_permissions (void );
@@ -375,9 +376,9 @@ check_bin_dir(ClusterInfo *cluster)
375
376
report_status (PG_FATAL , "\"%s\" is not a directory\n" ,
376
377
cluster -> bindir );
377
378
378
- validate_exec (cluster -> bindir , "postgres" );
379
- validate_exec (cluster -> bindir , "pg_controldata" );
380
- validate_exec (cluster -> bindir , "pg_ctl" );
379
+ check_exec (cluster -> bindir , "postgres" );
380
+ check_exec (cluster -> bindir , "pg_controldata" );
381
+ check_exec (cluster -> bindir , "pg_ctl" );
381
382
382
383
/*
383
384
* Fetch the binary version after checking for the existence of pg_ctl.
@@ -388,9 +389,9 @@ check_bin_dir(ClusterInfo *cluster)
388
389
389
390
/* pg_resetxlog has been renamed to pg_resetwal in version 10 */
390
391
if (GET_MAJOR_VERSION (cluster -> bin_version ) <= 906 )
391
- validate_exec (cluster -> bindir , "pg_resetxlog" );
392
+ check_exec (cluster -> bindir , "pg_resetxlog" );
392
393
else
393
- validate_exec (cluster -> bindir , "pg_resetwal" );
394
+ check_exec (cluster -> bindir , "pg_resetwal" );
394
395
395
396
if (cluster == & new_cluster )
396
397
{
@@ -399,63 +400,46 @@ check_bin_dir(ClusterInfo *cluster)
399
400
* pg_dumpall are used to dump the old cluster, but must be of the
400
401
* target version.
401
402
*/
402
- validate_exec (cluster -> bindir , "initdb" );
403
- validate_exec (cluster -> bindir , "pg_dump" );
404
- validate_exec (cluster -> bindir , "pg_dumpall" );
405
- validate_exec (cluster -> bindir , "pg_restore" );
406
- validate_exec (cluster -> bindir , "psql" );
407
- validate_exec (cluster -> bindir , "vacuumdb" );
403
+ check_exec (cluster -> bindir , "initdb" );
404
+ check_exec (cluster -> bindir , "pg_dump" );
405
+ check_exec (cluster -> bindir , "pg_dumpall" );
406
+ check_exec (cluster -> bindir , "pg_restore" );
407
+ check_exec (cluster -> bindir , "psql" );
408
+ check_exec (cluster -> bindir , "vacuumdb" );
408
409
}
409
410
}
410
411
411
-
412
- /*
413
- * validate_exec()
414
- *
415
- * validate "path" as an executable file
416
- */
417
412
static void
418
- validate_exec (const char * dir , const char * cmdName )
413
+ check_exec (const char * dir , const char * program )
419
414
{
420
- char path [MAXPGPATH ];
421
- struct stat buf ;
415
+ char path [MAXPGPATH ];
416
+ char line [MAXPGPATH ];
417
+ char cmd [MAXPGPATH ];
418
+ char versionstr [128 ];
419
+ int ret ;
422
420
423
- snprintf (path , sizeof (path ), "%s/%s" , dir , cmdName );
421
+ snprintf (path , sizeof (path ), "%s/%s" , dir , program );
424
422
425
- #ifdef WIN32
426
- /* Windows requires a .exe suffix for stat() */
427
- if (strlen (path ) <= strlen (EXE_EXT ) ||
428
- pg_strcasecmp (path + strlen (path ) - strlen (EXE_EXT ), EXE_EXT ) != 0 )
429
- strlcat (path , EXE_EXT , sizeof (path ));
430
- #endif
423
+ ret = validate_exec (path );
431
424
432
- /*
433
- * Ensure that the file exists and is a regular file.
434
- */
435
- if (stat (path , & buf ) < 0 )
436
- pg_fatal ("check for \"%s\" failed: %s\n" ,
437
- path , strerror (errno ));
438
- else if (!S_ISREG (buf .st_mode ))
425
+ if (ret == -1 )
439
426
pg_fatal ("check for \"%s\" failed: not a regular file\n" ,
440
427
path );
441
-
442
- /*
443
- * Ensure that the file is both executable and readable (required for
444
- * dynamic loading).
445
- */
446
- #ifndef WIN32
447
- if (access (path , R_OK ) != 0 )
448
- #else
449
- if ((buf .st_mode & S_IRUSR ) == 0 )
450
- #endif
451
- pg_fatal ("check for \"%s\" failed: cannot read file (permission denied)\n" ,
428
+ else if (ret == -2 )
429
+ pg_fatal ("check for \"%s\" failed: cannot execute (permission denied)\n" ,
452
430
path );
453
431
454
- #ifndef WIN32
455
- if (access (path , X_OK ) != 0 )
456
- #else
457
- if ((buf .st_mode & S_IXUSR ) == 0 )
458
- #endif
459
- pg_fatal ("check for \"%s\" failed: cannot execute (permission denied)\n" ,
432
+ snprintf (cmd , sizeof (cmd ), "\"%s\" -V" , path );
433
+
434
+ if (!pipe_read_line (cmd , line , sizeof (line )))
435
+ pg_fatal ("check for \"%s\" failed: cannot execute\n" ,
460
436
path );
437
+
438
+ pg_strip_crlf (line );
439
+
440
+ snprintf (versionstr , sizeof (versionstr ), "%s (PostgreSQL) " PG_VERSION , program );
441
+
442
+ if (strcmp (line , versionstr ) != 0 )
443
+ pg_fatal ("check for \"%s\" failed: incorrect version: found \"%s\", expected \"%s\"\n" ,
444
+ path , line , versionstr );
461
445
}
0 commit comments