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