PostgreSQL Source Code git master
version.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * version.c
4 * Routine to retrieve information of PG_VERSION
5 *
6 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 *
10 * IDENTIFICATION
11 * src/fe_utils/version.c
12 *
13 *-------------------------------------------------------------------------
14 */
15
16#include "postgres_fe.h"
17
18#include <sys/stat.h>
19
20#include "common/logging.h"
21#include "fe_utils/version.h"
22
23/*
24 * Assumed maximum size of PG_VERSION. This should be more than enough for
25 * any version numbers that need to be handled.
26 */
27#define PG_VERSION_MAX_SIZE 64
28
29/*
30 * get_pg_version
31 *
32 * Retrieve the major version number of the given data folder, from
33 * PG_VERSION. The result returned is a version number, that can be used
34 * for comparisons based on PG_VERSION_NUM. For example, if PG_VERSION
35 * contains "18\n", this function returns 180000.
36 *
37 * This supports both the pre-v10 and the post-v10 version numbering.
38 *
39 * Optionally, "version_str" can be specified to store the contents
40 * retrieved from PG_VERSION. It is allocated by this routine; the
41 * caller is responsible for pg_free()-ing it.
42 */
44get_pg_version(const char *datadir, char **version_str)
45{
46 FILE *version_fd;
47 char ver_filename[MAXPGPATH];
49 int v1 = 0,
50 v2 = 0;
51 struct stat st;
52
53 snprintf(ver_filename, sizeof(ver_filename), "%s/PG_VERSION",
54 datadir);
55
56 if ((version_fd = fopen(ver_filename, "r")) == NULL)
57 pg_fatal("could not open version file \"%s\": %m", ver_filename);
58
59 if (fstat(fileno(version_fd), &st) != 0)
60 pg_fatal("could not stat file \"%s\": %m", ver_filename);
62 pg_fatal("file \"%s\" is too large", ver_filename);
63
64 if (fscanf(version_fd, "%63s", buf) == 0 ||
65 sscanf(buf, "%d.%d", &v1, &v2) < 1)
66 pg_fatal("could not parse version file \"%s\"", ver_filename);
67
68 fclose(version_fd);
69
70 if (version_str)
71 {
72 *version_str = pg_malloc(PG_VERSION_MAX_SIZE);
73 memcpy(*version_str, buf, st.st_size);
74 }
75
76 if (v1 < 10)
77 {
78 /* pre-v10 style, e.g. 9.6.1 */
79 return v1 * 10000 + v2 * 100;
80 }
81 else
82 {
83 /* post-v10 style, e.g. 10.1 */
84 return v1 * 10000;
85 }
86}
uint32_t uint32
Definition: c.h:543
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
#define PG_VERSION_MAX_SIZE
Definition: version.c:27
uint32 get_pg_version(const char *datadir, char **version_str)
Definition: version.c:44
#define pg_fatal(...)
#define MAXPGPATH
char * datadir
static char * buf
Definition: pg_test_fsync.c:72
#define snprintf
Definition: port.h:239
__int64 st_size
Definition: win32_port.h:263
#define fstat
Definition: win32_port.h:273