v1-0009-Clean-up-read-return-type.patch

text/plain

Filename: v1-0009-Clean-up-read-return-type.patch
Type: text/plain
Part: 8
Message: clean up size_t/ssize_t use with POSIX file system APIs

Patch

Format: format-patch
Series: patch v1-0009
Subject: Clean up read() return type
File+
contrib/basic_archive/basic_archive.c 3 3
src/backend/access/transam/timeline.c 4 4
src/backend/access/transam/twophase.c 8 6
src/backend/access/transam/xlog.c 6 6
src/backend/libpq/be-fsstubs.c 2 2
src/backend/postmaster/syslogger.c 1 1
src/backend/replication/logical/origin.c 3 3
src/backend/replication/logical/reorderbuffer.c 3 3
src/backend/replication/logical/snapbuild.c 2 2
src/backend/replication/slot.c 4 4
src/backend/replication/walsender.c 14 4
src/backend/storage/file/copydir.c 2 2
src/backend/storage/ipc/waiteventset.c 1 1
src/backend/utils/cache/relmapper.c 2 2
src/backend/utils/init/miscinit.c 4 3
src/bin/pg_basebackup/pg_basebackup.c 4 3
src/bin/pg_basebackup/pg_receivewal.c 2 2
src/bin/pg_checksums/pg_checksums.c 4 3
src/bin/pg_combinebackup/load_manifest.c 19 14
src/bin/pg_combinebackup/pg_combinebackup.c 8 5
src/bin/pg_combinebackup/reconstruct.c 6 4
src/bin/pg_ctl/pg_ctl.c 9 6
src/bin/pg_resetwal/pg_resetwal.c 1 1
src/bin/pg_rewind/file_ops.c 4 4
src/bin/pg_rewind/parsexlog.c 2 3
src/bin/pg_verifybackup/pg_verifybackup.c 21 17
src/bin/pg_waldump/archive_waldump.c 1 1
src/bin/pg_waldump/pg_waldump.c 3 3
src/common/controldata_utils.c 3 3
src/interfaces/libpq/fe-lobj.c 2 2
src/test/examples/testlo64.c 2 2
src/test/examples/testlo.c 3 3
From f41dee0e9fe292a1ef1698a89e7628cf54f49197 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Mon, 29 Jun 2026 13:37:54 +0200
Subject: [PATCH v1 09/15] Clean up read() return type

Be sure to store the return value in a variable of type
ssize_t, not int.

Also make the error messages for short reads consistent.  They should
always be like "read %zd of %zu".  Appearance of other placeholders
indicates the types are probably wrong (although in some cases some
casts are added to make macros have the right type and keep the
strings consistent, and it some cases it's left as "%zu of %zu", which
is close enough).

In several cases, the input length is derived from struct stat
st_size, which has type off_t, which is neither size_t nor ssize_t.
To keep the type handling clearer, this introduces intermediate
variables in these cases.

In SendTimeLineHistory() in walsender.c, we need to adjust the logic a
bit to over underflow wrap if we end up reading more from the file
than expected.  This is believed to be a theoretical problem only.
Alternatively, we could treat this as an error.  Note that the
previous code would have processed the extra data but only up to a
full block, which seems wrong in any case.
---
 contrib/basic_archive/basic_archive.c         |  6 +--
 src/backend/access/transam/timeline.c         |  8 ++--
 src/backend/access/transam/twophase.c         | 14 ++++---
 src/backend/access/transam/xlog.c             | 12 +++---
 src/backend/libpq/be-fsstubs.c                |  4 +-
 src/backend/postmaster/syslogger.c            |  2 +-
 src/backend/replication/logical/origin.c      |  6 +--
 .../replication/logical/reorderbuffer.c       |  6 +--
 src/backend/replication/logical/snapbuild.c   |  4 +-
 src/backend/replication/slot.c                |  8 ++--
 src/backend/replication/walsender.c           | 18 +++++++--
 src/backend/storage/file/copydir.c            |  4 +-
 src/backend/storage/ipc/waiteventset.c        |  2 +-
 src/backend/utils/cache/relmapper.c           |  4 +-
 src/backend/utils/init/miscinit.c             |  7 ++--
 src/bin/pg_basebackup/pg_basebackup.c         |  7 ++--
 src/bin/pg_basebackup/pg_receivewal.c         |  4 +-
 src/bin/pg_checksums/pg_checksums.c           |  7 ++--
 src/bin/pg_combinebackup/load_manifest.c      | 33 +++++++++-------
 src/bin/pg_combinebackup/pg_combinebackup.c   | 13 ++++---
 src/bin/pg_combinebackup/reconstruct.c        | 10 +++--
 src/bin/pg_ctl/pg_ctl.c                       | 15 +++++---
 src/bin/pg_resetwal/pg_resetwal.c             |  2 +-
 src/bin/pg_rewind/file_ops.c                  |  8 ++--
 src/bin/pg_rewind/parsexlog.c                 |  5 +--
 src/bin/pg_verifybackup/pg_verifybackup.c     | 38 ++++++++++---------
 src/bin/pg_waldump/archive_waldump.c          |  2 +-
 src/bin/pg_waldump/pg_waldump.c               |  6 +--
 src/common/controldata_utils.c                |  6 +--
 src/interfaces/libpq/fe-lobj.c                |  4 +-
 src/test/examples/testlo.c                    |  6 +--
 src/test/examples/testlo64.c                  |  4 +-
 32 files changed, 153 insertions(+), 122 deletions(-)

diff --git a/contrib/basic_archive/basic_archive.c b/contrib/basic_archive/basic_archive.c
index 914a0b56d16..532311a6406 100644
--- a/contrib/basic_archive/basic_archive.c
+++ b/contrib/basic_archive/basic_archive.c
@@ -245,9 +245,9 @@ compare_files(const char *file1, const char *file2)
 
 	for (;;)
 	{
-		int			nbytes = 0;
-		int			buf1_len = 0;
-		int			buf2_len = 0;
+		ssize_t		nbytes = 0;
+		size_t		buf1_len = 0;
+		size_t		buf2_len = 0;
 
 		while (buf1_len < CMP_BUF_SIZE)
 		{
diff --git a/src/backend/access/transam/timeline.c b/src/backend/access/transam/timeline.c
index d49e52993b7..db101b761ee 100644
--- a/src/backend/access/transam/timeline.c
+++ b/src/backend/access/transam/timeline.c
@@ -311,7 +311,7 @@ writeTimeLineHistory(TimeLineID newTLI, TimeLineID parentTLI,
 	char		buffer[BLCKSZ];
 	int			srcfd;
 	int			fd;
-	int			nbytes;
+	ssize_t		nbytes;
 
 	Assert(newTLI > parentTLI); /* else bad selection of newTLI */
 
@@ -355,7 +355,7 @@ writeTimeLineHistory(TimeLineID newTLI, TimeLineID parentTLI,
 		{
 			errno = 0;
 			pgstat_report_wait_start(WAIT_EVENT_TIMELINE_HISTORY_READ);
-			nbytes = (int) read(srcfd, buffer, sizeof(buffer));
+			nbytes = read(srcfd, buffer, sizeof(buffer));
 			pgstat_report_wait_end();
 			if (nbytes < 0 || errno != 0)
 				ereport(ERROR,
@@ -365,7 +365,7 @@ writeTimeLineHistory(TimeLineID newTLI, TimeLineID parentTLI,
 				break;
 			errno = 0;
 			pgstat_report_wait_start(WAIT_EVENT_TIMELINE_HISTORY_WRITE);
-			if ((int) write(fd, buffer, nbytes) != nbytes)
+			if (write(fd, buffer, nbytes) != nbytes)
 			{
 				int			save_errno = errno;
 
@@ -409,7 +409,7 @@ writeTimeLineHistory(TimeLineID newTLI, TimeLineID parentTLI,
 	nbytes = strlen(buffer);
 	errno = 0;
 	pgstat_report_wait_start(WAIT_EVENT_TIMELINE_HISTORY_WRITE);
-	if ((int) write(fd, buffer, nbytes) != nbytes)
+	if (write(fd, buffer, nbytes) != nbytes)
 	{
 		int			save_errno = errno;
 
diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c
index e27efcaab47..69c12226b7b 100644
--- a/src/backend/access/transam/twophase.c
+++ b/src/backend/access/transam/twophase.c
@@ -1301,6 +1301,7 @@ static char *
 ReadTwoPhaseFile(FullTransactionId fxid, bool missing_ok)
 {
 	char		path[MAXPGPATH];
+	size_t		buflen;
 	char	   *buf;
 	TwoPhaseFileHeader *hdr;
 	int			fd;
@@ -1308,7 +1309,7 @@ ReadTwoPhaseFile(FullTransactionId fxid, bool missing_ok)
 	uint32		crc_offset;
 	pg_crc32c	calc_crc,
 				file_crc;
-	int			r;
+	ssize_t		r;
 
 	TwoPhaseFilePath(path, fxid);
 
@@ -1355,11 +1356,12 @@ ReadTwoPhaseFile(FullTransactionId fxid, bool missing_ok)
 	/*
 	 * OK, slurp in the file.
 	 */
-	buf = (char *) palloc(stat.st_size);
+	buflen = stat.st_size;
+	buf = (char *) palloc(buflen);
 
 	pgstat_report_wait_start(WAIT_EVENT_TWOPHASE_FILE_READ);
-	r = read(fd, buf, stat.st_size);
-	if (r != stat.st_size)
+	r = read(fd, buf, buflen);
+	if (r != buflen)
 	{
 		if (r < 0)
 			ereport(ERROR,
@@ -1367,8 +1369,8 @@ ReadTwoPhaseFile(FullTransactionId fxid, bool missing_ok)
 					 errmsg("could not read file \"%s\": %m", path)));
 		else
 			ereport(ERROR,
-					(errmsg("could not read file \"%s\": read %d of %lld",
-							path, r, (long long int) stat.st_size)));
+					(errmsg("could not read file \"%s\": read %zd of %zu",
+							path, r, buflen)));
 	}
 
 	pgstat_report_wait_end();
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index ddd0f4b7642..d76f77ac3f2 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -3506,7 +3506,7 @@ XLogFileCopy(TimeLineID destTLI, XLogSegNo destsegno,
 	 */
 	for (nbytes = 0; nbytes < wal_segment_size; nbytes += sizeof(buffer))
 	{
-		int			nread;
+		ssize_t		nread;
 
 		nread = upto - nbytes;
 
@@ -3519,7 +3519,7 @@ XLogFileCopy(TimeLineID destTLI, XLogSegNo destsegno,
 
 		if (nread > 0)
 		{
-			int			r;
+			ssize_t		r;
 
 			if (nread > sizeof(buffer))
 				nread = sizeof(buffer);
@@ -3535,8 +3535,8 @@ XLogFileCopy(TimeLineID destTLI, XLogSegNo destsegno,
 				else
 					ereport(ERROR,
 							(errcode(ERRCODE_DATA_CORRUPTED),
-							 errmsg("could not read file \"%s\": read %d of %zu",
-									path, r, (Size) nread)));
+							 errmsg("could not read file \"%s\": read %zd of %zu",
+									path, r, nread)));
 			}
 			pgstat_report_wait_end();
 		}
@@ -4408,7 +4408,7 @@ ReadControlFile(void)
 	pg_crc32c	crc;
 	int			fd;
 	char		wal_segsz_str[20];
-	int			r;
+	ssize_t		r;
 
 	/*
 	 * Read data...
@@ -4433,7 +4433,7 @@ ReadControlFile(void)
 		else
 			ereport(PANIC,
 					(errcode(ERRCODE_DATA_CORRUPTED),
-					 errmsg("could not read file \"%s\": read %d of %zu",
+					 errmsg("could not read file \"%s\": read %zd of %zu",
 							XLOG_CONTROL_FILE, r, sizeof(ControlFileData))));
 	}
 	pgstat_report_wait_end();
diff --git a/src/backend/libpq/be-fsstubs.c b/src/backend/libpq/be-fsstubs.c
index f27e374c4ee..1aa4a3080f5 100644
--- a/src/backend/libpq/be-fsstubs.c
+++ b/src/backend/libpq/be-fsstubs.c
@@ -424,8 +424,8 @@ static Oid
 lo_import_internal(text *filename, Oid lobjOid)
 {
 	int			fd;
-	int			nbytes,
-				tmp PG_USED_FOR_ASSERTS_ONLY;
+	ssize_t		nbytes;
+	int			tmp PG_USED_FOR_ASSERTS_ONLY;
 	char		buf[BUFSIZE];
 	char		fnamebuf[MAXPGPATH];
 	LargeObjectDesc *lobj;
diff --git a/src/backend/postmaster/syslogger.c b/src/backend/postmaster/syslogger.c
index 7645c495a81..b4b599c4c69 100644
--- a/src/backend/postmaster/syslogger.c
+++ b/src/backend/postmaster/syslogger.c
@@ -533,7 +533,7 @@ SysLoggerMain(const void *startup_data, size_t startup_data_len)
 
 		if (rc == 1 && event.events == WL_SOCKET_READABLE)
 		{
-			int			bytesRead;
+			ssize_t		bytesRead;
 
 			bytesRead = read(syslogPipe[0],
 							 logbuffer + bytes_in_logbuffer,
diff --git a/src/backend/replication/logical/origin.c b/src/backend/replication/logical/origin.c
index c9dfb094c2b..5cb18d851ae 100644
--- a/src/backend/replication/logical/origin.c
+++ b/src/backend/replication/logical/origin.c
@@ -741,7 +741,7 @@ StartupReplicationOrigin(void)
 {
 	const char *path = PG_REPLORIGIN_CHECKPOINT_FILENAME;
 	int			fd;
-	int			readBytes;
+	ssize_t		readBytes;
 	uint32		magic = REPLICATION_STATE_MAGIC;
 	int			last_state = 0;
 	pg_crc32c	file_crc;
@@ -788,7 +788,7 @@ StartupReplicationOrigin(void)
 		else
 			ereport(PANIC,
 					(errcode(ERRCODE_DATA_CORRUPTED),
-					 errmsg("could not read file \"%s\": read %d of %zu",
+					 errmsg("could not read file \"%s\": read %zd of %zu",
 							path, readBytes, sizeof(magic))));
 	}
 	COMP_CRC32C(crc, &magic, sizeof(magic));
@@ -826,7 +826,7 @@ StartupReplicationOrigin(void)
 		{
 			ereport(PANIC,
 					(errcode_for_file_access(),
-					 errmsg("could not read file \"%s\": read %d of %zu",
+					 errmsg("could not read file \"%s\": read %zd of %zu",
 							path, readBytes, sizeof(disk_state))));
 		}
 
diff --git a/src/backend/replication/logical/reorderbuffer.c b/src/backend/replication/logical/reorderbuffer.c
index 059ed860314..bd005a2aaf9 100644
--- a/src/backend/replication/logical/reorderbuffer.c
+++ b/src/backend/replication/logical/reorderbuffer.c
@@ -5361,7 +5361,7 @@ ApplyLogicalMappingFile(HTAB *tuplecid_data, const char *fname)
 {
 	char		path[MAXPGPATH];
 	int			fd;
-	int			readBytes;
+	ssize_t		readBytes;
 	LogicalRewriteMappingData map;
 
 	sprintf(path, "%s/%s", PG_LOGICAL_MAPPINGS_DIR, fname);
@@ -5396,9 +5396,9 @@ ApplyLogicalMappingFile(HTAB *tuplecid_data, const char *fname)
 		else if (readBytes != sizeof(LogicalRewriteMappingData))
 			ereport(ERROR,
 					(errcode_for_file_access(),
-					 errmsg("could not read from file \"%s\": read %d instead of %d bytes",
+					 errmsg("could not read from file \"%s\": read %zd of %zu",
 							path, readBytes,
-							(int32) sizeof(LogicalRewriteMappingData))));
+							sizeof(LogicalRewriteMappingData))));
 
 		key.rlocator = map.old_locator;
 		ItemPointerCopy(&map.old_tid,
diff --git a/src/backend/replication/logical/snapbuild.c b/src/backend/replication/logical/snapbuild.c
index b8992234924..5247d8deb89 100644
--- a/src/backend/replication/logical/snapbuild.c
+++ b/src/backend/replication/logical/snapbuild.c
@@ -1936,7 +1936,7 @@ SnapBuildRestore(SnapBuild *builder, XLogRecPtr lsn)
 static void
 SnapBuildRestoreContents(int fd, void *dest, Size size, const char *path)
 {
-	int			readBytes;
+	ssize_t		readBytes;
 
 	pgstat_report_wait_start(WAIT_EVENT_SNAPBUILD_READ);
 	readBytes = read(fd, dest, size);
@@ -1957,7 +1957,7 @@ SnapBuildRestoreContents(int fd, void *dest, Size size, const char *path)
 		else
 			ereport(ERROR,
 					(errcode(ERRCODE_DATA_CORRUPTED),
-					 errmsg("could not read file \"%s\": read %d of %zu",
+					 errmsg("could not read file \"%s\": read %zd of %zu",
 							path, readBytes, size)));
 	}
 }
diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c
index d7fb9f5a67f..c7ab82a28e1 100644
--- a/src/backend/replication/slot.c
+++ b/src/backend/replication/slot.c
@@ -2688,7 +2688,7 @@ RestoreSlotFromDisk(const char *name)
 	char		path[MAXPGPATH + sizeof(PG_REPLSLOT_DIR) + 10];
 	int			fd;
 	bool		restored = false;
-	int			readBytes;
+	ssize_t		readBytes;
 	pg_crc32c	checksum;
 	TimestampTz now = 0;
 
@@ -2748,9 +2748,9 @@ RestoreSlotFromDisk(const char *name)
 		else
 			ereport(PANIC,
 					(errcode(ERRCODE_DATA_CORRUPTED),
-					 errmsg("could not read file \"%s\": read %d of %zu",
+					 errmsg("could not read file \"%s\": read %zd of %zu",
 							path, readBytes,
-							(Size) ReplicationSlotOnDiskConstantSize)));
+							ReplicationSlotOnDiskConstantSize)));
 	}
 
 	/* verify magic */
@@ -2789,7 +2789,7 @@ RestoreSlotFromDisk(const char *name)
 		else
 			ereport(PANIC,
 					(errcode(ERRCODE_DATA_CORRUPTED),
-					 errmsg("could not read file \"%s\": read %d of %zu",
+					 errmsg("could not read file \"%s\": read %zd of %zu",
 							path, readBytes, (Size) cp.length)));
 	}
 
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index de8c9940877..23af75901a9 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -617,7 +617,7 @@ SendTimeLineHistory(TimeLineHistoryCmd *cmd)
 	char		path[MAXPGPATH];
 	int			fd;
 	off_t		histfilelen;
-	off_t		bytesleft;
+	size_t		bytesleft;
 	Size		len;
 
 	dest = CreateDestReceiver(DestRemoteSimple);
@@ -669,7 +669,7 @@ SendTimeLineHistory(TimeLineHistoryCmd *cmd)
 	while (bytesleft > 0)
 	{
 		PGAlignedBlock rbuf;
-		int			nread;
+		ssize_t		nread;
 
 		pgstat_report_wait_start(WAIT_EVENT_WALSENDER_TIMELINE_HISTORY_READ);
 		nread = read(fd, rbuf.data, sizeof(rbuf));
@@ -682,10 +682,20 @@ SendTimeLineHistory(TimeLineHistoryCmd *cmd)
 		else if (nread == 0)
 			ereport(ERROR,
 					(errcode(ERRCODE_DATA_CORRUPTED),
-					 errmsg("could not read file \"%s\": read %d of %zu",
-							path, nread, (Size) bytesleft)));
+					 errmsg("could not read file \"%s\": read %zd of %zu",
+							path, nread, bytesleft)));
+
+		/*
+		 * We could have read more than expected if the file changed
+		 * concurrently.  In that case, only send as much as we expected and
+		 * make sure the loop aborts properly (no wrap of bytesleft).  (This
+		 * isn't possible in practice, because the files are updated by atomic
+		 * renames, but it's a safer programming practice.)
+		 */
+		nread = Min(nread, bytesleft);
 
 		pq_sendbytes(&buf, rbuf.data, nread);
+
 		bytesleft -= nread;
 	}
 
diff --git a/src/backend/storage/file/copydir.c b/src/backend/storage/file/copydir.c
index 5ee141f13a5..ee42c796f77 100644
--- a/src/backend/storage/file/copydir.c
+++ b/src/backend/storage/file/copydir.c
@@ -136,7 +136,7 @@ copy_file(const char *fromfile, const char *tofile)
 	char	   *buffer;
 	int			srcfd;
 	int			dstfd;
-	int			nbytes;
+	ssize_t		nbytes;
 	off_t		offset;
 	off_t		flush_offset;
 
@@ -204,7 +204,7 @@ copy_file(const char *fromfile, const char *tofile)
 			break;
 		errno = 0;
 		pgstat_report_wait_start(WAIT_EVENT_COPY_FILE_WRITE);
-		if ((int) write(dstfd, buffer, nbytes) != nbytes)
+		if (write(dstfd, buffer, nbytes) != nbytes)
 		{
 			/* if write didn't set errno, assume problem is no disk space */
 			if (errno == 0)
diff --git a/src/backend/storage/ipc/waiteventset.c b/src/backend/storage/ipc/waiteventset.c
index 627dba0a842..880c05dd647 100644
--- a/src/backend/storage/ipc/waiteventset.c
+++ b/src/backend/storage/ipc/waiteventset.c
@@ -1947,7 +1947,7 @@ static void
 drain(void)
 {
 	char		buf[1024];
-	int			rc;
+	ssize_t		rc;
 	int			fd;
 
 #ifdef WAIT_USE_SELF_PIPE
diff --git a/src/backend/utils/cache/relmapper.c b/src/backend/utils/cache/relmapper.c
index 3aaf466868d..ca7f1b69007 100644
--- a/src/backend/utils/cache/relmapper.c
+++ b/src/backend/utils/cache/relmapper.c
@@ -787,7 +787,7 @@ read_relmap_file(RelMapFile *map, char *dbpath, bool lock_held, int elevel)
 	char		mapfilename[MAXPGPATH];
 	pg_crc32c	crc;
 	int			fd;
-	int			r;
+	ssize_t		r;
 
 	Assert(elevel >= ERROR);
 
@@ -831,7 +831,7 @@ read_relmap_file(RelMapFile *map, char *dbpath, bool lock_held, int elevel)
 		else
 			ereport(elevel,
 					(errcode(ERRCODE_DATA_CORRUPTED),
-					 errmsg("could not read file \"%s\": read %d of %zu",
+					 errmsg("could not read file \"%s\": read %zd of %zu",
 							mapfilename, r, sizeof(RelMapFile))));
 	}
 	pgstat_report_wait_end();
diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c
index 7ffc808073a..263ae7b8d86 100644
--- a/src/backend/utils/init/miscinit.c
+++ b/src/backend/utils/init/miscinit.c
@@ -1164,7 +1164,6 @@ CreateLockFile(const char *filename, bool amPostmaster,
 	int			fd;
 	char		buffer[MAXPGPATH * 2 + 256];
 	int			ntries;
-	int			len;
 	int			encoded_pid;
 	pid_t		other_pid;
 	pid_t		my_pid,
@@ -1216,6 +1215,8 @@ CreateLockFile(const char *filename, bool amPostmaster,
 	 */
 	for (ntries = 0;; ntries++)
 	{
+		ssize_t		len;
+
 		/*
 		 * Try to create the lock file --- O_EXCL makes this atomic.
 		 *
@@ -1521,7 +1522,7 @@ void
 AddToDataDirLockFile(int target_line, const char *str)
 {
 	int			fd;
-	int			len;
+	ssize_t		len;
 	int			lineno;
 	char	   *srcptr;
 	char	   *destptr;
@@ -1648,7 +1649,7 @@ bool
 RecheckDataDirLockFile(void)
 {
 	int			fd;
-	int			len;
+	ssize_t		len;
 	long		file_pid;
 	char		buffer[BLCKSZ];
 
diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c
index 80dc3bbc8da..da906591ed6 100644
--- a/src/bin/pg_basebackup/pg_basebackup.c
+++ b/src/bin/pg_basebackup/pg_basebackup.c
@@ -480,12 +480,13 @@ reached_end_position(XLogRecPtr segendpos, uint32 timeline,
 		r = select(bgpipe[0] + 1, &fds, NULL, NULL, &tv);
 		if (r == 1)
 		{
+			ssize_t		nread;
 			char		xlogend[64] = {0};
 			uint32		hi,
 						lo;
 
-			r = read(bgpipe[0], xlogend, sizeof(xlogend) - 1);
-			if (r < 0)
+			nread = read(bgpipe[0], xlogend, sizeof(xlogend) - 1);
+			if (nread < 0)
 				pg_fatal("could not read from ready pipe: %m");
 
 			if (sscanf(xlogend, "%X/%08X", &hi, &lo) != 2)
@@ -1822,7 +1823,7 @@ BaseBackup(char *compression_algorithm, char *compression_detail,
 	{
 		int			fd;
 		char		mbuf[65536];
-		int			nbytes;
+		ssize_t		nbytes;
 
 		/* Reject if server is too old. */
 		if (serverVersion < MINIMUM_VERSION_FOR_WAL_SUMMARIES)
diff --git a/src/bin/pg_basebackup/pg_receivewal.c b/src/bin/pg_basebackup/pg_receivewal.c
index ddfec298fb7..20506fc3560 100644
--- a/src/bin/pg_basebackup/pg_receivewal.c
+++ b/src/bin/pg_basebackup/pg_receivewal.c
@@ -331,7 +331,7 @@ FindStreamingStart(uint32 *tli)
 			char		buf[4];
 			int			bytes_out;
 			char		fullpath[MAXPGPATH * 2];
-			int			r;
+			ssize_t		r;
 
 			snprintf(fullpath, sizeof(fullpath), "%s/%s", basedir, dirent->d_name);
 
@@ -349,7 +349,7 @@ FindStreamingStart(uint32 *tli)
 					pg_fatal("could not read compressed file \"%s\": %m",
 							 fullpath);
 				else
-					pg_fatal("could not read compressed file \"%s\": read %d of %zu",
+					pg_fatal("could not read compressed file \"%s\": read %zd of %zu",
 							 fullpath, r, sizeof(buf));
 			}
 
diff --git a/src/bin/pg_checksums/pg_checksums.c b/src/bin/pg_checksums/pg_checksums.c
index cfacd1300fc..412c9a18f95 100644
--- a/src/bin/pg_checksums/pg_checksums.c
+++ b/src/bin/pg_checksums/pg_checksums.c
@@ -196,8 +196,9 @@ scan_file(const char *fn, int segmentno)
 	for (blockno = 0;; blockno++)
 	{
 		uint16		csum;
-		int			r = read(f, buf.data, BLCKSZ);
+		ssize_t		r;
 
+		r = read(f, buf.data, BLCKSZ);
 		if (r == 0)
 			break;
 		if (r != BLCKSZ)
@@ -206,8 +207,8 @@ scan_file(const char *fn, int segmentno)
 				pg_fatal("could not read block %u in file \"%s\": %m",
 						 blockno, fn);
 			else
-				pg_fatal("could not read block %u in file \"%s\": read %d of %d",
-						 blockno, fn, r, BLCKSZ);
+				pg_fatal("could not read block %u in file \"%s\": read %zd of %zu",
+						 blockno, fn, r, (size_t) BLCKSZ);
 		}
 		blocks_scanned++;
 
diff --git a/src/bin/pg_combinebackup/load_manifest.c b/src/bin/pg_combinebackup/load_manifest.c
index 021fd3ffa1d..e54ee24a954 100644
--- a/src/bin/pg_combinebackup/load_manifest.c
+++ b/src/bin/pg_combinebackup/load_manifest.c
@@ -111,10 +111,10 @@ load_backup_manifest(char *backup_directory)
 	uint32		initial_size;
 	manifest_files_hash *ht;
 	char	   *buffer;
-	int			rc;
 	JsonManifestParseContext context;
 	manifest_data *result;
-	int			chunk_size = READ_CHUNK_SIZE;
+	size_t		total_size;
+	const size_t chunk_size = READ_CHUNK_SIZE;
 
 	/* Open the manifest file. */
 	snprintf(pathname, MAXPGPATH, "%s/backup_manifest", backup_directory);
@@ -148,31 +148,35 @@ load_backup_manifest(char *backup_directory)
 	context.per_wal_range_cb = combinebackup_per_wal_range_cb;
 	context.error_cb = report_manifest_error;
 
+	total_size = statbuf.st_size;
+
 	/*
 	 * Parse the file, in chunks if necessary.
 	 */
-	if (statbuf.st_size <= chunk_size)
+	if (total_size <= chunk_size)
 	{
-		buffer = pg_malloc(statbuf.st_size);
-		rc = read(fd, buffer, statbuf.st_size);
-		if (rc != statbuf.st_size)
+		ssize_t		rc;
+
+		buffer = pg_malloc(total_size);
+		rc = read(fd, buffer, total_size);
+		if (rc != total_size)
 		{
 			if (rc < 0)
 				pg_fatal("could not read file \"%s\": %m", pathname);
 			else
-				pg_fatal("could not read file \"%s\": read %d of %lld",
-						 pathname, rc, (long long int) statbuf.st_size);
+				pg_fatal("could not read file \"%s\": read %zd of %zu",
+						 pathname, rc, total_size);
 		}
 
 		/* Close the manifest file. */
 		close(fd);
 
 		/* Parse the manifest. */
-		json_parse_manifest(&context, buffer, statbuf.st_size);
+		json_parse_manifest(&context, buffer, total_size);
 	}
 	else
 	{
-		int			bytes_left = statbuf.st_size;
+		size_t		bytes_left = total_size;
 		JsonManifestParseIncrementalState *inc_state;
 
 		inc_state = json_parse_manifest_incremental_init(&context);
@@ -181,7 +185,8 @@ load_backup_manifest(char *backup_directory)
 
 		while (bytes_left > 0)
 		{
-			int			bytes_to_read = chunk_size;
+			ssize_t		rc;
+			size_t		bytes_to_read = chunk_size;
 
 			/*
 			 * Make sure that the last chunk is sufficiently large. (i.e. at
@@ -198,10 +203,10 @@ load_backup_manifest(char *backup_directory)
 				if (rc < 0)
 					pg_fatal("could not read file \"%s\": %m", pathname);
 				else
-					pg_fatal("could not read file \"%s\": read %lld of %lld",
+					pg_fatal("could not read file \"%s\": read %zu of %zu",
 							 pathname,
-							 (long long int) (statbuf.st_size + rc - bytes_left),
-							 (long long int) statbuf.st_size);
+							 total_size + rc - bytes_left,
+							 total_size);
 			}
 			bytes_left -= rc;
 			json_parse_manifest_incremental_chunk(inc_state, buffer, rc, bytes_left == 0);
diff --git a/src/bin/pg_combinebackup/pg_combinebackup.c b/src/bin/pg_combinebackup/pg_combinebackup.c
index c8731c474b0..d0f2af7aa33 100644
--- a/src/bin/pg_combinebackup/pg_combinebackup.c
+++ b/src/bin/pg_combinebackup/pg_combinebackup.c
@@ -1344,6 +1344,7 @@ slurp_file(int fd, char *filename, StringInfo buf, int maxlen)
 {
 	struct stat st;
 	ssize_t		rb;
+	size_t		len;
 
 	/* Check file size, and complain if it's too large. */
 	if (fstat(fd, &st) != 0)
@@ -1351,23 +1352,25 @@ slurp_file(int fd, char *filename, StringInfo buf, int maxlen)
 	if (st.st_size > maxlen)
 		pg_fatal("file \"%s\" is too large", filename);
 
+	len = st.st_size;
+
 	/* Make sure we have enough space. */
-	enlargeStringInfo(buf, st.st_size);
+	enlargeStringInfo(buf, len);
 
 	/* Read the data. */
-	rb = read(fd, &buf->data[buf->len], st.st_size);
+	rb = read(fd, &buf->data[buf->len], len);
 
 	/*
 	 * We don't expect any concurrent changes, so we should read exactly the
 	 * expected number of bytes.
 	 */
-	if (rb != st.st_size)
+	if (rb != len)
 	{
 		if (rb < 0)
 			pg_fatal("could not read file \"%s\": %m", filename);
 		else
-			pg_fatal("could not read file \"%s\": read %zd of %lld",
-					 filename, rb, (long long int) st.st_size);
+			pg_fatal("could not read file \"%s\": read %zd of %zu",
+					 filename, rb, len);
 	}
 
 	/* Adjust buffer length for new data and restore trailing-\0 invariant */
diff --git a/src/bin/pg_combinebackup/reconstruct.c b/src/bin/pg_combinebackup/reconstruct.c
index 7f76b532588..b98f37aa430 100644
--- a/src/bin/pg_combinebackup/reconstruct.c
+++ b/src/bin/pg_combinebackup/reconstruct.c
@@ -61,7 +61,7 @@ static void write_reconstructed_file(const char *input_filename,
 									 CopyMethod copy_method,
 									 bool debug,
 									 bool dry_run);
-static void read_bytes(const rfile *rf, void *buffer, unsigned length);
+static void read_bytes(const rfile *rf, void *buffer, size_t length);
 static void write_block(int fd, const char *output_filename,
 						const uint8 *buffer,
 						pg_checksum_context *checksum_ctx);
@@ -532,16 +532,18 @@ make_rfile(const char *filename, bool missing_ok)
  * Read the indicated number of bytes from an rfile into the buffer.
  */
 static void
-read_bytes(const rfile *rf, void *buffer, unsigned length)
+read_bytes(const rfile *rf, void *buffer, size_t length)
 {
-	int			rb = read(rf->fd, buffer, length);
+	ssize_t		rb;
+
+	rb = read(rf->fd, buffer, length);
 
 	if (rb != length)
 	{
 		if (rb < 0)
 			pg_fatal("could not read file \"%s\": %m", rf->filename);
 		else
-			pg_fatal("could not read file \"%s\": read %d of %u",
+			pg_fatal("could not read file \"%s\": read %zd of %zu",
 					 rf->filename, rb, length);
 	}
 }
diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c
index b5433a75d12..85ded4c0e2b 100644
--- a/src/bin/pg_ctl/pg_ctl.c
+++ b/src/bin/pg_ctl/pg_ctl.c
@@ -317,11 +317,12 @@ readfile(const char *path, int *numlines)
 	int			fd;
 	int			nlines;
 	char	  **result;
+	size_t		buflen;
 	char	   *buffer;
 	char	   *linebegin;
 	int			i;
 	int			n;
-	int			len;
+	ssize_t		nread;
 	struct stat statbuf;
 
 	*numlines = 0;				/* in case of failure or empty file */
@@ -350,11 +351,13 @@ readfile(const char *path, int *numlines)
 		*result = NULL;
 		return result;
 	}
-	buffer = pg_malloc(statbuf.st_size + 1);
 
-	len = read(fd, buffer, statbuf.st_size + 1);
+	buflen = statbuf.st_size + 1;
+	buffer = pg_malloc(buflen);
+
+	nread = read(fd, buffer, buflen);
 	close(fd);
-	if (len != statbuf.st_size)
+	if (nread != buflen - 1)
 	{
 		/* oops, the file size changed between fstat and read */
 		free(buffer);
@@ -367,7 +370,7 @@ readfile(const char *path, int *numlines)
 	 * any characters after the last newline will be ignored.
 	 */
 	nlines = 0;
-	for (i = 0; i < len; i++)
+	for (i = 0; i < nread; i++)
 	{
 		if (buffer[i] == '\n')
 			nlines++;
@@ -380,7 +383,7 @@ readfile(const char *path, int *numlines)
 	/* now split the buffer into lines */
 	linebegin = buffer;
 	n = 0;
-	for (i = 0; i < len; i++)
+	for (i = 0; i < nread; i++)
 	{
 		if (buffer[i] == '\n')
 		{
diff --git a/src/bin/pg_resetwal/pg_resetwal.c b/src/bin/pg_resetwal/pg_resetwal.c
index f8d25afed9d..d072e7c2ea4 100644
--- a/src/bin/pg_resetwal/pg_resetwal.c
+++ b/src/bin/pg_resetwal/pg_resetwal.c
@@ -596,7 +596,7 @@ static bool
 read_controlfile(void)
 {
 	int			fd;
-	int			len;
+	ssize_t		len;
 	char	   *buffer;
 	pg_crc32c	crc;
 
diff --git a/src/bin/pg_rewind/file_ops.c b/src/bin/pg_rewind/file_ops.c
index 6a3562d8bde..3bf6296ed0e 100644
--- a/src/bin/pg_rewind/file_ops.c
+++ b/src/bin/pg_rewind/file_ops.c
@@ -340,8 +340,8 @@ slurpFile(const char *datadir, const char *path, size_t *filesize)
 	char	   *buffer;
 	struct stat statbuf;
 	char		fullpath[MAXPGPATH];
-	int			len;
-	int			r;
+	size_t		len;
+	ssize_t		r;
 
 	snprintf(fullpath, sizeof(fullpath), "%s/%s", datadir, path);
 
@@ -364,8 +364,8 @@ slurpFile(const char *datadir, const char *path, size_t *filesize)
 			pg_fatal("could not read file \"%s\": %m",
 					 fullpath);
 		else
-			pg_fatal("could not read file \"%s\": read %d of %zu",
-					 fullpath, r, (Size) len);
+			pg_fatal("could not read file \"%s\": read %zd of %zu",
+					 fullpath, r, len);
 	}
 	close(fd);
 
diff --git a/src/bin/pg_rewind/parsexlog.c b/src/bin/pg_rewind/parsexlog.c
index db7a7e73042..023e23b063c 100644
--- a/src/bin/pg_rewind/parsexlog.c
+++ b/src/bin/pg_rewind/parsexlog.c
@@ -279,7 +279,7 @@ SimpleXLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr,
 	uint32		targetPageOff;
 	XLogRecPtr	targetSegEnd;
 	XLogSegNo	targetSegNo;
-	int			r;
+	ssize_t		r;
 
 	XLByteToSeg(targetPagePtr, targetSegNo, WalSegSz);
 	XLogSegNoOffsetToRecPtr(targetSegNo + 1, 0, WalSegSz, targetSegEnd);
@@ -370,9 +370,8 @@ SimpleXLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr,
 		if (r < 0)
 			pg_log_error("could not read file \"%s\": %m", xlogfpath);
 		else
-			pg_log_error("could not read file \"%s\": read %d of %zu",
+			pg_log_error("could not read file \"%s\": read %zd of %zu",
 						 xlogfpath, r, (Size) XLOG_BLCKSZ);
-
 		return -1;
 	}
 
diff --git a/src/bin/pg_verifybackup/pg_verifybackup.c b/src/bin/pg_verifybackup/pg_verifybackup.c
index 5c63bea14c7..df7c796acbc 100644
--- a/src/bin/pg_verifybackup/pg_verifybackup.c
+++ b/src/bin/pg_verifybackup/pg_verifybackup.c
@@ -412,11 +412,10 @@ parse_manifest_file(char *manifest_path)
 	uint32		initial_size;
 	manifest_files_hash *ht;
 	char	   *buffer;
-	int			rc;
 	JsonManifestParseContext context;
 	manifest_data *result;
-
-	int			chunk_size = READ_CHUNK_SIZE;
+	size_t		total_size;
+	const size_t chunk_size = READ_CHUNK_SIZE;
 
 	/* Open the manifest file. */
 	if ((fd = open(manifest_path, O_RDONLY | PG_BINARY, 0)) < 0)
@@ -442,31 +441,35 @@ parse_manifest_file(char *manifest_path)
 	context.per_wal_range_cb = verifybackup_per_wal_range_cb;
 	context.error_cb = report_manifest_error;
 
+	total_size = statbuf.st_size;
+
 	/*
 	 * Parse the file, in chunks if necessary.
 	 */
-	if (statbuf.st_size <= chunk_size)
+	if (total_size <= chunk_size)
 	{
-		buffer = pg_malloc(statbuf.st_size);
-		rc = read(fd, buffer, statbuf.st_size);
-		if (rc != statbuf.st_size)
+		ssize_t		rc;
+
+		buffer = pg_malloc(total_size);
+		rc = read(fd, buffer, total_size);
+		if (rc != total_size)
 		{
 			if (rc < 0)
 				pg_fatal("could not read file \"%s\": %m", manifest_path);
 			else
-				pg_fatal("could not read file \"%s\": read %d of %lld",
-						 manifest_path, rc, (long long int) statbuf.st_size);
+				pg_fatal("could not read file \"%s\": read %zd of %zu",
+						 manifest_path, rc, total_size);
 		}
 
 		/* Close the manifest file. */
 		close(fd);
 
 		/* Parse the manifest. */
-		json_parse_manifest(&context, buffer, statbuf.st_size);
+		json_parse_manifest(&context, buffer, total_size);
 	}
 	else
 	{
-		int			bytes_left = statbuf.st_size;
+		size_t		bytes_left = total_size;
 		JsonManifestParseIncrementalState *inc_state;
 
 		inc_state = json_parse_manifest_incremental_init(&context);
@@ -475,7 +478,8 @@ parse_manifest_file(char *manifest_path)
 
 		while (bytes_left > 0)
 		{
-			int			bytes_to_read = chunk_size;
+			ssize_t		rc;
+			size_t		bytes_to_read = chunk_size;
 
 			/*
 			 * Make sure that the last chunk is sufficiently large. (i.e. at
@@ -492,10 +496,10 @@ parse_manifest_file(char *manifest_path)
 				if (rc < 0)
 					pg_fatal("could not read file \"%s\": %m", manifest_path);
 				else
-					pg_fatal("could not read file \"%s\": read %lld of %lld",
+					pg_fatal("could not read file \"%s\": read %zu of %zu",
 							 manifest_path,
-							 (long long int) (statbuf.st_size + rc - bytes_left),
-							 (long long int) statbuf.st_size);
+							 total_size + rc - bytes_left,
+							 total_size);
 			}
 			bytes_left -= rc;
 			json_parse_manifest_incremental_chunk(inc_state, buffer, rc,
@@ -1016,7 +1020,7 @@ verify_tar_file(verifier_context *context, char *relpath, char *fullpath,
 				astreamer *streamer)
 {
 	int			fd;
-	int			rc;
+	ssize_t		rc;
 	char	   *buffer;
 
 	pg_log_debug("reading \"%s\"", fullpath);
@@ -1124,7 +1128,7 @@ verify_file_checksum(verifier_context *context, manifest_file *m,
 	pg_checksum_context checksum_ctx;
 	const char *relpath = m->pathname;
 	int			fd;
-	int			rc;
+	ssize_t		rc;
 	uint64		bytes_read = 0;
 	uint8		checksumbuf[PG_CHECKSUM_MAX_LENGTH];
 	int			checksumlen;
diff --git a/src/bin/pg_waldump/archive_waldump.c b/src/bin/pg_waldump/archive_waldump.c
index 0f44ebfeb20..e0c3aa4d255 100644
--- a/src/bin/pg_waldump/archive_waldump.c
+++ b/src/bin/pg_waldump/archive_waldump.c
@@ -535,7 +535,7 @@ get_archive_wal_entry(const char *fname, XLogDumpPrivate *privateInfo)
 static bool
 read_archive_file(XLogDumpPrivate *privateInfo)
 {
-	int			rc;
+	ssize_t		rc;
 
 	/* Fail if we already reached EOF in a prior call. */
 	if (privateInfo->archive_fd_eof)
diff --git a/src/bin/pg_waldump/pg_waldump.c b/src/bin/pg_waldump/pg_waldump.c
index c777e6763e5..855e4f84813 100644
--- a/src/bin/pg_waldump/pg_waldump.c
+++ b/src/bin/pg_waldump/pg_waldump.c
@@ -236,7 +236,7 @@ search_directory(const char *directory, const char *fname, int *WalSegSz)
 	if (fd >= 0)
 	{
 		PGAlignedXLogBlock buf;
-		int			r;
+		ssize_t		r;
 
 		r = read(fd, buf.data, XLOG_BLCKSZ);
 		if (r == XLOG_BLCKSZ)
@@ -259,8 +259,8 @@ search_directory(const char *directory, const char *fname, int *WalSegSz)
 			pg_fatal("could not read file \"%s\": %m",
 					 fname);
 		else
-			pg_fatal("could not read file \"%s\": read %d of %d",
-					 fname, r, XLOG_BLCKSZ);
+			pg_fatal("could not read file \"%s\": read %zd of %zu",
+					 fname, r, (size_t) XLOG_BLCKSZ);
 		close(fd);
 		return true;
 	}
diff --git a/src/common/controldata_utils.c b/src/common/controldata_utils.c
index 4ab116afcde..0e8e03c566c 100644
--- a/src/common/controldata_utils.c
+++ b/src/common/controldata_utils.c
@@ -71,7 +71,7 @@ get_controlfile_by_exact_path(const char *ControlFilePath, bool *crc_ok_p)
 	ControlFileData *ControlFile;
 	int			fd;
 	pg_crc32c	crc;
-	int			r;
+	ssize_t		r;
 #ifdef FRONTEND
 	pg_crc32c	last_crc;
 	int			retries = 0;
@@ -114,10 +114,10 @@ get_controlfile_by_exact_path(const char *ControlFilePath, bool *crc_ok_p)
 #ifndef FRONTEND
 			ereport(ERROR,
 					(errcode(ERRCODE_DATA_CORRUPTED),
-					 errmsg("could not read file \"%s\": read %d of %zu",
+					 errmsg("could not read file \"%s\": read %zd of %zu",
 							ControlFilePath, r, sizeof(ControlFileData))));
 #else
-			pg_fatal("could not read file \"%s\": read %d of %zu",
+			pg_fatal("could not read file \"%s\": read %zd of %zu",
 					 ControlFilePath, r, sizeof(ControlFileData));
 #endif
 	}
diff --git a/src/interfaces/libpq/fe-lobj.c b/src/interfaces/libpq/fe-lobj.c
index 12a32fcbaf3..3014cae33ac 100644
--- a/src/interfaces/libpq/fe-lobj.c
+++ b/src/interfaces/libpq/fe-lobj.c
@@ -647,8 +647,8 @@ static Oid
 lo_import_internal(PGconn *conn, const char *filename, Oid oid)
 {
 	int			fd;
-	int			nbytes,
-				tmp;
+	ssize_t		nbytes;
+	int			tmp;
 	char		buf[LO_BUFSIZE];
 	Oid			lobjOid;
 	int			lobj;
diff --git a/src/test/examples/testlo.c b/src/test/examples/testlo.c
index fefef1395b8..f73a0fcb100 100644
--- a/src/test/examples/testlo.c
+++ b/src/test/examples/testlo.c
@@ -36,8 +36,8 @@ importFile(PGconn *conn, char *filename)
 	Oid			lobjId;
 	int			lobj_fd;
 	char		buf[BUFSIZE];
-	int			nbytes,
-				tmp;
+	ssize_t		nbytes;
+	int			tmp;
 	int			fd;
 
 	/*
@@ -79,7 +79,7 @@ pickout(PGconn *conn, Oid lobjId, int start, int len)
 {
 	int			lobj_fd;
 	char	   *buf;
-	int			nbytes;
+	ssize_t		nbytes;
 	int			nread;
 
 	lobj_fd = lo_open(conn, lobjId, INV_READ);
diff --git a/src/test/examples/testlo64.c b/src/test/examples/testlo64.c
index 32404e59f5d..cecfa683698 100644
--- a/src/test/examples/testlo64.c
+++ b/src/test/examples/testlo64.c
@@ -37,8 +37,8 @@ importFile(PGconn *conn, char *filename)
 	Oid			lobjId;
 	int			lobj_fd;
 	char		buf[BUFSIZE];
-	int			nbytes,
-				tmp;
+	ssize_t		nbytes;
+	int			tmp;
 	int			fd;
 
 	/*
-- 
2.54.0