]> git.eshelyaron.com Git - sweep.git/commitdiff
Handle SIGHUP in daemon mode when killing a tty top-level
authorEshel Yaron <me@eshelyaron.com>
Thu, 9 Nov 2023 19:47:57 +0000 (20:47 +0100)
committerEshel Yaron <me@eshelyaron.com>
Thu, 9 Nov 2023 19:47:57 +0000 (20:47 +0100)
When Emacs is running as a daemon, and deletes the process of a
top-level that uses a tty, the top-level receives SIGHUP.  But since
the top-level is a thread is the same process as Emacs itself, this
results in 'kill-emacs'.  To prevent this unfortunate outcome, set a
no-op handler for SIGHUP before deleting the top-level process and
restore the original handler afterwards.

* sweep.pl (sweep_nohup/2): New predicate.
* sweeprolog.el (sweeprolog-top-level-filter): New function.
(sweeprolog-top-level-buffer): Use it.

sweep.pl
sweeprolog.el

index 954b3b501af703586f12c470004000c50334bf64..51ebf4d48d6e2ac74ed2ed34bd9ff10fbed0cdcd 100644 (file)
--- a/sweep.pl
+++ b/sweep.pl
             sweep_options_collection/2,
             sweep_option_arguments_collection/2,
             sweep_functions_collection/2,
-            sweep_function_functors_collection/2
+            sweep_function_functors_collection/2,
+            sweep_nohup/2
           ]).
 
 :- use_module(library(pldoc)).
@@ -2179,3 +2180,6 @@ sweep_extract_lambda_1(Clause, ClauseVarNames, Func, Shared, Args, GoalPos, Offs
     ->  Exists = "true"
     ;   Exists = []
     ).
+
+sweep_nohup(1, _) :- on_signal(hup, _, atom).
+sweep_nohup(0, _) :- on_signal(hup, _, default).
index 3387a0fdd53d5194d3273e5a9c10b63f591344d1..02246c65e10c3a6ef1d75e4edaac9e1fc761c7c5 100644 (file)
@@ -3415,6 +3415,19 @@ function with PROC and MSG."
                           #'sweeprolog-top-level-sentinel)
     (add-hook 'kill-buffer-hook #'comint-write-input-ring nil t)))
 
+(defun sweeprolog-top-level-filter (process string)
+  (let ((sweeprolog-top-level-output-filter t))
+    (comint-output-filter process string))
+  (when (string-match (rx "Sweep top-level thread exited") string)
+    (with-current-buffer (process-buffer process)
+      (setq sweeprolog-top-level-thread-id nil))
+    (if (or (eq (process-type process) 'network)
+            (not (daemonp)))
+        (delete-process process)
+      (sweeprolog--query-once "sweep" "sweep_nohup" 1)
+      (delete-process process)
+      (sweeprolog--query-once "sweep" "sweep_nohup" 0))))
+
 (defun sweeprolog-top-level-buffer (&optional name)
   "Return a Prolog top-level buffer named NAME.
 
@@ -3447,14 +3460,7 @@ top-level."
                                              sweeprolog-prolog-server-port))
                 (sweeprolog--query-once "sweep" "sweep_accept_top_level_client" nil)))
         (let ((proc (get-buffer-process buf)))
-          (set-process-filter proc
-                              (lambda (process string)
-                                (let ((sweeprolog-top-level-output-filter t))
-                                  (comint-output-filter process string))
-                                (when (string-match (rx "Sweep top-level thread exited") string)
-                                  (delete-process process)
-                                  (with-current-buffer buf
-                                    (setq sweeprolog-top-level-thread-id nil)))))
+          (set-process-filter proc #'sweeprolog-top-level-filter)
           (unless comint-last-prompt buf (accept-process-output proc 1))
           (set-process-query-on-exit-flag proc nil)
           (setq-local comint-input-ring-file-name