nt/cmdproxy.c (main): Use _snprintf instead of wsprintf (bug#6647).
[bpt/emacs.git] / lisp / server.el
CommitLineData
55535639 1;;; server.el --- Lisp code for GNU Emacs running as server process
c88ab9ce 2
0d30b337 3;; Copyright (C) 1986, 1987, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
114f9c96 4;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
e6ce8c42 5;; Free Software Foundation, Inc.
6d74b528 6
630cc463 7;; Author: William Sommerfeld <wesommer@athena.mit.edu>
e4874521 8;; Maintainer: FSF
d7b4d18f 9;; Keywords: processes
630cc463 10
9ae0f972 11;; Changes by peck@sun.com and by rms.
35dfa9b6 12;; Overhaul by Karoly Lorentey <lorentey@elte.hu> for multi-tty support.
9ae0f972 13
14;; This file is part of GNU Emacs.
15
eb3fa2cf 16;; GNU Emacs is free software: you can redistribute it and/or modify
9ae0f972 17;; it under the terms of the GNU General Public License as published by
eb3fa2cf
GM
18;; the Free Software Foundation, either version 3 of the License, or
19;; (at your option) any later version.
9ae0f972 20
21;; GNU Emacs is distributed in the hope that it will be useful,
22;; but WITHOUT ANY WARRANTY; without even the implied warranty of
23;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24;; GNU General Public License for more details.
25
26;; You should have received a copy of the GNU General Public License
eb3fa2cf 27;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
9ae0f972 28
630cc463 29;;; Commentary:
9ae0f972 30
b578f267
EN
31;; This Lisp code is run in Emacs when it is to operate as
32;; a server for other processes.
9ae0f972 33
b578f267 34;; Load this library and do M-x server-edit to enable Emacs as a server.
44a56b29
SM
35;; Emacs opens up a socket for communication with clients. If there are no
36;; client buffers to edit, server-edit acts like (switch-to-buffer
37;; (other-buffer))
9ae0f972 38
b578f267
EN
39;; When some other program runs "the editor" to edit a file,
40;; "the editor" can be the Emacs client program ../lib-src/emacsclient.
41;; This program transmits the file names to Emacs through
42;; the server subprocess, and Emacs visits them and lets you edit them.
9ae0f972 43
6d3a46f7 44;; Note that any number of clients may dispatch files to Emacs to be edited.
9ae0f972 45
b578f267 46;; When you finish editing a Server buffer, again call server-edit
64f51134
JPW
47;; to mark that buffer as done for the client and switch to the next
48;; Server buffer. When all the buffers for a client have been edited
b578f267 49;; and exited with server-edit, the client "editor" will return
64f51134 50;; to the program that invoked it.
9ae0f972 51
b578f267
EN
52;; Your editing commands and Emacs's display output go to and from
53;; the terminal in the usual way. Thus, server operation is possible
54;; only when Emacs can talk to the terminal at the time you invoke
55;; the client. This is possible in four cases:
9ae0f972 56
b578f267
EN
57;; 1. On a window system, where Emacs runs in one window and the
58;; program that wants to use "the editor" runs in another.
9ae0f972 59
b578f267
EN
60;; 2. On a multi-terminal system, where Emacs runs on one terminal and the
61;; program that wants to use "the editor" runs on another.
9ae0f972 62
b578f267
EN
63;; 3. When the program that wants to use "the editor" is running
64;; as a subprocess of Emacs.
9ae0f972 65
b578f267
EN
66;; 4. On a system with job control, when Emacs is suspended, the program
67;; that wants to use "the editor" will stop and display
68;; "Waiting for Emacs...". It can then be suspended, and Emacs can be
69;; brought into the foreground for editing. When done editing, Emacs is
70;; suspended again, and the client program is brought into the foreground.
9ae0f972 71
64f51134
JPW
72;; The buffer local variable "server-buffer-clients" lists
73;; the clients who are waiting for this buffer to be edited.
b578f267
EN
74;; The global variable "server-clients" lists all the waiting clients,
75;; and which files are yet to be edited for each.
630cc463 76
0acb1916
SM
77;; Todo:
78
79;; - handle command-line-args-left.
80;; - move most of the args processing and decision making from emacsclient.c
81;; to here.
82;; - fix up handling of the client's environment (place it in the terminal?).
83
630cc463 84;;; Code:
8b3e840e
SM
85
86(eval-when-compile (require 'cl))
87
ab1c7f35
RS
88(defgroup server nil
89 "Emacs running as a server process."
90 :group 'external)
91
337e3c70
JB
92(defcustom server-use-tcp nil
93 "If non-nil, use TCP sockets instead of local sockets."
94 :set #'(lambda (sym val)
95 (unless (featurep 'make-network-process '(:family local))
96 (setq val t)
97 (unless load-in-progress
98 (message "Local sockets unsupported, using TCP sockets")))
99 (when val (random t))
100 (set-default sym val))
101 :group 'server
102 :type 'boolean
103 :version "22.1")
104
105(defcustom server-host nil
106 "The name or IP address to use as host address of the server process.
107If set, the server accepts remote connections; otherwise it is local."
108 :group 'server
109 :type '(choice
110 (string :tag "Name or IP address")
111 (const :tag "Local" nil))
112 :version "22.1")
113(put 'server-host 'risky-local-variable t)
114
d6c180c4 115(defcustom server-auth-dir (locate-user-emacs-file "server/")
3e70541a
JB
116 "Directory for server authentication files.
117
118NOTE: On FAT32 filesystems, directories are not secure;
119files can be read and modified by any user or process.
120It is strongly suggested to set `server-auth-dir' to a
121directory residing in a NTFS partition instead."
337e3c70
JB
122 :group 'server
123 :type 'directory
124 :version "22.1")
125(put 'server-auth-dir 'risky-local-variable t)
126
90caccca 127(defcustom server-raise-frame t
ff348fba 128 "If non-nil, raise frame when switching to a buffer."
90caccca
JB
129 :group 'server
130 :type 'boolean
131 :version "22.1")
132
ab1c7f35 133(defcustom server-visit-hook nil
ff348fba 134 "Hook run when visiting a file for the Emacs server."
ab1c7f35 135 :group 'server
0c851d78 136 :type 'hook)
ab1c7f35
RS
137
138(defcustom server-switch-hook nil
ff348fba 139 "Hook run when switching to a buffer for the Emacs server."
ab1c7f35 140 :group 'server
0c851d78 141 :type 'hook)
ab1c7f35
RS
142
143(defcustom server-done-hook nil
ff348fba 144 "Hook run when done editing a buffer for the Emacs server."
ab1c7f35 145 :group 'server
0c851d78 146 :type 'hook)
f9b3ef88 147
64f51134
JPW
148(defvar server-process nil
149 "The current server process.")
9ae0f972 150
151(defvar server-clients nil
152 "List of current server clients.
448f754f 153Each element is a process.")
0a125897 154
9ae0f972 155(defvar server-buffer-clients nil
5f3c1a63 156 "List of client processes requesting editing of current buffer.")
faf931a8 157(make-variable-buffer-local 'server-buffer-clients)
9ae0f972 158;; Changing major modes should not erase this local.
159(put 'server-buffer-clients 'permanent-local t)
160
33186f32 161(defcustom server-window nil
ff348fba 162 "Specification of the window to use for selecting Emacs server buffers.
ec40ed9f 163If nil, use the selected window.
408784a7 164If it is a function, it should take one argument (a buffer) and
33186f32
DL
165display and select it. A common value is `pop-to-buffer'.
166If it is a window, use that.
167If it is a frame, use the frame's selected window.
168
169It is not meaningful to set this to a specific frame or window with Custom.
170Only programs can do so."
171 :group 'server
bf247b6e 172 :version "22.1"
33186f32
DL
173 :type '(choice (const :tag "Use selected window"
174 :match (lambda (widget value)
175 (not (functionp value)))
176 nil)
ee9272ff 177 (function-item :tag "Display in new frame" switch-to-buffer-other-frame)
33186f32
DL
178 (function-item :tag "Use pop-to-buffer" pop-to-buffer)
179 (function :tag "Other function")))
ec40ed9f 180
ab1c7f35 181(defcustom server-temp-file-regexp "^/tmp/Re\\|/draft$"
ff348fba 182 "Regexp matching names of temporary files.
33186f32
DL
183These are deleted and reused after each edit by the programs that
184invoke the Emacs server."
ab1c7f35
RS
185 :group 'server
186 :type 'regexp)
9ae0f972 187
c6a117f0 188(defcustom server-kill-new-buffers t
ff348fba 189 "Whether to kill buffers when done with them.
c6a117f0 190If non-nil, kill a buffer unless it already existed before editing
f258b525 191it with the Emacs server. If nil, kill only buffers as specified by
c6a117f0 192`server-temp-file-regexp'.
f258b525 193Please note that only buffers that still have a client are killed,
a77ad240
JB
194i.e. buffers visited with \"emacsclient --no-wait\" are never killed
195in this way."
c6a117f0
GM
196 :group 'server
197 :type 'boolean
198 :version "21.1")
199
9ae0f972 200(or (assq 'server-buffer-clients minor-mode-alist)
b7621225 201 (push '(server-buffer-clients " Server") minor-mode-alist))
9ae0f972 202
c6a117f0 203(defvar server-existing-buffer nil
ca0c7250 204 "Non-nil means the buffer existed before the server was asked to visit it.
4dd04714 205This means that the server should not kill the buffer when you say you
ca0c7250 206are done with it in the server.")
c6a117f0
GM
207(make-variable-buffer-local 'server-existing-buffer)
208
77c4d024
CY
209(defcustom server-name "server"
210 "The name of the Emacs server, if this Emacs process creates one.
211The command `server-start' makes use of this. It should not be
212changed while a server is running."
213 :group 'server
214 :type 'string
215 :version "23.1")
03ae35cf 216
03542605
CY
217;; We do not use `temporary-file-directory' here, because emacsclient
218;; does not read the init file.
f77b11a0 219(defvar server-socket-dir
a77ad240
JB
220 (and (featurep 'make-network-process '(:family local))
221 (format "%s/emacs%d" (or (getenv "TMPDIR") "/tmp") (user-uid)))
222 "The directory in which to place the server socket.
223If local sockets are not supported, this is nil.")
0c851d78 224
9002956f
KL
225(defun server-clients-with (property value)
226 "Return a list of clients with PROPERTY set to VALUE."
227 (let (result)
448f754f
SM
228 (dolist (proc server-clients result)
229 (when (equal value (process-get proc property))
230 (push proc result)))))
9002956f
KL
231
232(defun server-add-client (proc)
233 "Create a client for process PROC, if it doesn't already have one.
234New clients have no properties."
448f754f 235 (add-to-list 'server-clients proc))
9002956f 236
59e085e0
KL
237(defmacro server-with-environment (env vars &rest body)
238 "Evaluate BODY with environment variables VARS set to those in ENV.
65f64034
KL
239The environment variables are then restored to their previous values.
240
59e085e0
KL
241VARS should be a list of strings.
242ENV should be in the same format as `process-environment'."
65f64034 243 (declare (indent 2))
13ba3740
SM
244 (let ((var (make-symbol "var"))
245 (value (make-symbol "value")))
246 `(let ((process-environment process-environment))
59e085e0 247 (dolist (,var ,vars)
e159b869 248 (let ((,value (getenv-internal ,var ,env)))
abab01f2
JB
249 (push (if (stringp ,value)
250 (concat ,var "=" ,value)
251 ,var)
13ba3740
SM
252 process-environment)))
253 (progn ,@body))))
65f64034 254
448f754f 255(defun server-delete-client (proc &optional noframe)
c48254fb 256 "Delete PROC, including its buffers, terminals and frames.
a77ad240
JB
257If NOFRAME is non-nil, let the frames live.
258Updates `server-clients'."
ff91dc79 259 (server-log (concat "server-delete-client" (if noframe " noframe")) proc)
9002956f 260 ;; Force a new lookup of client (prevents infinite recursion).
448f754f
SM
261 (when (memq proc server-clients)
262 (let ((buffers (process-get proc 'buffers)))
9002956f 263
5f3c1a63 264 ;; Kill the client's buffers.
9002956f 265 (dolist (buf buffers)
6ed9e43a
KL
266 (when (buffer-live-p buf)
267 (with-current-buffer buf
6ed9e43a 268 ;; Kill the buffer if necessary.
5f3c1a63
KL
269 (when (and (equal server-buffer-clients
270 (list proc))
6ed9e43a
KL
271 (or (and server-kill-new-buffers
272 (not server-existing-buffer))
5f3c1a63
KL
273 (server-temp-file-p))
274 (not (buffer-modified-p)))
275 (let (flag)
276 (unwind-protect
277 (progn (setq server-buffer-clients nil)
278 (kill-buffer (current-buffer))
279 (setq flag t))
280 (unless flag
281 ;; Restore clients if user pressed C-g in `kill-buffer'.
282 (setq server-buffer-clients (list proc)))))))))
9002956f 283
160f0817
KL
284 ;; Delete the client's frames.
285 (unless noframe
286 (dolist (frame (frame-list))
287 (when (and (frame-live-p frame)
288 (equal proc (frame-parameter frame 'client)))
289 ;; Prevent `server-handle-delete-frame' from calling us
290 ;; recursively.
291 (set-frame-parameter frame 'client nil)
292 (delete-frame frame))))
293
448f754f 294 (setq server-clients (delq proc server-clients))
5f3c1a63 295
9002956f 296 ;; Delete the client's tty.
448f754f 297 (let ((terminal (process-get proc 'terminal)))
977ede64
DN
298 ;; Only delete the terminal if it is non-nil.
299 (when (and terminal (eq (terminal-live-p terminal) t))
6ed8eeff 300 (delete-terminal terminal)))
9002956f 301
9002956f 302 ;; Delete the client's process.
448f754f
SM
303 (if (eq (process-status proc) 'open)
304 (delete-process proc))
9002956f
KL
305
306 (server-log "Deleted" proc))))
307
88fd26a1 308(defvar server-log-time-function 'current-time-string
f03ea9d9 309 "Function to generate timestamps for `server-buffer'.")
88fd26a1 310
28cbade4
SM
311(defconst server-buffer " *server*"
312 "Buffer used internally by Emacs's server.
313One use is to log the I/O for debugging purposes (see `server-log'),
314the other is to provide a current buffer in which the process filter can
f03ea9d9 315safely let-bind buffer-local variables like `default-directory'.")
28cbade4
SM
316
317(defvar server-log nil
318 "If non-nil, log the server's inputs and outputs in the `server-buffer'.")
319
8b3e840e 320(defun server-log (string &optional client)
28cbade4 321 "If `server-log' is non-nil, log STRING to `server-buffer'.
c48254fb 322If CLIENT is non-nil, add a description of it to the logged message."
28cbade4
SM
323 (when server-log
324 (with-current-buffer (get-buffer-create server-buffer)
337e3c70 325 (goto-char (point-max))
88fd26a1 326 (insert (funcall server-log-time-function)
974b73e8 327 (cond
88fd26a1
JB
328 ((null client) " ")
329 ((listp client) (format " %s: " (car client)))
330 (t (format " %s: " client)))
337e3c70
JB
331 string)
332 (or (bolp) (newline)))))
9ae0f972 333
334(defun server-sentinel (proc msg)
9002956f 335 "The process sentinel for Emacs server connections."
cbfc02e4
RF
336 ;; If this is a new client process, set the query-on-exit flag to nil
337 ;; for this process (it isn't inherited from the server process).
338 (when (and (eq (process-status proc) 'open)
339 (process-query-on-exit-flag proc))
340 (set-process-query-on-exit-flag proc nil))
757e1681 341 ;; Delete the associated connection file, if applicable.
c63a334e
JB
342 ;; Although there's no 100% guarantee that the file is owned by the
343 ;; running Emacs instance, server-start uses server-running-p to check
344 ;; for possible servers before doing anything, so it *should* be ours.
345 (and (process-contact proc :server)
346 (eq (process-status proc) 'closed)
347 (ignore-errors (delete-file (process-get proc :server-file))))
9002956f
KL
348 (server-log (format "Status changed to %s: %s" (process-status proc) msg) proc)
349 (server-delete-client proc))
0c851d78 350
13ba3740
SM
351(defun server-select-display (display)
352 ;; If the current frame is on `display' we're all set.
a77ad240 353 ;; Similarly if we are unable to open frames on other displays, there's
1a4a884c
SM
354 ;; nothing more we can do.
355 (unless (or (not (fboundp 'make-frame-on-display))
356 (equal (frame-parameter (selected-frame) 'display) display))
13ba3740
SM
357 ;; Otherwise, look for an existing frame there and select it.
358 (dolist (frame (frame-list))
359 (when (equal (frame-parameter frame 'display) display)
360 (select-frame frame)))
361 ;; If there's no frame on that display yet, create and select one.
362 (unless (equal (frame-parameter (selected-frame) 'display) display)
363 (let* ((buffer (generate-new-buffer " *server-dummy*"))
364 (frame (make-frame-on-display
365 display
366 ;; Make it display (and remember) some dummy buffer, so
367 ;; we can detect later if the frame is in use or not.
ff91dc79 368 `((server-dummy-buffer . ,buffer)
13ba3740
SM
369 ;; This frame may be deleted later (see
370 ;; server-unselect-display) so we want it to be as
371 ;; unobtrusive as possible.
372 (visibility . nil)))))
373 (select-frame frame)
374 (set-window-buffer (selected-window) buffer)
375 frame))))
376
377(defun server-unselect-display (frame)
378 (when (frame-live-p frame)
379 ;; If the temporary frame is in use (displays something real), make it
380 ;; visible. If not (which can happen if the user's customizations call
381 ;; pop-to-buffer etc.), delete it to avoid preserving the connection after
382 ;; the last real frame is deleted.
383 (if (and (eq (frame-first-window frame)
384 (next-window (frame-first-window frame) 'nomini))
385 (eq (window-buffer (frame-first-window frame))
386 (frame-parameter frame 'server-dummy-buffer)))
387 ;; The temp frame still only shows one buffer, and that is the
388 ;; internal temp buffer.
389 (delete-frame frame)
390 (set-frame-parameter frame 'visibility t))
391 (kill-buffer (frame-parameter frame 'server-dummy-buffer))
392 (set-frame-parameter frame 'server-dummy-buffer nil)))
393
77134727 394(defun server-handle-delete-frame (frame)
a77ad240
JB
395 "Delete the client connection when the emacsclient frame is deleted.
396\(To be used from `delete-frame-functions'.)"
9002956f 397 (let ((proc (frame-parameter frame 'client)))
e519a50b
KL
398 (when (and (frame-live-p frame)
399 proc
160f0817 400 ;; See if this is the last frame for this client.
d5381da2 401 (>= 1 (let ((frame-num 0))
aabf0cb9 402 (dolist (f (frame-list))
160f0817
KL
403 (when (eq proc (frame-parameter f 'client))
404 (setq frame-num (1+ frame-num))))
405 frame-num)))
9002956f 406 (server-log (format "server-handle-delete-frame, frame %s" frame) proc)
de93c791 407 (server-delete-client proc 'noframe)))) ; Let delete-frame delete the frame later.
9002956f 408
6ed8eeff 409(defun server-handle-suspend-tty (terminal)
9002956f 410 "Notify the emacsclient process to suspend itself when its tty device is suspended."
6ed8eeff
KL
411 (dolist (proc (server-clients-with 'terminal terminal))
412 (server-log (format "server-handle-suspend-tty, terminal %s" terminal) proc)
6d3a46f7 413 (condition-case err
6afdd335 414 (server-send-string proc "-suspend \n")
44954c2f
SM
415 (file-error ;The pipe/socket was closed.
416 (ignore-errors (server-delete-client proc))))))
44a56b29 417
0c851d78 418(defun server-unquote-arg (arg)
6afdd335
KL
419 "Remove &-quotation from ARG.
420See `server-quote-arg' and `server-process-filter'."
0c851d78
SM
421 (replace-regexp-in-string
422 "&." (lambda (s)
423 (case (aref s 1)
424 (?& "&")
425 (?- "-")
426 (?n "\n")
427 (t " ")))
428 arg t t))
9ae0f972 429
0b0d3e0b 430(defun server-quote-arg (arg)
9002956f 431 "In ARG, insert a & before each &, each space, each newline, and -.
0b0d3e0b 432Change spaces to underscores, too, so that the return value never
6afdd335
KL
433contains a space.
434
435See `server-unquote-arg' and `server-process-filter'."
0b0d3e0b
KL
436 (replace-regexp-in-string
437 "[-&\n ]" (lambda (s)
438 (case (aref s 0)
439 (?& "&&")
440 (?- "&-")
441 (?\n "&n")
442 (?\s "&_")))
443 arg t t))
444
6afdd335 445(defun server-send-string (proc string)
a77ad240 446 "A wrapper around `process-send-string' for logging."
6afdd335
KL
447 (server-log (concat "Sent " string) proc)
448 (process-send-string proc string))
449
724629d2
SM
450(defun server-ensure-safe-dir (dir)
451 "Make sure DIR is a directory with no race-condition issues.
452Creates the directory if necessary and makes sure:
453- there's no symlink involved
454- it's owned by us
455- it's not readable/writable by anybody else."
456 (setq dir (directory-file-name dir))
d7554167 457 (let ((attrs (file-attributes dir 'integer)))
724629d2 458 (unless attrs
337e3c70 459 (letf (((default-file-modes) ?\700)) (make-directory dir t))
d7554167 460 (setq attrs (file-attributes dir 'integer)))
3e70541a 461
724629d2 462 ;; Check that it's safe for use.
3e70541a
JB
463 (let* ((uid (nth 2 attrs))
464 (w32 (eq system-type 'windows-nt))
465 (safe (catch :safe
466 (unless (eq t (car attrs)) ; is a dir?
467 (throw :safe nil))
468 (when (and w32 (zerop uid)) ; on FAT32?
469 (display-warning
470 'server
471 (format "Using `%s' to store Emacs-server authentication files.
472Directories on FAT32 filesystems are NOT secure against tampering.
473See variable `server-auth-dir' for details."
474 (file-name-as-directory dir))
475 :warning)
476 (throw :safe t))
477 (unless (eql uid (user-uid)) ; is the dir ours?
478 (throw :safe nil))
479 (when w32 ; on NTFS?
480 (throw :safe t))
481 (unless (zerop (logand ?\077 (file-modes dir)))
482 (throw :safe nil))
483 t)))
484 (unless safe
485 (error "The directory `%s' is unsafe" dir)))))
724629d2 486
7229064d 487;;;###autoload
9ae0f972 488(defun server-start (&optional leave-dead)
489 "Allow this Emacs process to be a server for client processes.
490This starts a server communications subprocess through which
6d3a46f7
KL
491client \"editors\" can send your editing commands to this Emacs
492job. To use the server, set up the program `emacsclient' in the
9ae0f972 493Emacs distribution as your standard \"editor\".
494
bd410bb0 495Optional argument LEAVE-DEAD (interactively, a prefix arg) means just
c63a334e
JB
496kill any existing server communications subprocess.
497
498If a server is already running, the server is not started.
499To force-start a server, do \\[server-force-delete] and then
500\\[server-start]."
9ae0f972 501 (interactive "P")
97e121cc
CY
502 (when (or (not server-clients)
503 ;; Ask the user before deleting existing clients---except
504 ;; when we can't get user input, which may happen when
505 ;; doing emacsclient --eval "(kill-emacs)" in daemon mode.
506 (if (and (daemonp)
507 (null (cdr (frame-list)))
508 (eq (selected-frame) terminal-frame))
509 leave-dead
510 (yes-or-no-p
511 "The current server still has clients; delete them? ")))
c63a334e
JB
512 (let* ((server-dir (if server-use-tcp server-auth-dir server-socket-dir))
513 (server-file (expand-file-name server-name server-dir)))
514 (when server-process
515 ;; kill it dead!
516 (ignore-errors (delete-process server-process)))
517 ;; Delete the socket files made by previous server invocations.
518 (if (not (eq t (server-running-p server-name)))
519 ;; Remove any leftover socket or authentication file
520 (ignore-errors (delete-file server-file))
521 (setq server-mode nil) ;; already set by the minor mode code
c31ee003
CY
522 (display-warning
523 'server
524 (concat "Unable to start the Emacs server.\n"
525 (format "There is an existing Emacs server, named %S.\n"
526 server-name)
527 "To start the server in this Emacs process, stop the existing
528server or call `M-x server-force-delete' to forcibly disconnect it.")
529 :warning)
35f372ca 530 (setq leave-dead t))
c63a334e
JB
531 ;; If this Emacs already had a server, clear out associated status.
532 (while server-clients
533 (server-delete-client (car server-clients)))
534 ;; Now any previous server is properly stopped.
535 (if leave-dead
536 (progn
35f372ca 537 (unless (eq t leave-dead) (server-log (message "Server stopped")))
c63a334e 538 (setq server-process nil))
974b73e8
KL
539 ;; Make sure there is a safe directory in which to place the socket.
540 (server-ensure-safe-dir server-dir)
974b73e8
KL
541 (when server-process
542 (server-log (message "Restarting server")))
543 (letf (((default-file-modes) ?\700))
e4019195 544 (add-hook 'suspend-tty-functions 'server-handle-suspend-tty)
974b73e8
KL
545 (add-hook 'delete-frame-functions 'server-handle-delete-frame)
546 (add-hook 'kill-buffer-query-functions 'server-kill-buffer-query-function)
547 (add-hook 'kill-emacs-query-functions 'server-kill-emacs-query-function)
1d515b42 548 (add-hook 'kill-emacs-hook (lambda () (server-mode -1))) ;Cleanup upon exit.
974b73e8
KL
549 (setq server-process
550 (apply #'make-network-process
551 :name server-name
552 :server t
553 :noquery t
554 :sentinel 'server-sentinel
555 :filter 'server-process-filter
556 ;; We must receive file names without being decoded.
557 ;; Those are decoded by server-process-filter according
1b0a6c68
SM
558 ;; to file-name-coding-system. Also don't get
559 ;; confused by CRs since we don't quote them.
560 :coding 'raw-text-unix
28cbade4 561 ;; The other args depend on the kind of socket used.
974b73e8
KL
562 (if server-use-tcp
563 (list :family nil
564 :service t
565 :host (or server-host 'local)
566 :plist '(:authenticated nil))
567 (list :family 'local
568 :service server-file
569 :plist '(:authenticated t)))))
570 (unless server-process (error "Could not start server process"))
c63a334e 571 (process-put server-process :server-file server-file)
974b73e8
KL
572 (when server-use-tcp
573 (let ((auth-key
574 (loop
d76e2046
JB
575 ;; The auth key is a 64-byte string of random chars in the
576 ;; range `!'..`~'.
577 for i below 64
578 collect (+ 33 (random 94)) into auth
579 finally return (concat auth))))
974b73e8
KL
580 (process-put server-process :auth-key auth-key)
581 (with-temp-file server-file
582 (set-buffer-multibyte nil)
583 (setq buffer-file-coding-system 'no-conversion)
584 (insert (format-network-address
585 (process-contact server-process :local))
586 " " (int-to-string (emacs-pid))
587 "\n" auth-key)))))))))
33186f32 588
c63a334e
JB
589;;;###autoload
590(defun server-force-delete (&optional name)
591 "Unconditionally delete connection file for server NAME.
592If server is running, it is first stopped.
593NAME defaults to `server-name'. With argument, ask for NAME."
594 (interactive
595 (list (if current-prefix-arg
596 (read-string "Server name: " nil nil server-name))))
597 (when server-mode (with-temp-message nil (server-mode -1)))
598 (let ((file (expand-file-name (or name server-name)
599 (if server-use-tcp
600 server-auth-dir
601 server-socket-dir))))
602 (condition-case nil
603 (progn
604 (delete-file file)
605 (message "Connection file %S deleted" file))
606 (file-error
607 (message "No connection file %S" file)))))
608
44954c2f 609(defun server-running-p (&optional name)
c63a334e
JB
610 "Test whether server NAME is running.
611
612Return values:
613 nil the server is definitely not running.
614 t the server seems to be running.
615 something else we cannot determine whether it's running without using
616 commands which may have to wait for a long time."
44954c2f
SM
617 (unless name (setq name server-name))
618 (condition-case nil
c63a334e
JB
619 (if server-use-tcp
620 (with-temp-buffer
621 (insert-file-contents-literally (expand-file-name name server-auth-dir))
d9569a55 622 (or (and (looking-at "127\\.0\\.0\\.1:[0-9]+ \\([0-9]+\\)")
c63a334e 623 (assq 'comm
a20878b6 624 (process-attributes
c63a334e
JB
625 (string-to-number (match-string 1))))
626 t)
627 :other))
44954c2f
SM
628 (delete-process
629 (make-network-process
630 :name "server-client-test" :family 'local :server nil :noquery t
631 :service (expand-file-name name server-socket-dir)))
632 t)
633 (file-error nil)))
634
33186f32
DL
635;;;###autoload
636(define-minor-mode server-mode
637 "Toggle Server mode.
638With ARG, turn Server mode on if ARG is positive, off otherwise.
639Server mode runs a process that accepts commands from the
640`emacsclient' program. See `server-start' and Info node `Emacs server'."
641 :global t
642 :group 'server
bf247b6e 643 :version "22.1"
33186f32
DL
644 ;; Fixme: Should this check for an existing server socket and do
645 ;; nothing if there is one (for multiple Emacs sessions)?
646 (server-start (not server-mode)))
9ae0f972 647\f
13ba3740
SM
648(defun server-eval-and-print (expr proc)
649 "Eval EXPR and send the result back to client PROC."
650 (let ((v (eval (car (read-from-string expr)))))
651 (when (and v proc)
652 (with-temp-buffer
653 (let ((standard-output (current-buffer)))
654 (pp v)
655 (let ((text (buffer-substring-no-properties
656 (point-min) (point-max))))
657 (server-send-string
658 proc (format "-print %s\n"
659 (server-quote-arg text)))))))))
660
661(defun server-create-tty-frame (tty type proc)
f79b43b2
DN
662 (unless tty
663 (error "Invalid terminal device"))
664 (unless type
665 (error "Invalid terminal type"))
4419b755 666 (add-to-list 'frame-inherited-parameters 'client)
13ba3740
SM
667 (let ((frame
668 (server-with-environment (process-get proc 'env)
669 '("LANG" "LC_CTYPE" "LC_ALL"
670 ;; For tgetent(3); list according to ncurses(3).
671 "BAUDRATE" "COLUMNS" "ESCDELAY" "HOME" "LINES"
672 "NCURSES_ASSUMED_COLORS" "NCURSES_NO_PADDING"
673 "NCURSES_NO_SETBUF" "TERM" "TERMCAP" "TERMINFO"
c48254fb 674 "TERMINFO_DIRS" "TERMPATH"
13ba3740
SM
675 ;; rxvt wants these
676 "COLORFGBG" "COLORTERM")
f79b43b2
DN
677 (make-frame `((window-system . nil)
678 (tty . ,tty)
679 (tty-type . ,type)
680 ;; Ignore nowait here; we always need to
681 ;; clean up opened ttys when the client dies.
682 (client . ,proc)
683 ;; This is a leftover from an earlier
684 ;; attempt at making it possible for process
685 ;; run in the server process to use the
686 ;; environment of the client process.
687 ;; It has no effect now and to make it work
688 ;; we'd need to decide how to make
689 ;; process-environment interact with client
690 ;; envvars, and then to change the
691 ;; C functions `child_setup' and
692 ;; `getenv_internal' accordingly.
693 (environment . ,(process-get proc 'env)))))))
052056a9 694
e159b869
SM
695 ;; ttys don't use the `display' parameter, but callproc.c does to set
696 ;; the DISPLAY environment on subprocesses.
697 (set-frame-parameter frame 'display
698 (getenv-internal "DISPLAY" (process-get proc 'env)))
13ba3740 699 (select-frame frame)
448f754f 700 (process-put proc 'frame frame)
448f754f 701 (process-put proc 'terminal (frame-terminal frame))
13ba3740
SM
702
703 ;; Display *scratch* by default.
704 (switch-to-buffer (get-buffer-create "*scratch*") 'norecord)
705
706 ;; Reply with our pid.
707 (server-send-string proc (concat "-emacs-pid "
708 (number-to-string (emacs-pid)) "\n"))
709 frame))
710
711(defun server-create-window-system-frame (display nowait proc)
4419b755 712 (add-to-list 'frame-inherited-parameters 'client)
e159b869 713 (if (not (fboundp 'make-frame-on-display))
13ba3740
SM
714 (progn
715 ;; This emacs does not support X.
716 (server-log "Window system unsupported" proc)
717 (server-send-string proc "-window-system-unsupported \n")
718 nil)
719 ;; Flag frame as client-created, but use a dummy client.
720 ;; This will prevent the frame from being deleted when
721 ;; emacsclient quits while also preventing
722 ;; `server-save-buffers-kill-terminal' from unexpectedly
723 ;; killing emacs on that frame.
724 (let* ((params `((client . ,(if nowait 'nowait proc))
4419b755 725 ;; This is a leftover, see above.
13ba3740
SM
726 (environment . ,(process-get proc 'env))))
727 (frame (make-frame-on-display
728 (or display
729 (frame-parameter nil 'display)
730 (getenv "DISPLAY")
731 (error "Please specify display"))
448f754f 732 params)))
13ba3740 733 (server-log (format "%s created" frame) proc)
13ba3740 734 (select-frame frame)
448f754f
SM
735 (process-put proc 'frame frame)
736 (process-put proc 'terminal (frame-terminal frame))
13ba3740
SM
737
738 ;; Display *scratch* by default.
739 (switch-to-buffer (get-buffer-create "*scratch*") 'norecord)
740 frame)))
741
13ba3740
SM
742(defun server-goto-toplevel (proc)
743 (condition-case nil
744 ;; If we're running isearch, we must abort it to allow Emacs to
745 ;; display the buffer and switch to it.
746 (dolist (buffer (buffer-list))
747 (with-current-buffer buffer
748 (when (bound-and-true-p isearch-mode)
749 (isearch-cancel))))
750 ;; Signaled by isearch-cancel.
751 (quit (message nil)))
752 (when (> (recursion-depth) 0)
753 ;; We're inside a minibuffer already, so if the emacs-client is trying
754 ;; to open a frame on a new display, we might end up with an unusable
755 ;; frame because input from that display will be blocked (until exiting
756 ;; the minibuffer). Better exit this minibuffer right away.
757 ;; Similarly with recursive-edits such as the splash screen.
758 (run-with-timer 0 nil (lexical-let ((proc proc))
759 (lambda () (server-execute-continuation proc))))
760 (top-level)))
761
762;; We use various special properties on process objects:
763;; - `env' stores the info about the environment of the emacsclient process.
764;; - `continuation' is a no-arg function that we need to execute. It contains
765;; commands we wanted to execute in some earlier invocation of the process
766;; filter but that we somehow were unable to process at that time
767;; (e.g. because we first need to throw to the toplevel).
768
769(defun server-execute-continuation (proc)
770 (let ((continuation (process-get proc 'continuation)))
771 (process-put proc 'continuation nil)
772 (if continuation (ignore-errors (funcall continuation)))))
773
337e3c70 774(defun* server-process-filter (proc string)
33186f32 775 "Process a request from the server to edit some files.
6afdd335 776PROC is the server process. STRING consists of a sequence of
909049cb
JB
777commands prefixed by a dash. Some commands have arguments;
778these are &-quoted and need to be decoded by `server-unquote-arg'.
779The filter parses and executes these commands.
6afdd335
KL
780
781To illustrate the protocol, here is an example command that
782emacsclient sends to create a new X frame (note that the whole
783sequence is sent on a single line):
784
909049cb
JB
785 -env HOME=/home/lorentey
786 -env DISPLAY=:0.0
6afdd335
KL
787 ... lots of other -env commands
788 -display :0.0
789 -window-system
790
6afdd335
KL
791The following commands are accepted by the server:
792
974b73e8
KL
793`-auth AUTH-STRING'
794 Authenticate the client using the secret authentication string
a38daa0a 795 AUTH-STRING.
974b73e8 796
59e085e0 797`-env NAME=VALUE'
6afdd335
KL
798 An environment variable on the client side.
799
2828d5f9
KL
800`-dir DIRNAME'
801 The current working directory of the client process.
802
92071250
KL
803`-current-frame'
804 Forbid the creation of new frames.
805
6afdd335
KL
806`-nowait'
807 Request that the next frame created should not be
808 associated with this client.
809
810`-display DISPLAY'
811 Set the display name to open X frames on.
812
813`-position LINE[:COLUMN]'
814 Go to the given line and column number
815 in the next file opened.
816
817`-file FILENAME'
818 Load the given file in the current frame.
819
820`-eval EXPR'
821 Evaluate EXPR as a Lisp expression and return the
822 result in -print commands.
823
824`-window-system'
825 Open a new X frame.
826
827`-tty DEVICENAME TYPE'
828 Open a new tty frame at the client.
829
6afdd335
KL
830`-suspend'
831 Suspend this tty frame. The client sends this string in
832 response to SIGTSTP and SIGTTOU. The server must cease all I/O
833 on this tty until it gets a -resume command.
834
2828d5f9 835`-resume'
c48254fb 836 Resume this tty frame. The client sends this string when it
2828d5f9
KL
837 gets the SIGCONT signal and it is the foreground process on its
838 controlling tty.
839
6afdd335 840`-ignore COMMENT'
909049cb
JB
841 Do nothing, but put the comment in the server log.
842 Useful for debugging.
6afdd335
KL
843
844
845The following commands are accepted by the client:
846
6afdd335
KL
847`-emacs-pid PID'
848 Describes the process id of the Emacs process;
849 used to forward window change signals to it.
850
851`-window-system-unsupported'
c48254fb
JB
852 Signals that the server does not support creating X frames;
853 the client must try again with a tty frame.
6afdd335
KL
854
855`-print STRING'
856 Print STRING on stdout. Used to send values
857 returned by -eval.
858
859`-error DESCRIPTION'
860 Signal an error (but continue processing).
861
862`-suspend'
c48254fb
JB
863 Suspend this terminal, i.e., stop the client process.
864 Sent when the user presses C-z."
6afdd335 865 (server-log (concat "Received " string) proc)
337e3c70
JB
866 ;; First things first: let's check the authentication
867 (unless (process-get proc :authenticated)
38b9f0f3 868 (if (and (string-match "-auth \\([!-~]+\\)\n?" string)
974b73e8
KL
869 (equal (match-string 1 string) (process-get proc :auth-key)))
870 (progn
871 (setq string (substring string (match-end 0)))
872 (process-put proc :authenticated t)
873 (server-log "Authentication successful" proc))
337e3c70 874 (server-log "Authentication failed" proc)
974b73e8
KL
875 (server-send-string
876 proc (concat "-error " (server-quote-arg "Authentication failed")))
337e3c70
JB
877 (delete-process proc)
878 ;; We return immediately
879 (return-from server-process-filter)))
3f7ef08e
SM
880 (let ((prev (process-get proc 'previous-string)))
881 (when prev
882 (setq string (concat prev string))
883 (process-put proc 'previous-string nil)))
a9298135 884 (condition-case err
0b0d3e0b 885 (progn
9002956f 886 (server-add-client proc)
13ba3740
SM
887 (if (not (string-match "\n" string))
888 ;; Save for later any partial line that remains.
889 (when (> (length string) 0)
890 (process-put proc 'previous-string string))
c48254fb 891
13ba3740
SM
892 ;; In earlier versions of server.el (where we used an `emacsserver'
893 ;; process), there could be multiple lines. Nowadays this is not
894 ;; supported any more.
895 (assert (eq (match-end 0) (length string)))
0b0d3e0b 896 (let ((request (substring string 0 (match-beginning 0)))
597e2240 897 (coding-system (and (default-value 'enable-multibyte-characters)
0b0d3e0b
KL
898 (or file-name-coding-system
899 default-file-name-coding-system)))
9002956f
KL
900 nowait ; t if emacsclient does not want to wait for us.
901 frame ; The frame that was opened for the client (if any).
59e085e0 902 display ; Open the frame on this display.
0b0d3e0b 903 dontkill ; t if the client should not be killed.
650d0dbc 904 commands
2828d5f9 905 dir
cd9c54eb 906 use-current-frame
650d0dbc
CY
907 tty-name ;nil, `window-system', or the tty name.
908 tty-type ;string.
909 files
910 filepos
bfb74e75
DK
911 command-line-args-left
912 arg)
0b0d3e0b
KL
913 ;; Remove this line from STRING.
914 (setq string (substring string (match-end 0)))
bfb74e75
DK
915 (setq command-line-args-left
916 (mapcar 'server-unquote-arg (split-string request " " t)))
917 (while (setq arg (pop command-line-args-left))
0b0d3e0b 918 (cond
13ba3740 919 ;; -version CLIENT-VERSION: obsolete at birth.
bfb74e75
DK
920 ((and (equal "-version" arg) command-line-args-left)
921 (pop command-line-args-left))
0b0d3e0b 922
9002956f 923 ;; -nowait: Emacsclient won't wait for a result.
0b0d3e0b
KL
924 ((equal "-nowait" arg) (setq nowait t))
925
92071250 926 ;; -current-frame: Don't create frames.
cd9c54eb 927 ((equal "-current-frame" arg) (setq use-current-frame t))
92071250 928
9002956f 929 ;; -display DISPLAY:
59e085e0 930 ;; Open X frames on the given display instead of the default.
bfb74e75 931 ((and (equal "-display" arg) command-line-args-left)
ff91dc79
SM
932 (setq display (pop command-line-args-left))
933 (if (zerop (length display)) (setq display nil)))
0b0d3e0b 934
9002956f 935 ;; -window-system: Open a new X frame.
0b0d3e0b 936 ((equal "-window-system" arg)
13ba3740
SM
937 (setq dontkill t)
938 (setq tty-name 'window-system))
9002956f
KL
939
940 ;; -resume: Resume a suspended tty frame.
0b0d3e0b 941 ((equal "-resume" arg)
448f754f 942 (lexical-let ((terminal (process-get proc 'terminal)))
0b0d3e0b 943 (setq dontkill t)
13ba3740
SM
944 (push (lambda ()
945 (when (eq (terminal-live-p terminal) t)
946 (resume-tty terminal)))
947 commands)))
0b0d3e0b 948
9002956f
KL
949 ;; -suspend: Suspend the client's frame. (In case we
950 ;; get out of sync, and a C-z sends a SIGTSTP to
951 ;; emacsclient.)
0b0d3e0b 952 ((equal "-suspend" arg)
448f754f 953 (lexical-let ((terminal (process-get proc 'terminal)))
0b0d3e0b 954 (setq dontkill t)
13ba3740
SM
955 (push (lambda ()
956 (when (eq (terminal-live-p terminal) t)
957 (suspend-tty terminal)))
958 commands)))
0b0d3e0b 959
9002956f
KL
960 ;; -ignore COMMENT: Noop; useful for debugging emacsclient.
961 ;; (The given comment appears in the server log.)
bfb74e75
DK
962 ((and (equal "-ignore" arg) command-line-args-left
963 (setq dontkill t)
964 (pop command-line-args-left)))
0b0d3e0b 965
9002956f 966 ;; -tty DEVICE-NAME TYPE: Open a new tty frame at the client.
13ba3740 967 ((and (equal "-tty" arg)
bfb74e75
DK
968 (cdr command-line-args-left))
969 (setq tty-name (pop command-line-args-left)
970 tty-type (pop command-line-args-left)
cd9c54eb
CY
971 dontkill (or dontkill
972 (not use-current-frame))))
13ba3740
SM
973
974 ;; -position LINE[:COLUMN]: Set point to the given
975 ;; position in the next file.
976 ((and (equal "-position" arg)
bfb74e75
DK
977 command-line-args-left
978 (string-match "\\+\\([0-9]+\\)\\(?::\\([0-9]+\\)\\)?"
979 (car command-line-args-left)))
980 (setq arg (pop command-line-args-left))
656d4706
SM
981 (setq filepos
982 (cons (string-to-number (match-string 1 arg))
983 (string-to-number (or (match-string 2 arg) "")))))
0b0d3e0b 984
9002956f 985 ;; -file FILENAME: Load the given file.
13ba3740 986 ((and (equal "-file" arg)
bfb74e75
DK
987 command-line-args-left)
988 (let ((file (pop command-line-args-left)))
0b0d3e0b
KL
989 (if coding-system
990 (setq file (decode-coding-string file coding-system)))
ba528748 991 (setq file (expand-file-name file dir))
656d4706
SM
992 (push (cons file filepos) files)
993 (server-log (format "New file: %s %s"
994 file (or filepos "")) proc))
995 (setq filepos nil))
0b0d3e0b 996
9002956f 997 ;; -eval EXPR: Evaluate a Lisp expression.
13ba3740 998 ((and (equal "-eval" arg)
bfb74e75 999 command-line-args-left)
cd9c54eb
CY
1000 (if use-current-frame
1001 (setq use-current-frame 'always))
bfb74e75 1002 (lexical-let ((expr (pop command-line-args-left)))
0b0d3e0b
KL
1003 (if coding-system
1004 (setq expr (decode-coding-string expr coding-system)))
13ba3740
SM
1005 (push (lambda () (server-eval-and-print expr proc))
1006 commands)
656d4706 1007 (setq filepos nil)))
0b0d3e0b 1008
59e085e0 1009 ;; -env NAME=VALUE: An environment variable.
bfb74e75
DK
1010 ((and (equal "-env" arg) command-line-args-left)
1011 (let ((var (pop command-line-args-left)))
da8e8fc1 1012 ;; XXX Variables should be encoded as in getenv/setenv.
13ba3740
SM
1013 (process-put proc 'env
1014 (cons var (process-get proc 'env)))))
9002956f 1015
2828d5f9 1016 ;; -dir DIRNAME: The cwd of the emacsclient process.
bfb74e75
DK
1017 ((and (equal "-dir" arg) command-line-args-left)
1018 (setq dir (pop command-line-args-left))
2828d5f9
KL
1019 (if coding-system
1020 (setq dir (decode-coding-string dir coding-system)))
1021 (setq dir (command-line-normalize-file-name dir)))
1022
0b0d3e0b 1023 ;; Unknown command.
bfb74e75 1024 (t (error "Unknown command: %s" arg))))
c48254fb 1025
cd9c54eb
CY
1026 (setq frame
1027 (cond
1028 ((and use-current-frame
1029 (or (eq use-current-frame 'always)
1030 ;; We can't use the Emacs daemon's
1031 ;; terminal frame.
d9bf544c 1032 (not (and (daemonp)
97e121cc 1033 (null (cdr (frame-list)))
cd9c54eb
CY
1034 (eq (selected-frame)
1035 terminal-frame)))))
d9bf544c 1036 (setq tty-name nil tty-type nil)
cd9c54eb
CY
1037 (if display (server-select-display display)))
1038 ((eq tty-name 'window-system)
1039 (server-create-window-system-frame display nowait proc))
650d0dbc
CY
1040 ;; When resuming on a tty, tty-name is nil.
1041 (tty-name
1042 (server-create-tty-frame tty-name tty-type proc))))
13ba3740 1043
28cbade4
SM
1044 (process-put
1045 proc 'continuation
1046 (lexical-let ((proc proc)
1047 (files files)
1048 (nowait nowait)
1049 (commands commands)
1050 (dontkill dontkill)
1051 (frame frame)
1052 (dir dir)
1053 (tty-name tty-name))
1054 (lambda ()
1055 (with-current-buffer (get-buffer-create server-buffer)
1056 ;; Use the same cwd as the emacsclient, if possible, so
1057 ;; relative file names work correctly, even in `eval'.
1058 (let ((default-directory
f03ea9d9
JB
1059 (if (and dir (file-directory-p dir))
1060 dir default-directory)))
28cbade4
SM
1061 (server-execute proc files nowait commands
1062 dontkill frame tty-name))))))
13ba3740
SM
1063
1064 (when (or frame files)
1065 (server-goto-toplevel proc))
1066
1067 (server-execute-continuation proc))))
a9298135 1068 ;; condition-case
13ba3740
SM
1069 (error (server-return-error proc err))))
1070
1071(defun server-execute (proc files nowait commands dontkill frame tty-name)
7197f5de
SM
1072 ;; This is run from timers and process-filters, i.e. "asynchronously".
1073 ;; But w.r.t the user, this is not really asynchronous since the timer
1074 ;; is run after 0s and the process-filter is run in response to the
1075 ;; user running `emacsclient'. So it is OK to override the
1076 ;; inhibit-quit flag, which is good since `commands' (as well as
1077 ;; find-file-noselect via the major-mode) can run arbitrary code,
1078 ;; including code that needs to wait.
1079 (with-local-quit
1080 (condition-case err
1081 (let* ((buffers
1082 (when files
1083 (run-hooks 'pre-command-hook)
1084 (prog1 (server-visit-files files proc nowait)
1085 (run-hooks 'post-command-hook)))))
1086
1087 (mapc 'funcall (nreverse commands))
1088
1089 ;; Delete the client if necessary.
1090 (cond
1091 (nowait
1092 ;; Client requested nowait; return immediately.
1093 (server-log "Close nowait client" proc)
1094 (server-delete-client proc))
1095 ((and (not dontkill) (null buffers))
1096 ;; This client is empty; get rid of it immediately.
1097 (server-log "Close empty client" proc)
1098 (server-delete-client proc)))
1099 (cond
1100 ((or isearch-mode (minibufferp))
1101 nil)
1102 ((and frame (null buffers))
13ba3740 1103 (message "%s" (substitute-command-keys
7197f5de
SM
1104 "When done with this frame, type \\[delete-frame]")))
1105 ((not (null buffers))
1106 (server-switch-buffer (car buffers) nil (cdr (car files)))
1107 (run-hooks 'server-switch-hook)
1108 (unless nowait
1109 (message "%s" (substitute-command-keys
1110 "When done with a buffer, type \\[server-edit]")))))
1111 (when (and frame (null tty-name))
1112 (server-unselect-display frame)))
1113 (error (server-return-error proc err)))))
13ba3740
SM
1114
1115(defun server-return-error (proc err)
1116 (ignore-errors
1117 (server-send-string
1118 proc (concat "-error " (server-quote-arg
1119 (error-message-string err))))
1120 (server-log (error-message-string err) proc)
1121 (delete-process proc)))
9ae0f972 1122
656d4706
SM
1123(defun server-goto-line-column (line-col)
1124 "Move point to the position indicated in LINE-COL.
1125LINE-COL should be a pair (LINE . COL)."
1126 (when line-col
e6ce8c42
GM
1127 (goto-char (point-min))
1128 (forward-line (1- (car line-col)))
656d4706
SM
1129 (let ((column-number (cdr line-col)))
1130 (when (> column-number 0)
1131 (move-to-column (1- column-number))))))
6b98185f 1132
448f754f 1133(defun server-visit-files (files proc &optional nowait)
c5b0a355 1134 "Find FILES and return a list of buffers created.
656d4706
SM
1135FILES is an alist whose elements are (FILENAME . FILEPOS)
1136where FILEPOS can be nil or a pair (LINENUMBER . COLUMNNUMBER).
448f754f 1137PROC is the client that requested this operation.
dfa35e6b
RS
1138NOWAIT non-nil means this client is not waiting for the results,
1139so don't mark these buffers specially, just visit them normally."
e82e73c2 1140 ;; Bind last-nonmenu-event to force use of keyboard, not mouse, for queries.
44a56b29 1141 (let ((last-nonmenu-event t) client-record)
3a0ce849
RS
1142 ;; Restore the current buffer afterward, but not using save-excursion,
1143 ;; because we don't want to save point in this buffer
1144 ;; if it happens to be one of those specified by the server.
44a56b29
SM
1145 (save-current-buffer
1146 (dolist (file files)
1147 ;; If there is an existing buffer modified or the file is
1148 ;; modified, revert it. If there is an existing buffer with
1149 ;; deleted file, offer to write it.
cd7320d4 1150 (let* ((minibuffer-auto-raise (or server-raise-frame
974b73e8 1151 minibuffer-auto-raise))
c2d0d432 1152 (filen (car file))
44a56b29 1153 (obuf (get-file-buffer filen)))
c398358a 1154 (add-to-history 'file-name-history filen)
656d4706
SM
1155 (if (null obuf)
1156 (set-buffer (find-file-noselect filen))
1157 (set-buffer obuf)
1158 (cond ((file-exists-p filen)
1159 (when (not (verify-visited-file-modtime obuf))
1160 (revert-buffer t nil)))
1161 (t
1162 (when (y-or-n-p
1163 (concat "File no longer exists: " filen
1164 ", write buffer to file? "))
1165 (write-file filen))))
1166 (unless server-buffer-clients
1167 (setq server-existing-buffer t)))
1168 (server-goto-line-column (cdr file))
1169 (run-hooks 'server-visit-hook))
44a56b29
SM
1170 (unless nowait
1171 ;; When the buffer is killed, inform the clients.
1172 (add-hook 'kill-buffer-hook 'server-kill-buffer nil t)
448f754f 1173 (push proc server-buffer-clients))
c5b0a355
KL
1174 (push (current-buffer) client-record)))
1175 (unless nowait
448f754f
SM
1176 (process-put proc 'buffers
1177 (nconc (process-get proc 'buffers) client-record)))
c5b0a355 1178 client-record))
9ae0f972 1179\f
b392bac9 1180(defun server-buffer-done (buffer &optional for-killing)
9ae0f972 1181 "Mark BUFFER as \"done\" for its client(s).
9184aafb
RS
1182This buries the buffer, then returns a list of the form (NEXT-BUFFER KILLED).
1183NEXT-BUFFER is another server buffer, as a suggestion for what to select next,
8b3e840e
SM
1184or nil. KILLED is t if we killed BUFFER (typically, because it was visiting
1185a temp file).
1186FOR-KILLING if non-nil indicates that we are called from `kill-buffer'."
0c851d78 1187 (let ((next-buffer nil)
9002956f 1188 (killed nil))
448f754f
SM
1189 (dolist (proc server-clients)
1190 (let ((buffers (process-get proc 'buffers)))
8b3e840e 1191 (or next-buffer
9002956f
KL
1192 (setq next-buffer (nth 1 (memq buffer buffers))))
1193 (when buffers ; Ignore bufferless clients.
1194 (setq buffers (delq buffer buffers))
448f754f 1195 ;; Delete all dead buffers from PROC.
9002956f
KL
1196 (dolist (b buffers)
1197 (and (bufferp b)
1198 (not (buffer-live-p b))
1199 (setq buffers (delq b buffers))))
448f754f 1200 (process-put proc 'buffers buffers)
9002956f
KL
1201 ;; If client now has no pending buffers,
1202 ;; tell it that it is done, and forget it entirely.
1203 (unless buffers
448f754f 1204 (server-log "Close" proc)
737e5c83
CY
1205 (if for-killing
1206 ;; `server-delete-client' might delete the client's
1207 ;; frames, which might change the current buffer. We
1208 ;; don't want that (bug#640).
1209 (save-current-buffer
1210 (server-delete-client proc))
1211 (server-delete-client proc))))))
337e3c70
JB
1212 (when (and (bufferp buffer) (buffer-name buffer))
1213 ;; We may or may not kill this buffer;
1214 ;; if we do, do not call server-buffer-done recursively
1215 ;; from kill-buffer-hook.
1216 (let ((server-kill-buffer-running t))
1217 (with-current-buffer buffer
1218 (setq server-buffer-clients nil)
1219 (run-hooks 'server-done-hook))
1220 ;; Notice whether server-done-hook killed the buffer.
1221 (if (null (buffer-name buffer))
1222 (setq killed t)
1223 ;; Don't bother killing or burying the buffer
1224 ;; when we are called from kill-buffer.
1225 (unless for-killing
1226 (when (and (not killed)
1227 server-kill-new-buffers
1228 (with-current-buffer buffer
1229 (not server-existing-buffer)))
599f9a5c 1230 (setq killed t)
337e3c70 1231 (bury-buffer buffer)
2d25aa5a
CY
1232 ;; Prevent kill-buffer from prompting (Bug#3696).
1233 (with-current-buffer buffer
1234 (set-buffer-modified-p nil))
337e3c70
JB
1235 (kill-buffer buffer))
1236 (unless killed
1237 (if (server-temp-file-p buffer)
1238 (progn
2d25aa5a
CY
1239 (with-current-buffer buffer
1240 (set-buffer-modified-p nil))
337e3c70
JB
1241 (kill-buffer buffer)
1242 (setq killed t))
1243 (bury-buffer buffer)))))))
9184aafb 1244 (list next-buffer killed)))
9ae0f972 1245
408784a7 1246(defun server-temp-file-p (&optional buffer)
9ae0f972 1247 "Return non-nil if BUFFER contains a file considered temporary.
1248These are files whose names suggest they are repeatedly
1249reused to pass information to another program.
1250
1251The variable `server-temp-file-regexp' controls which filenames
1252are considered temporary."
1253 (and (buffer-file-name buffer)
a77ad240 1254 (string-match-p server-temp-file-regexp (buffer-file-name buffer))))
9ae0f972 1255
1256(defun server-done ()
cc9875f9 1257 "Offer to save current buffer, mark it as \"done\" for clients.
ed9ae328
RS
1258This kills or buries the buffer, then returns a list
1259of the form (NEXT-BUFFER KILLED). NEXT-BUFFER is another server buffer,
1260as a suggestion for what to select next, or nil.
1261KILLED is t if we killed BUFFER, which happens if it was created
1262specifically for the clients and did not exist before their request for it."
408784a7
SM
1263 (when server-buffer-clients
1264 (if (server-temp-file-p)
1265 ;; For a temp file, save, and do make a non-numeric backup
1266 ;; (unless make-backup-files is nil).
1267 (let ((version-control nil)
1268 (buffer-backed-up nil))
1269 (save-buffer))
337e3c70
JB
1270 (when (and (buffer-modified-p)
1271 buffer-file-name
1272 (y-or-n-p (concat "Save file " buffer-file-name "? ")))
1273 (save-buffer)))
408784a7 1274 (server-buffer-done (current-buffer))))
faf931a8 1275
71207de2
RS
1276;; Ask before killing a server buffer.
1277;; It was suggested to release its client instead,
1278;; but I think that is dangerous--the client would proceed
1279;; using whatever is on disk in that file. -- rms.
03d78665 1280(defun server-kill-buffer-query-function ()
9002956f 1281 "Ask before killing a server buffer."
03d78665 1282 (or (not server-buffer-clients)
114a8b8c
KL
1283 (let ((res t))
1284 (dolist (proc server-buffer-clients res)
448f754f
SM
1285 (when (and (memq proc server-clients)
1286 (eq (process-status proc) 'open))
1287 (setq res nil))))
03d78665
RS
1288 (yes-or-no-p (format "Buffer `%s' still has clients; kill it? "
1289 (buffer-name (current-buffer))))))
1290
03d78665 1291(defun server-kill-emacs-query-function ()
c48254fb 1292 "Ask before exiting Emacs if it has live clients."
9002956f
KL
1293 (or (not server-clients)
1294 (let (live-client)
448f754f
SM
1295 (dolist (proc server-clients live-client)
1296 (when (memq t (mapcar 'buffer-live-p (process-get
1297 proc 'buffers)))
974b73e8 1298 (setq live-client t))))
9002956f 1299 (yes-or-no-p "This Emacs session has clients; exit anyway? ")))
b392bac9 1300
fb873cfc 1301(defvar server-kill-buffer-running nil
599f9a5c 1302 "Non-nil while `server-kill-buffer' or `server-buffer-done' is running.")
fb873cfc 1303
b392bac9 1304(defun server-kill-buffer ()
6d3a46f7
KL
1305 "Remove the current buffer from its clients' buffer list.
1306Designed to be added to `kill-buffer-hook'."
fb873cfc
RS
1307 ;; Prevent infinite recursion if user has made server-done-hook
1308 ;; call kill-buffer.
1309 (or server-kill-buffer-running
599f9a5c
RS
1310 (and server-buffer-clients
1311 (let ((server-kill-buffer-running t))
1312 (when server-process
1313 (server-buffer-done (current-buffer) t))))))
9ae0f972 1314\f
1315(defun server-edit (&optional arg)
1316 "Switch to next server editing buffer; say \"Done\" for current buffer.
1317If a server buffer is current, it is marked \"done\" and optionally saved.
ed9ae328 1318The buffer is also killed if it did not exist before the clients asked for it.
9ae0f972 1319When all of a client's buffers are marked as \"done\", the client is notified.
1320
1321Temporary files such as MH <draft> files are always saved and backed up,
991298c3
RS
1322no questions asked. (The variable `make-backup-files', if nil, still
1323inhibits a backup; you can set it locally in a particular buffer to
1324prevent a backup for it.) The variable `server-temp-file-regexp' controls
9ae0f972 1325which filenames are considered temporary.
1326
64f51134 1327If invoked with a prefix argument, or if there is no server process running,
9ae0f972 1328starts server process and that is all. Invoked by \\[server-edit]."
9ae0f972 1329 (interactive "P")
6b519504 1330 (cond
95eefb35
JB
1331 ((or arg
1332 (not server-process)
1333 (memq (process-status server-process) '(signal exit)))
1334 (server-mode 1))
1335 (server-clients (apply 'server-switch-buffer (server-done)))
1336 (t (message "No server editing buffers exist"))))
9ae0f972 1337
ee0aed46 1338(defun server-switch-buffer (&optional next-buffer killed-one filepos)
9ae0f972 1339 "Switch to another buffer, preferably one that has a client.
6d3a46f7
KL
1340Arg NEXT-BUFFER is a suggestion; if it is a live buffer, use it.
1341
1342KILLED-ONE is t in a recursive call if we have already killed one
1343temp-file server buffer. This means we should avoid the final
1344\"switch to some other buffer\" since we've already effectively
ee0aed46
CY
1345done that.
1346
1347FILEPOS specifies a new buffer position for NEXT-BUFFER, if we
1348visit NEXT-BUFFER in an existing window. If non-nil, it should
1349be a cons cell (LINENUMBER . COLUMNNUMBER)."
ca0c7250 1350 (if (null next-buffer)
9002956f
KL
1351 (progn
1352 (let ((rest server-clients))
1353 (while (and rest (not next-buffer))
448f754f 1354 (let ((proc (car rest)))
a7ce6c7f
AS
1355 ;; Only look at frameless clients, or those in the selected
1356 ;; frame.
1357 (when (or (not (process-get proc 'frame))
1358 (eq (process-get proc 'frame) (selected-frame)))
448f754f 1359 (setq next-buffer (car (process-get proc 'buffers))))
9002956f
KL
1360 (setq rest (cdr rest)))))
1361 (and next-buffer (server-switch-buffer next-buffer killed-one))
1362 (unless (or next-buffer killed-one (window-dedicated-p (selected-window)))
1363 ;; (switch-to-buffer (other-buffer))
90ee5627 1364 (message "No server buffers remain to edit")))
9002956f 1365 (if (not (buffer-live-p next-buffer))
ca0c7250 1366 ;; If NEXT-BUFFER is a dead buffer, remove the server records for it
9ae0f972 1367 ;; and try the next surviving server buffer.
ca0c7250
SM
1368 (apply 'server-switch-buffer (server-buffer-done next-buffer))
1369 ;; OK, we know next-buffer is live, let's display and select it.
408784a7
SM
1370 (if (functionp server-window)
1371 (funcall server-window next-buffer)
1372 (let ((win (get-buffer-window next-buffer 0)))
1373 (if (and win (not server-window))
ee0aed46
CY
1374 ;; The buffer is already displayed: just reuse the
1375 ;; window. If FILEPOS is non-nil, use it to replace the
1376 ;; window's own value of point.
90caccca
JB
1377 (progn
1378 (select-window win)
ee0aed46
CY
1379 (set-buffer next-buffer)
1380 (when filepos
1381 (server-goto-line-column filepos)))
408784a7 1382 ;; Otherwise, let's find an appropriate window.
60b4b298 1383 (cond ((window-live-p server-window)
408784a7
SM
1384 (select-window server-window))
1385 ((framep server-window)
337e3c70
JB
1386 (unless (frame-live-p server-window)
1387 (setq server-window (make-frame)))
408784a7 1388 (select-window (frame-selected-window server-window))))
337e3c70
JB
1389 (when (window-minibuffer-p (selected-window))
1390 (select-window (next-window nil 'nomini 0)))
408784a7
SM
1391 ;; Move to a non-dedicated window, if we have one.
1392 (when (window-dedicated-p (selected-window))
1393 (select-window
1394 (get-window-with-predicate
1395 (lambda (w)
1396 (and (not (window-dedicated-p w))
6ed8eeff
KL
1397 (equal (frame-terminal (window-frame w))
1398 (frame-terminal (selected-frame)))))
408784a7
SM
1399 'nomini 'visible (selected-window))))
1400 (condition-case nil
1401 (switch-to-buffer next-buffer)
1402 ;; After all the above, we might still have ended up with
1403 ;; a minibuffer/dedicated-window (if there's no other).
90caccca
JB
1404 (error (pop-to-buffer next-buffer)))))))
1405 (when server-raise-frame
1406 (select-frame-set-input-focus (window-frame (selected-window))))))
9ae0f972 1407
59e085e0 1408;;;###autoload
ac088d51 1409(defun server-save-buffers-kill-terminal (arg)
c61a4448 1410 ;; Called from save-buffers-kill-terminal in files.el.
ac088d51 1411 "Offer to save each buffer, then kill the current client.
a77ad240 1412With ARG non-nil, silently save all file-visiting buffers, then kill.
7540c1e0
KL
1413
1414If emacsclient was started with a list of filenames to edit, then
1415only these files will be asked to be saved."
ac088d51
CY
1416 (let ((proc (frame-parameter (selected-frame) 'client)))
1417 (cond ((eq proc 'nowait)
1418 ;; Nowait frames have no client buffer list.
1419 (if (cdr (frame-list))
1420 (progn (save-some-buffers arg)
1421 (delete-frame))
1422 ;; If we're the last frame standing, kill Emacs.
1423 (save-buffers-kill-emacs arg)))
1424 ((processp proc)
1425 (let ((buffers (process-get proc 'buffers)))
1426 ;; If client is bufferless, emulate a normal Emacs exit
1427 ;; and offer to save all buffers. Otherwise, offer to
1428 ;; save only the buffers belonging to the client.
1429 (save-some-buffers
1430 arg (if buffers
1431 (lambda () (memq (current-buffer) buffers))
1432 t))
1433 (server-delete-client proc)))
1434 (t (error "Invalid client frame")))))
b4ca0271 1435
772c5eb7 1436(define-key ctl-x-map "#" 'server-edit)
df4e8a11 1437
08446d5e 1438(defun server-unload-function ()
6d3a46f7 1439 "Unload the server library."
2e8457a0 1440 (server-mode -1)
a8e0c053 1441 (substitute-key-definition 'server-edit nil ctl-x-map)
08446d5e
JB
1442 (save-current-buffer
1443 (dolist (buffer (buffer-list))
1444 (set-buffer buffer)
1445 (remove-hook 'kill-buffer-hook 'server-kill-buffer t)))
1446 ;; continue standard unloading
1447 nil)
3bb38bc2 1448
16c15321
RM
1449\f
1450(provide 'server)
c88ab9ce 1451
2e8457a0 1452;; arch-tag: 1f7ecb42-f00a-49f8-906d-61995d84c8d6
c88ab9ce 1453;;; server.el ends here