3

I am trying to stop the simple-httpd server with its command httpd-stop when I type the C-x C-c command (save-buffers-kill-terminal to quit emacs), cause I would like to get rid of the "Active processes exist; kill them and exit anyway? (yes or no)" message every time I type C-x C-c. To achieve my aim, I was thinking about writing a hook like:

(add-hook 'save-buffers-kill-terminal
                (lambda () (httpd-stop)
                    ))

But it did not work. I continue to get the message "Active processes exist; kill them and exit anyway? (yes or no)" when I type C-x C-c.

How can I achieve my goal?

Thanks!

phils
  • 71,335
  • 11
  • 153
  • 198
tonix
  • 6,671
  • 13
  • 75
  • 136

1 Answers1

4

There is no hook named save-buffers-kill-terminal.

There's a function by that name, but hooks don't automatically exist for every function (the advice mechanism does facilitate that in effect, but you don't need that here (edit: or maybe you do; see below)).

A hook only exists if there is code which explicitly runs it with run-hooks, or similar (e.g. C-u C-h a run.*hook RET). Or more specifically, you can add-hook with any arbitrary variable, but it will never function as a hook unless something runs it.

In general you would use either of kill-emacs-hook (if the callback does not need to interact with the user), or kill-emacs-query-functions if interaction could be necessary. See the help of each of those variables for details.

Edit:

In the case of active processes, a different mechanism is needed, as these queries happen before either of those hooks are run.

If you just want to avoid the query and let the process be killed, you can use set-process-query-on-exit-flag. This sets a per-process flag which determines whether or not this query will happen:

set-process-query-on-exit-flag is a built-in function in `process.c'.

(set-process-query-on-exit-flag PROCESS FLAG)

Specify if query is needed for PROCESS when Emacs is exited.
If the second argument FLAG is non-nil, Emacs will query the user before
exiting or killing a buffer if PROCESS is running.  This function
returns FLAG.

You would probably arrange this when you started the process (assuming you have some code which starts httpd), obtaining PROCESS with either (get-process NAME) or (get-buffer-process BUFFER). I'm not using this httpd library, so I don't know specifically what you'll need here.

If you definitely want to call a graceful shut-down function like httpd-stop, I think you'll need to do something custom.

(defadvice save-buffers-kill-emacs (before my-httpd-auto-stop)
  (when (httpd-is-running-p) ;; not a real predicate
    (httpd-stop)))
(ad-activate 'save-buffers-kill-emacs)

You'll have to figure out what to use in place of my hypothetical httpd-is-running-p, to establish whether or not to call the stop function.

Note that this would run before any other queries, so you might stop httpd this way but then decide not to kill emacs after all (but that sort of thing is possible regardless).

Edit: Alternatively, as it is apparently safe to call this stop function whether or not httpd is running, you could use the following (including an added test to see whether or not httpd-stop is defined, as calling it will be an error otherwise, and I'm not sure how you load the library):

(defadvice save-buffers-kill-emacs (before my-httpd-auto-stop)
  (when (fboundp 'httpd-stop)
    (httpd-stop)))
(ad-activate 'save-buffers-kill-emacs)
phils
  • 71,335
  • 11
  • 153
  • 198
  • Thank you for your response, I have tried this: `(add-hook 'kill-emacs-hook (lambda () (httpd-stop) ))` But it did not work, how can I run automatically httpd-stop when I type C-x C-c??? – tonix Dec 03 '13 at 18:06
  • Ah, tricky. The active processes query actually happens *before* either of these hooks are run. But I see there's a mechanism for this. I shall update the answer. – phils Dec 03 '13 at 20:42
  • Thank you for your attention, I have found this [link](http://stackoverflow.com/questions/2706527/make-emacs-stop-asking-active-processes-exist-kill-them-and-exit-anyway) But I do not want to auto kill all the processes, just the simple-httpd server... – tonix Dec 03 '13 at 21:06
  • `(when (httpd-is-running-p) (httpd-stop)))` -> I have changed it in this: `(if t httpd-stop)))` Cause the **httpd-stop** function does nothing if the server has already been stopped, so it runs httpd-stop every time. I can do something like that, can't I? I guess I can. – tonix Dec 05 '13 at 20:23
  • Sure, but the code in your comment has wrong/unbalanced parentheses, and in any case an `if` or `when` with condition `t` is fairly pointless, so just call `(httpd-stop)` on its own. Note that if this function is not autoloaded, you would either need to ensure that the library is loaded, or else instead use `(when (fboundp 'httpd-stop) (httpd-stop))` so that it only calls the function if it is defined. – phils Dec 05 '13 at 21:09
  • Sorry phils, what does fboundp do? – tonix Dec 05 '13 at 21:39
  • Type: `C-h f fboundp RET`. The same applies for any (loaded or autoloaded) elisp function. – phils Dec 05 '13 at 21:43
  • Thank you for your responses phils, you really help me! It works! – tonix Dec 05 '13 at 21:58