This is an automated email from the git hooks/post-receive script.

git pushed a commit to branch tymux
in repository terminology.

View the commit online.

commit 13031233df25556c0838f29e43d3ac5900bc0103
Author: [email protected] <[email protected]>
AuthorDate: Sun Mar 15 18:01:15 2026 -0600

    feat: add termsrv.h header for tymux session recovery IPC
    
    Defines the shared memory and messaging protocol for the tymux feature,
    which allows recovering disconnected Terminology sessions. Includes:
    
    - TermShmHeader: memfd-backed screen buffer layout with atomic sequence
      numbers for lock-free client-server synchronization
    - TermSrvMsgType enum: 9 message types for attach, detach, input,
      resize, notifications, title, bell, and session exit events
    - Message structs: type-safe payload definitions for IPC communication
    - Helper declarations: socket path functions and message I/O primitives
    
    Linux-only feature gated with HAVE_TYMUX.
    
    Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
---
 src/bin/termsrv.h | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 137 insertions(+)

diff --git a/src/bin/termsrv.h b/src/bin/termsrv.h
new file mode 100644
index 00000000..0ba4ee9b
--- /dev/null
+++ b/src/bin/termsrv.h
@@ -0,0 +1,137 @@
+#ifndef TERMINOLOGY_TERMSRV_H_
+#define TERMINOLOGY_TERMSRV_H_
+
+#include "config.h"
+
+#ifdef HAVE_TYMUX
+
+#include <stdint.h>
+#include <stdatomic.h>
+#include <stddef.h>
+#include "termpty.h"  /* Termcell */
+
+/* ── shared memory ──────────────────────────────────────────────── */
+
+#define TERMSRV_SHM_MAGIC    0x544D5348u  /* "TMSH" */
+#define TERMSRV_SHM_VERSION  1u
+#define TERMSRV_MAX_COLS     500
+#define TERMSRV_MAX_ROWS     200
+
+/*
+ * Header occupies the first 4096 bytes (one page) of the memfd.
+ * Cells follow at TERMSRV_SHM_HEADER_SIZE, in display order (row 0 = top).
+ * Client reads write_seq with ACQUIRE; server stores with RELEASE.
+ */
+typedef struct {
+    uint32_t          magic;
+    uint32_t          version;
+    uint32_t          cols;
+    uint32_t          rows;
+    uint32_t          cursor_x;
+    uint32_t          cursor_y;
+    uint8_t           cursor_visible;
+    uint8_t           _pad[7];
+    _Atomic uint64_t  write_seq;
+} TermShmHeader;
+
+#define TERMSRV_SHM_HEADER_SIZE  4096u
+#define TERMSRV_SHM_CELLS_SIZE   \
+    ((size_t)TERMSRV_MAX_COLS * TERMSRV_MAX_ROWS * sizeof(Termcell))
+#define TERMSRV_SHM_TOTAL_SIZE   \
+    (TERMSRV_SHM_HEADER_SIZE + TERMSRV_SHM_CELLS_SIZE)
+
+#define TERMSRV_SHM_CELLS(shm_ptr) \
+    ((Termcell *)((uint8_t *)(shm_ptr) + TERMSRV_SHM_HEADER_SIZE))
+
+/* ── IPC messages ───────────────────────────────────────────────── */
+
+typedef enum {
+    TSRV_MSG_ATTACH   = 1, /* client → server: attach to this session        */
+    TSRV_MSG_ATTACHED = 2, /* server → client: cols/rows + memfd via SCM_RIGHTS */
+    TSRV_MSG_DETACH   = 3, /* client → server: clean disconnect               */
+    TSRV_MSG_INPUT    = 4, /* client → server: raw PTY bytes                  */
+    TSRV_MSG_RESIZE   = 5, /* client → server: new cols/rows                  */
+    TSRV_MSG_NOTIFY   = 6, /* server → client: write_seq updated              */
+    TSRV_MSG_TITLE    = 7, /* server → client: new window title               */
+    TSRV_MSG_BELL     = 8, /* server → client: BEL                           */
+    TSRV_MSG_EXIT     = 9, /* server → client: session ended, exit code       */
+} TermSrvMsgType;
+
+/* Every message starts with this 8-byte header */
+typedef struct {
+    uint32_t type;   /* TermSrvMsgType */
+    uint32_t size;   /* payload bytes after this header */
+} TermSrvMsgHdr;
+
+/* ATTACHED payload (memfd via SCM_RIGHTS alongside this) */
+typedef struct {
+    uint32_t cols;
+    uint32_t rows;
+} TermSrvMsgAttached;
+
+/* RESIZE payload */
+typedef struct {
+    uint32_t cols;
+    uint32_t rows;
+} TermSrvMsgResize;
+
+/* NOTIFY payload */
+typedef struct {
+    uint64_t write_seq;
+} TermSrvMsgNotify;
+
+/* EXIT payload */
+typedef struct {
+    int32_t exit_code;
+} TermSrvMsgExit;
+
+/* ── session name ───────────────────────────────────────────────── */
+
+/* Maximum length of a session name (excluding null terminator).
+ * Must be safe as a filename component. */
+#define TSRV_MAX_SESSION_NAME 64
+
+/* ── socket paths ───────────────────────────────────────────────── */
+
+/*
+ * Fill buf with the socket path for a named session:
+ *   $XDG_RUNTIME_DIR/terminology/tymux/<name>.sock
+ * Falls back to /tmp if XDG_RUNTIME_DIR is unset.
+ * Returns 0 on success, -1 if buf too small or name contains '/'.
+ */
+int termsrv_socket_path(const char *session_name, char *buf, size_t bufsz);
+
+/*
+ * Fill buf with the sessions directory path:
+ *   $XDG_RUNTIME_DIR/terminology/tymux
+ * Returns 0 on success, -1 if buf too small.
+ */
+int termsrv_sessions_dir(char *buf, size_t bufsz);
+
+/*
+ * Create $XDG_RUNTIME_DIR/terminology/tymux/ (and parents) if absent.
+ * Returns 0 on success, -1 on error (errno set).
+ */
+int termsrv_ensure_sessions_dir(void);
+
+/* ── message I/O ────────────────────────────────────────────────── */
+
+/* Send header + payload over a blocking socket fd. Returns 0/-1. */
+int termsrv_msg_send(int fd, TermSrvMsgType type,
+                     const void *payload, uint32_t size);
+
+/* Receive a message. *payload_out is malloc'd; caller must free().
+ * Returns msg type (>0) on success, -1 on EOF/error.
+ * *payload_out is NULL and *size_out is 0 when there is no payload. */
+int termsrv_msg_recv(int fd, void **payload_out, uint32_t *size_out);
+
+/* Send ATTACHED with memfd via SCM_RIGHTS. Returns 0/-1. */
+int termsrv_send_attached(int sock_fd, int shm_fd,
+                          uint32_t cols, uint32_t rows);
+
+/* Receive ATTACHED and extract the shm fd. Returns 0/-1. */
+int termsrv_recv_attached(int sock_fd, int *shm_fd_out,
+                          uint32_t *cols_out, uint32_t *rows_out);
+
+#endif /* HAVE_TYMUX */
+#endif /* TERMINOLOGY_TERMSRV_H_ */

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to