bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#30421: 25.3; desktop.el: Steal lock when no living "emacs" process o


From: Pierre Neidhardt
Subject: bug#30421: 25.3; desktop.el: Steal lock when no living "emacs" process owns it
Date: Sun, 18 Feb 2018 12:26:06 +0100
User-agent: mu4e 1.0; emacs 26.0.91

Did not work.  Recipe:

- init.el:

        (require 'desktop)
        
        (defun desktop-read (&optional dirname)
          "Read and process the desktop file in directory DIRNAME.
        Look for a desktop file in DIRNAME, or if DIRNAME is omitted, look in
        directories listed in `desktop-path'.  If a desktop file is found, it
        is processed and `desktop-after-read-hook' is run.  If no desktop file
        is found, clear the desktop and run `desktop-no-desktop-file-hook'.
        This function is a no-op when Emacs is running in batch mode.
        It returns t if a desktop file was loaded, nil otherwise."
          (interactive)
          (unless noninteractive
            (setq desktop-dirname
                  (file-name-as-directory
                   (expand-file-name
                    (or
                     ;; If DIRNAME is specified, use it.
                     (and (< 0 (length dirname)) dirname)
                     ;; Otherwise search desktop file in desktop-path.
                     (let ((dirs desktop-path))
                       (while (and dirs
                                   (not (file-exists-p
                                         (desktop-full-file-name (car dirs)))))
                         (setq dirs (cdr dirs)))
                       (and dirs (car dirs)))
                     ;; If not found and `desktop-path' is non-nil, use its 
first element.
                     (and desktop-path (car desktop-path))
                     ;; Default: .emacs.d.
                     user-emacs-directory))))
            (if (file-exists-p (desktop-full-file-name))
                ;; Desktop file found, but is it already in use?
                (let ((desktop-first-buffer nil)
                      (desktop-buffer-ok-count 0)
                      (desktop-buffer-fail-count 0)
                      (owner (desktop-owner))
                      ;; Avoid desktop saving during evaluation of desktop 
buffer.
                      (desktop-save nil)
                      (desktop-autosave-was-enabled))
                  (if (and owner
                           (memq desktop-load-locked-desktop '(nil ask))
                           (or (null desktop-load-locked-desktop)
                               ;; Without a visible frame, Emacs daemon cannot
                               ;; prompt the user so we don't load.
                               (and (daemonp) (= (length (visible-frame-list)) 
1))
                               (not (y-or-n-p (format "Warning: desktop file 
appears to be in use by PID %s.\n\
        Using it may cause conflicts.  Use it anyway? " owner)))))
                      (let ((default-directory desktop-dirname))
                        (setq desktop-dirname nil)
                        (run-hooks 'desktop-not-loaded-hook)
                        (unless desktop-dirname
                          (message "Desktop file in use; not loaded.")))
                    (desktop-lazy-abort)
                    ;; Temporarily disable the autosave that will leave it
                    ;; disabled when loading the desktop fails with errors,
                    ;; thus not overwriting the desktop with broken contents.
                    (setq desktop-autosave-was-enabled
                          (memq 'desktop-auto-save-set-timer 
(default-toplevel-value 'window-configuration-change-hook)))
                    (desktop-auto-save-disable)
                    ;; Evaluate desktop buffer and remember when it was 
modified.
                    (load (desktop-full-file-name) t t t)
                    (setq desktop-file-modtime (nth 5 (file-attributes 
(desktop-full-file-name))))
                    ;; If it wasn't already, mark it as in-use, to bother other
                    ;; desktop instances.
                    (unless (eq (emacs-pid) owner)
                      (condition-case nil
                          (desktop-claim-lock)
                        (file-error (message "Couldn't record use of desktop 
file")
                                    (sit-for 1))))
        
                    (unless (desktop-restoring-frameset-p)
                      ;; `desktop-create-buffer' puts buffers at end of the 
buffer list.
                      ;; We want buffers existing prior to evaluating the 
desktop (and
                      ;; not reused) to be placed at the end of the buffer 
list, so we
                      ;; move them here.
                      (mapc 'bury-buffer
                            (nreverse (cdr (memq desktop-first-buffer (nreverse 
(buffer-list))))))
                      (switch-to-buffer (car (buffer-list))))
                    (run-hooks 'desktop-delay-hook)
                    (setq desktop-delay-hook nil)
                    (desktop-restore-frameset)
                    (run-hooks 'desktop-after-read-hook)
                    (message "Desktop: %s%d buffer%s restored%s%s."
                             (if desktop-saved-frameset
                                 (let ((fn (length (frameset-states 
desktop-saved-frameset))))
                                   (format "%d frame%s, "
                                           fn (if (= fn 1) "" "s")))
                               "")
                             desktop-buffer-ok-count
                             (if (= 1 desktop-buffer-ok-count) "" "s")
                             (if (< 0 desktop-buffer-fail-count)
                                 (format ", %d failed to restore" 
desktop-buffer-fail-count)
                               "")
                             (if desktop-buffer-args-list
                                 (format ", %d to restore lazily"
                                         (length desktop-buffer-args-list))
                               ""))
                    (unless (desktop-restoring-frameset-p)
                      ;; Bury the *Messages* buffer to not reshow it when 
burying
                      ;; the buffer we switched to above.
                      (when (buffer-live-p (get-buffer "*Messages*"))
                        (bury-buffer "*Messages*"))
                      ;; Clear all windows' previous and next buffers, these 
have
                      ;; been corrupted by the `switch-to-buffer' calls in
                      ;; `desktop-restore-file-buffer' (bug#11556).  This is a
                      ;; brute force fix and should be replaced by a more subtle
                      ;; strategy eventually.
                      (walk-window-tree (lambda (window)
                                          (set-window-prev-buffers window nil)
                                          (set-window-next-buffers window 
nil))))
                    (setq desktop-saved-frameset nil)
                    (if desktop-autosave-was-enabled (desktop-auto-save-enable))
                    t))
              ;; No desktop file found.
              (let ((default-directory desktop-dirname))
                (run-hooks 'desktop-no-desktop-file-hook))
              (message "No desktop file.")
              nil)))
        
        (when (daemonp)
          (defun ambrevar/desktop-init (frame)
            (when (frame-parameter frame 'client)
              (desktop-save-mode)
              (desktop-read)
              (remove-hook 'after-make-frame-functions 'ambrevar/desktop-init)))
          (add-hook 'after-make-frame-functions 'ambrevar/desktop-init))

- Leave a ~/.emacs.d/.emacs.desktop behind.
- Kill all emacs instances.
- `echo 0 > ~/.emacs.d/.emacs.desktop.lock`
- Optional: Switch to a TTY.
- Start `emacsclient -a '' -t` or `emacsclient -a '' -c` if not in a TTY.
- Emacs gives a blank screen (with a blinking cursor in a TTY). Press `n`.
- See the *Messages* buffer: the `n` was answering the desktop question.

Attachment: signature.asc
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]