From 3f7bf07497cf854e655b17ee0849924a82aa9839 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Deuc=D0=B5?= <shurd@sasktel.net>
Date: Sun, 5 Jan 2025 06:25:07 -0500
Subject: [PATCH] Define and use a new IGNORE_RESULT() macro

Historically, casting to void would suppress warnings about things
being unused.  However, an attribute was created for functions like
realloc() where not using the result is always a bug, so when the
attribute is used, you must actually use the return value and can't
cast to void to avoid a warning.

Given this attribute, the glibc authors decided to apply it to all
the functions that usually should have their return value checked
(chdir(), write(), etc) when _FORTIFY_SOURCE is defined because if
you care about correctness enough to define _FORTIFY_SOURCE, you'll
always do something useful with these return values.

Extending the hilarity, some distros define _FORTIFY_SOURCE by
default.

The result is functions that occasionally can safely be called
regardless of the return value will throw a warning if you don't
"do something" with that return value.

Of course, you can just turn off the warnings completely with a
compiler flag, but then you lose the excellent warning about things
like realloc() that always make sense and were the original reason
for the option.
---
 src/conio/x_events.c   | 30 +++++++++---------------------
 src/syncterm/telnets.c |  4 ++--
 src/xpdev/genwrap.h    | 12 ++++++++++++
 3 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/src/conio/x_events.c b/src/conio/x_events.c
index 71d69ae57b..75e11644ea 100644
--- a/src/conio/x_events.c
+++ b/src/conio/x_events.c
@@ -1665,17 +1665,17 @@ handle_bios_key(uint32_t *bios_key, bool *bios_key_parsing, bool *zero_first)
 			if (ch == 0)
 				x11.XBell(dpy, 100);
 			else {
-				write(key_pipe[1], &ch, 1);
+				IGNORE_RESULT(write(key_pipe[1], &ch, 1));
 				if (ch == 0xe0)
-					write(key_pipe[1], &ch, 1);
+					IGNORE_RESULT(write(key_pipe[1], &ch, 1));
 			}
 		}
 		else {
 			// Codepage character
 			ch = *bios_key;
-			write(key_pipe[1], &ch, 1);
+			IGNORE_RESULT(write(key_pipe[1], &ch, 1));
 			if (ch == 0xe0)
-				write(key_pipe[1], &ch, 1);
+				IGNORE_RESULT(write(key_pipe[1], &ch, 1));
 		}
 	}
 	*bios_key = 0;
@@ -1701,11 +1701,7 @@ x11_event(XEvent *ev)
 		case ClientMessage:
 			if (ev->xclient.format == 32 && ev->xclient.data.l[0] == A(WM_DELETE_WINDOW) && A(WM_DELETE_WINDOW) != None) {
 				uint16_t key=CIO_KEY_QUIT;
-				// Bow to GCC
-				if (write(key_pipe[1], &key, 2) == EXIT_FAILURE)
-					return;
-				else
-					return;
+				IGNORE_RESULT(write(key_pipe[1], &key, 2));
 			}
 			else if(ev->xclient.format == 32 && ev->xclient.data.l[0] == A(_NET_WM_PING) && A(_NET_WM_PING) != None) {
 				ev->xclient.window = root;
@@ -2078,14 +2074,10 @@ x11_event(XEvent *ev)
 								else
 									ch = cpchar_from_unicode_cpoint(getcodepage(), wbuf[i], 0);
 								if (ch) {
-									// Bow to GCC
 									if (ch == 0xe0) // Double-up 0xe0
-										if (write(key_pipe[1], &ch, 1) == -1)
-											return;
-									if (write(key_pipe[1], &ch, 1) == EXIT_SUCCESS)
-										return;
-									else
-										return;
+										IGNORE_RESULT(write(key_pipe[1], &ch, 1));
+									IGNORE_RESULT(write(key_pipe[1], &ch, 1));
+									return;
 								}
 							}
 							break;
@@ -2296,13 +2288,9 @@ x11_event(XEvent *ev)
 							uint16_t key=scan;
 							if (key < 128)
 								key = cpchar_from_unicode_cpoint(getcodepage(), key, key);
-							// Bow to GCC
 							if (key == 0xe0)
 								key = CIO_KEY_LITERAL_E0;
-							if (write(key_pipe[1], &key, (scan & 0xff) ? 1 : 2) != EXIT_SUCCESS)
-								return;
-							else
-								return;
+							IGNORE_RESULT(write(key_pipe[1], &key, (scan & 0xff) ? 1 : 2));
 						}
 						break;
 				}
diff --git a/src/syncterm/telnets.c b/src/syncterm/telnets.c
index 0e0f4e89c4..8e74b30706 100644
--- a/src/syncterm/telnets.c
+++ b/src/syncterm/telnets.c
@@ -41,7 +41,7 @@ telnets_input_thread(void *args)
 		if (!socket_readable(telnets_sock, 100))
 			continue;
 		pthread_mutex_lock(&telnets_mutex);
-		cryptFlushData(telnets_session);
+		IGNORE_RESULT(cryptFlushData(telnets_session));
 		status = cryptPopData(telnets_session, conn_api.rd_buf, conn_api.rd_buf_size, &rd);
 		pthread_mutex_unlock(&telnets_mutex);
                 // Handle case where there was socket activity without readable data (ie: rekey)
@@ -101,7 +101,7 @@ telnets_output_thread(void *args)
 			}
 			if (sent) {
 				pthread_mutex_lock(&telnets_mutex);
-				cryptFlushData(telnets_session);
+				IGNORE_RESULT(cryptFlushData(telnets_session));
 				pthread_mutex_unlock(&telnets_mutex);
 			}
 		}
diff --git a/src/xpdev/genwrap.h b/src/xpdev/genwrap.h
index d8dd96cfe9..57ba788198 100644
--- a/src/xpdev/genwrap.h
+++ b/src/xpdev/genwrap.h
@@ -48,6 +48,18 @@
 	#endif
 #endif
 
+#if defined(REALLY_GCC)
+	#define IGNORE_RESULT(x) do {                               \
+		_Pragma("GCC diagnostic push")                       \
+		_Pragma("GCC diagnostic ignored \"-Wunused-result\"") \
+		(void)x;                                               \
+		_Pragma("GCC diagnostic pop")                           \
+	} while(0)
+
+#else
+	#define IGNORE_RESULT(x) ((void)(x))
+#endif
+
 #if !defined(_WIN32)
 	/* Simple Win32 function equivalents */
 	#define GetCurrentProcessId()		getpid()
-- 
GitLab