Commit 5e0e378a for guacamole.apache.org

commit 5e0e378a1d0af1389afe6e6198b3acc51547bfdb
Author: Ciro Iriarte <ciro.iriarte@gmail.com>
Date:   Sat Oct 31 19:49:14 2026 -0300

    GUACAMOLE-2301: Adapt serial to guac_thread and guac_client_set_info.

    GUACAMOLE-2283 removed guacamole/proctitle.h from libguac. Threads are now
    created with guac_thread_create(), which names them, and the endpoint shown
    in guacd's process title is reported through guac_client_set_info(). Local
    devices and reverse-mode listeners are reported as the resource name, and
    outbound network connections as hostname and port.

    guac_thread tracks whether it was started, so the separate
    client_thread_valid flag is no longer needed.

    Also fixes early line breaks in the open() documentation of local.h,
    rfc2217.h and tcp.h.

diff --git a/src/protocols/serial/client.c b/src/protocols/serial/client.c
index d441fc60..e781d5ce 100644
--- a/src/protocols/serial/client.c
+++ b/src/protocols/serial/client.c
@@ -37,6 +37,7 @@
 #include <guacamole/mem.h>
 #include <guacamole/recording.h>
 #include <guacamole/socket.h>
+#include <guacamole/thread.h>

 /**
  * A pending join handler implementation that will synchronize the connection
@@ -117,12 +118,8 @@ int guac_serial_client_free_handler(guac_client* client) {
         guac_terminal_stop(serial_client->term);

     /* Wait for the client thread to fully exit before touching anything it
-     * uses. Joined only when it was successfully created, so early-failure
-     * setup paths neither leak the joinable thread nor join an invalid one. */
-    if (serial_client->client_thread_valid) {
-        pthread_join(serial_client->client_thread, NULL);
-        serial_client->client_thread_valid = 0;
-    }
+     * uses. This is a no-op if the thread was never started. */
+    guac_thread_join(&serial_client->client_thread, NULL);

     /* Clean up recording, if in progress */
     if (serial_client->recording != NULL)
diff --git a/src/protocols/serial/local.h b/src/protocols/serial/local.h
index 98a0e1ba..f8572516 100644
--- a/src/protocols/serial/local.h
+++ b/src/protocols/serial/local.h
@@ -29,9 +29,8 @@
  * Opens the local serial device described by the given settings, configuring
  * its termios line discipline (baud rate, data/stop bits, parity, and flow
  * control) for raw I/O, and stores the resulting file descriptor in the given
- * stream. On failure, the
- * stream's open_status is set and non-zero is returned; whether to retry is
- * left to the caller.
+ * stream. On failure, the stream's open_status is set and non-zero is
+ * returned; whether to retry is left to the caller.
  *
  * @param stream
  *     The serial stream to populate with the opened device.
diff --git a/src/protocols/serial/rfc2217.h b/src/protocols/serial/rfc2217.h
index 64810acc..d21f0459 100644
--- a/src/protocols/serial/rfc2217.h
+++ b/src/protocols/serial/rfc2217.h
@@ -29,9 +29,8 @@
  * Opens an RFC2217 (telnet COM-PORT-OPTION) connection to the network serial
  * server described by the given settings, negotiates the configured serial line
  * parameters, and stores the resulting socket and libtelnet session in the
- * given stream. On failure, the
- * stream's open_status is set and non-zero is returned; whether to retry is
- * left to the caller.
+ * given stream. On failure, the stream's open_status is set and non-zero is
+ * returned; whether to retry is left to the caller.
  *
  * If RFC2217 support was not compiled in, an error is logged, the stream's
  * open_status is set, and -1 is returned.
diff --git a/src/protocols/serial/serial.c b/src/protocols/serial/serial.c
index d4eee827..84f70fd8 100644
--- a/src/protocols/serial/serial.c
+++ b/src/protocols/serial/serial.c
@@ -29,9 +29,9 @@
 #include <guacamole/client.h>
 #include <guacamole/error.h>
 #include <guacamole/mem.h>
-#include <guacamole/proctitle.h>
 #include <guacamole/protocol.h>
 #include <guacamole/recording.h>
+#include <guacamole/thread.h>

 #include <errno.h>
 #include <poll.h>
@@ -271,10 +271,6 @@ static int guac_serial_translate_line_ending(guac_serial_line_ending line_ending
  */
 static void* guac_serial_input_thread(void* data) {

-    /* Thread name serial-stdin: reads terminal STDIN and forwards it to the
-     * serial line. */
-    guac_thread_name_set("serial-stdin");
-
     guac_client* client = (guac_client*) data;
     guac_serial_client* serial_client = (guac_serial_client*) client->data;
     guac_serial_settings* settings = serial_client->settings;
@@ -448,15 +444,11 @@ static int guac_serial_reconnect_wait(guac_client* client, int seconds) {

 void* guac_serial_client_thread(void* data) {

-    /* Thread name serial-worker: main serial client thread; runs the serial
-     * session and event loop. */
-    guac_thread_name_set("serial-worker");
-
     guac_client* client = (guac_client*) data;
     guac_serial_client* serial_client = (guac_serial_client*) client->data;
     guac_serial_settings* settings = serial_client->settings;

-    pthread_t input_thread;
+    guac_thread input_thread;

     /* Human-readable endpoint and "9600 8N1"-style line settings summary */
     char endpoint[256];
@@ -467,17 +459,19 @@ void* guac_serial_client_thread(void* data) {
             settings->baud_rate, settings->data_bits,
             guac_serial_parity_letter(settings->parity), settings->stop_bits);

-    /* Set process title to the device, listen endpoint, or hostname reached by
-     * this connection */
-    const char* title_host;
-    if (settings->type == GUAC_SERIAL_TYPE_LOCAL)
-        title_host = settings->device;
-    else if (settings->reverse_connect)
-        title_host = endpoint;
-    else
-        title_host = settings->hostname;
-    guac_process_title_set_endpoint(GUAC_SERIAL_PROCESS_TITLE_NAME,
-            NULL, title_host, NULL);
+    /* Describe the device, listen endpoint, or host:port reached by this
+     * connection */
+    if (settings->type == GUAC_SERIAL_TYPE_LOCAL || settings->reverse_connect) {
+        guac_client_set_info(client, &(guac_client_info) {
+            .resource_name = endpoint
+        });
+    }
+    else {
+        guac_client_set_info(client, &(guac_client_info) {
+            .hostname = settings->hostname,
+            .port = settings->port
+        });
+    }

     /* Set up screen recording, if requested */
     if (settings->recording_path != NULL) {
@@ -541,8 +535,8 @@ void* guac_serial_client_thread(void* data) {
     guac_client_for_owner(client, guac_serial_send_current_argv, serial_client);

     /* Start input thread (persists across reconnects) */
-    if (pthread_create(&input_thread, NULL, guac_serial_input_thread,
-            (void*) client)) {
+    if (guac_thread_create(&input_thread, guac_serial_input_thread,
+                (void*) client, "serial-stdin")) {
         guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
                 "Unable to start input thread");
         return NULL;
@@ -637,7 +631,7 @@ void* guac_serial_client_thread(void* data) {

     /* Kill client and wait for input thread to die */
     guac_client_stop(client);
-    pthread_join(input_thread, NULL);
+    guac_thread_join(&input_thread, NULL);

     guac_client_log(client, GUAC_LOG_INFO, "Serial connection ended.");
     return NULL;
diff --git a/src/protocols/serial/serial.h b/src/protocols/serial/serial.h
index 2963daa3..6fd67965 100644
--- a/src/protocols/serial/serial.h
+++ b/src/protocols/serial/serial.h
@@ -25,6 +25,7 @@
 #include "terminal/terminal.h"

 #include <guacamole/recording.h>
+#include <guacamole/thread.h>

 #include <pthread.h>

@@ -41,13 +42,7 @@ typedef struct guac_serial_client {
     /**
      * The serial client thread.
      */
-    pthread_t client_thread;
-
-    /**
-     * Whether client_thread has been successfully created and must therefore
-     * be joined during cleanup.
-     */
-    int client_thread_valid;
+    guac_thread client_thread;

     /**
      * The serial byte stream connected to the serial line, or NULL if no
diff --git a/src/protocols/serial/settings.h b/src/protocols/serial/settings.h
index 7ae6e8cc..85e00942 100644
--- a/src/protocols/serial/settings.h
+++ b/src/protocols/serial/settings.h
@@ -26,12 +26,6 @@
 #include <sys/types.h>
 #include <stdbool.h>

-/**
- * The protocol label included in the process title (the first argument passed
- * to guac_process_title_set_endpoint()), as seen in `ps`/`top`.
- */
-#define GUAC_SERIAL_PROCESS_TITLE_NAME "serial"
-
 /**
  * The default number of seconds to wait for a successful connection before
  * timing out.
diff --git a/src/protocols/serial/tcp.h b/src/protocols/serial/tcp.h
index 3a8120fb..9c67d2f6 100644
--- a/src/protocols/serial/tcp.h
+++ b/src/protocols/serial/tcp.h
@@ -28,9 +28,8 @@
 /**
  * Opens a raw TCP connection to the network serial server described by the
  * given settings (e.g. ser2net operating in raw mode) and stores the resulting
- * socket in the given stream. On failure, the
- * stream's open_status is set and non-zero is returned; whether to retry is
- * left to the caller.
+ * socket in the given stream. On failure, the stream's open_status is set and
+ * non-zero is returned; whether to retry is left to the caller.
  *
  * @param stream
  *     The serial stream to populate with the opened socket.
diff --git a/src/protocols/serial/user.c b/src/protocols/serial/user.c
index 2dce7dc4..531deb0f 100644
--- a/src/protocols/serial/user.c
+++ b/src/protocols/serial/user.c
@@ -31,6 +31,7 @@
 #include <guacamole/argv.h>
 #include <guacamole/client.h>
 #include <guacamole/socket.h>
+#include <guacamole/thread.h>
 #include <guacamole/user.h>

 #include <pthread.h>
@@ -62,16 +63,13 @@ int guac_serial_user_join_handler(guac_user* user, int argc, char** argv) {
         serial_client->settings = settings;

         /* Start client thread */
-        if (pthread_create(&(serial_client->client_thread), NULL,
-                    guac_serial_client_thread, (void*) client)) {
+        if (guac_thread_create(&serial_client->client_thread,
+                    guac_serial_client_thread, (void*) client, "serial-client")) {
             guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
                     "Unable to start serial client thread");
             return 1;
         }

-        /* Thread now owns cleanup responsibilities and must be joined */
-        serial_client->client_thread_valid = 1;
-
     }

     /* Only handle events if not read-only */