From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Karl Fogel Newsgroups: gmane.emacs.devel Subject: PROPOSAL: Control over process cleanup in `save-buffers-kill-emacs'. Date: Fri, 22 Sep 2017 13:58:41 -0500 Message-ID: <87poai36hq.fsf@red-bean.com> Reply-To: Karl Fogel NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: blaine.gmane.org 1506106731 12077 195.159.176.226 (22 Sep 2017 18:58:51 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Fri, 22 Sep 2017 18:58:51 +0000 (UTC) To: Emacs Development Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Fri Sep 22 20:58:48 2017 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dvT9z-0002tf-EP for ged-emacs-devel@m.gmane.org; Fri, 22 Sep 2017 20:58:47 +0200 Original-Received: from localhost ([::1]:60632 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dvTA6-00060k-P7 for ged-emacs-devel@m.gmane.org; Fri, 22 Sep 2017 14:58:54 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:37937) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dvT9z-00060N-M3 for emacs-devel@gnu.org; Fri, 22 Sep 2017 14:58:49 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dvT9w-0006vu-KH for emacs-devel@gnu.org; Fri, 22 Sep 2017 14:58:47 -0400 Original-Received: from mail-it0-x22c.google.com ([2607:f8b0:4001:c0b::22c]:44770) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1dvT9w-0006vk-E7 for emacs-devel@gnu.org; Fri, 22 Sep 2017 14:58:44 -0400 Original-Received: by mail-it0-x22c.google.com with SMTP id d192so1772082itd.1 for ; Fri, 22 Sep 2017 11:58:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:subject:reply-to:date:message-id:mime-version; bh=JwotvS3P4EBpWQgcnhUs+HdebG367zVBjyZP+bMAY6c=; b=QF7twIyUcOAwfmY001UFq1tlJkqY8Nek4F40VujrK8tcjxHnivk72jg5bf96/L+hNR K4q+x6jy9tLgKirBHuOgPki66YWyIuRW7sGYiJufhRNWP1h/9DN0rq2BHrbX/s/AA0s8 EyQ4Y3/sdmRgoTGVKJ89xRrrkyGGIkAQ9TWGXjHRg70wKDMH/gPyA0JsS/6zheulbSn7 cgt91/ehanjCzb/27LSt9w3JqgLL6xM9QO3gfVDxduK6DHAmuRMkjuiVW3oJTbS9Pz56 eJ8/gCyg5AT9QXGi+ZgsE4AfRHw2EYIztcU39W63rFBXxpSc4WctiFb7wxoM3msojtWh xGxg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:subject:reply-to:date:message-id :mime-version; bh=JwotvS3P4EBpWQgcnhUs+HdebG367zVBjyZP+bMAY6c=; b=PhCJgGBL3aEOLAHXQC/mqRFUewcsJp1ZAQcuu80l4fCVJkah7qcLIqBPNuW44hFxdx fk3q4iPe912XsKv1zfiiymKH5oW8DYN5uq4X3LUtXptu3uLHLBZ/0IwYGLBH3ibunjs1 GA5DEJ4jpY9MBlVI38PBYAh/1h4rr5rXw6AOwGSqVfGAYRfsF8ZoU6yLofnraGPD4CHW /oojPQiWZ1hfLpbHz2n6WToowiX8e1JrD4p7qM3pQfbETy7QOBzjk6v1nCthuebjIL52 km6kngCoHHpQlRGXHe0j84IrlmyjhiW3lzWP4hWPRLB9FmHdbn+1dnoBpOJaJVkWrG7h vlNQ== X-Gm-Message-State: AHPjjUjEA5VbHrCmM2WHnAI04WaW45Je1ZadYdOzkriRAYS9vU+Ni3bQ rFQj03TkAccOUgVxzLmfsHMfmQ== X-Google-Smtp-Source: AOwi7QDv7EbQ6fr+Ut8oUpiXcwB4BVW8RQ0R4JCu5LyYpirocvtD56LWQoExTY5cPKmveMOKXGf6Qw== X-Received: by 10.36.121.14 with SMTP id z14mr7711242itc.87.1506106723167; Fri, 22 Sep 2017 11:58:43 -0700 (PDT) Original-Received: from kwork (74-92-190-114-Illinois.hfc.comcastbusiness.net. [74.92.190.114]) by smtp.gmail.com with ESMTPSA id v188sm235378itb.24.2017.09.22.11.58.42 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 22 Sep 2017 11:58:42 -0700 (PDT) X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4001:c0b::22c X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:218697 Archived-At: In `save-buffers-kill-emacs' in files.el, we check for active processes -- the familiar "Active processes exist; kill them and exit anyway? " query -- and then only at the very end of the function do we run `kill-emacs-query-functions' and call `kill-emacs' (which then runs the hooks in `kill-emacs-hook' of course). This means that neither `kill-emacs-query-functions' nor `kill-emacs-hook' happen in time to offer any fine-grained control over whether the user gets queried about active processes. And since the `confirm-kill-processes' flag applies to all processes, one can't use it to customize *which* processes one is queried about at exit time. I propose moving `kill-emacs-query-functions' to before the process-killing block, so that hooks can do things with processes before Emacs asks about those processes. I haven't tested this patch yet, but this gives the idea: --- lisp/files.el +++ lisp/files.el @@ -6875,6 +6875,7 @@ save-buffers-kill-emacs (buffer-list)))) (progn (setq confirm nil) (yes-or-no-p "Modified buffers exist; exit anyway? "))) + (run-hook-with-args-until-failure 'kill-emacs-query-functions) (or (not (fboundp 'process-list)) ;; process-list is not defined on MSDOS. (not confirm-kill-processes) @@ -6897,8 +6898,6 @@ save-buffers-kill-emacs (when (window-live-p window) (quit-restore-window window 'kill))))) (list-processes t))))) - ;; Query the user for other things, perhaps. - (run-hook-with-args-until-failure 'kill-emacs-query-functions) (or (null confirm) (funcall confirm "Really exit Emacs? ")) (kill-emacs)))) Justification: Sometimes there are expected processes that one knows it's okay to kill at exit time, but one would prefer to be queried about any unexpected processes (perhaps there is a long-running job that one forgot about, and one would answer "no" to exiting Emacs if one were reminded about that job). For example, I just started using IMAP (instead of local spool source) to fetch email into Gnus. Since I'm querying two separate IMAP servers, there are two separate IMAP buffers each with its own process. When I exit Emacs, I do not need to be queried about those process buffers -- I know it's okay for Emacs to kill the processes. But I can't easily do `set-process-query-on-exit-flag' at the time the IMAP processes are started, since I just run `M-x gnus' and then somewhen after that something runs IMAP (maybe there's a hook for this somewhere, but if so, I haven't found it yet). But I could put code like this into a hook, if only there were a hook that were run before the process-killing block in `save-buffers-kill-emacs': (mapcar (lambda (buf) (when (string-match "^ \\*imap source\\*.*" (buffer-name buf)) (message "shutting down IMAP process '%s'" (get-buffer-process buf)) (set-process-query-on-exit-flag (get-buffer-process buf) nil) (kill-buffer buf))) (buffer-list)) I think it would be generally useful to offer the ability to have custom process cleanup at exit time. My only reservation about the change is that the hook name `kill-emacs-query-functions' perhaps becomes even less accurate (though it is already potentially inaccurate, depending on how people are using it). In fact, my personal use would be in order to *avoid* some queries, not to perform any new queries. But for all I know, people are already using that hook to do things that have nothing to do with queries, so maybe moving it earlier doesn't add to the problem. (A further possibility is to put the hook call at the very beginning of the function, even before the big `let', so that the hooks is run even before the "Modified buffers exist; exit anyway? " check. I'm not sure whether that would be useful or not; since I don't have a concrete use case for it, I'm not pushing for it here.) For reference, here's the entire function as it stands right now, current tip (commit 908af46abdb) of the "emacs-26" branch: (defun save-buffers-kill-emacs (&optional arg) "Offer to save each buffer, then kill this Emacs process. With prefix ARG, silently save all file-visiting buffers without asking. If there are active processes where `process-query-on-exit-flag' returns non-nil and `confirm-kill-processes' is non-nil, asks whether processes should be killed. Runs the members of `kill-emacs-query-functions' in turn and stops if any returns nil. If `confirm-kill-emacs' is non-nil, calls it." (interactive "P") ;; Don't use save-some-buffers-default-predicate, because we want ;; to ask about all the buffers before killing Emacs. (save-some-buffers arg t) (let ((confirm confirm-kill-emacs)) (and (or (not (memq t (mapcar (function (lambda (buf) (and (buffer-file-name buf) (buffer-modified-p buf)))) (buffer-list)))) (progn (setq confirm nil) (yes-or-no-p "Modified buffers exist; exit anyway? "))) (or (not (fboundp 'process-list)) ;; process-list is not defined on MSDOS. (not confirm-kill-processes) (let ((processes (process-list)) active) (while processes (and (memq (process-status (car processes)) '(run stop open listen)) (process-query-on-exit-flag (car processes)) (setq active t)) (setq processes (cdr processes))) (or (not active) (with-current-buffer-window (get-buffer-create "*Process List*") nil #'(lambda (window _value) (with-selected-window window (unwind-protect (progn (setq confirm nil) (yes-or-no-p "Active processes exist; kill them and exit anyway? ")) (when (window-live-p window) (quit-restore-window window 'kill))))) (list-processes t))))) ;; Query the user for other things, perhaps. (run-hook-with-args-until-failure 'kill-emacs-query-functions) (or (null confirm) (funcall confirm "Really exit Emacs? ")) (kill-emacs)))) Thoughts, -Karl