From 4bb6dec25ad3c3b548e18e82b2129b53c1ee1b69 Mon Sep 17 00:00:00 2001 From: Robert Pluim Date: Tue, 25 Apr 2023 12:48:26 +0200 Subject: [PATCH] Allow zero-length UDP send/receive To: emacs-devel@gnu.org * src/process.c (wait_reading_process_output) [DATAGRAM_SOCKETS]: Don't close the network connection if we receive a zero-length UDP packet. (send_process) [DATAGRAM_SOCKETS]: Allow sending a zero-length UDP packet. * etc/NEWS: Announce the change. --- etc/NEWS | 8 ++++++++ src/process.c | 16 ++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index ea233865f5a..4cc02d76b8f 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -82,6 +82,14 @@ The ':keepalive-idle', ':keepalive-interval', and ':keepalive-count' options can now be used to set the various timers and counters used when TCP keepalive is enabled for a connection. +** Emacs can now send zero-length UDP packets. +Previously 'process-send-string' of an empty string to a UDP process +did nothing, now it sends out a zero-length UDP packet. + +** Emacs can now receive zero-length UDP packets. +Previously, receiving a zero-length UDP packet closed the receiving +network process. They are now silently ignored. + * Editing Changes in Emacs 30.1 diff --git a/src/process.c b/src/process.c index 8e467ff7511..e3233f5ad89 100644 --- a/src/process.c +++ b/src/process.c @@ -5947,6 +5947,11 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, #endif /* HAVE_PTYS */ /* If we can detect process termination, don't consider the process gone just because its pipe is closed. */ +#ifdef DATAGRAM_SOCKETS + /* A zero byte read on a UDP socket is not an error. */ + else if (nread == 0 && DATAGRAM_CHAN_P (channel)) + got_some_output = 1; +#endif else if (nread == 0 && !NETCONN_P (proc) && !SERIALCONN_P (proc) && !PIPECONN_P (proc)) ; @@ -6616,9 +6621,16 @@ send_process (Lisp_Object proc, const char *buf, ptrdiff_t len, cur_buf = buf; cur_object = object; } - - while (cur_len > 0) + /* UDP allows zero-length writes. */ + bool zero_length = false; +#ifdef DATAGRAM_SOCKETS + if (cur_len == 0 && NETCONN_P (proc) && 0 <= p->outfd + && DATAGRAM_CHAN_P (p->outfd)) + zero_length = true; +#endif + while (cur_len > 0 || zero_length) { + zero_length = false; /* Send this batch, using one or more write calls. */ ptrdiff_t written = 0; int outfd = p->outfd; -- 2.38.1.420.g319605f8f0