Clean up tty device handling. Change name of controlling tty from nil to "/dev/tty".
[bpt/emacs.git] / lib-src / emacsclient.c
CommitLineData
efb859b4 1/* Client process that communicates with GNU Emacs acting as server.
92b47a4a 2 Copyright (C) 1986, 1987, 1994, 1999, 2000, 2001, 2002, 2003, 2004,
273dc16a 3 2005, 2006 Free Software Foundation, Inc.
46cec291
RS
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
92af894f 9the Free Software Foundation; either version 2, or (at your option)
46cec291
RS
10any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs; see the file COPYING. If not, write to
364c38d3
LK
19the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20Boston, MA 02110-1301, USA. */
46cec291
RS
21
22
23#define NO_SHORTNAMES
e69233c2
PJ
24
25#ifdef HAVE_CONFIG_H
2f8fe2f4 26#include <config.h>
e69233c2
PJ
27#endif
28
4e23f2ba 29#undef signal
46cec291 30
e69233c2 31#include <ctype.h>
8f9aaa0a
RS
32#include <stdio.h>
33#include <getopt.h>
79f13bba
DL
34#ifdef HAVE_UNISTD_H
35#include <unistd.h>
36#endif
8f9aaa0a 37
9f637eea
GM
38#ifdef VMS
39# include "vms-pwd.h"
40#else
41# include <pwd.h>
42#endif /* not VMS */
43
9628b887 44#include <signal.h>
4d553a13 45#include <errno.h>
9628b887
KL
46
47\f
8f9aaa0a 48char *getenv (), *getwd ();
5b9562c3 49char *(getcwd) ();
8f9aaa0a 50
8f9aaa0a
RS
51#ifndef VERSION
52#define VERSION "unspecified"
53#endif
54\f
55/* Name used to invoke this program. */
56char *progname;
57
0a125897
KL
58/* The first argument to main. */
59int main_argc;
60
61/* The second argument to main. */
62char **main_argv;
63
749ae770 64/* Nonzero means don't wait for a response from Emacs. --no-wait. */
8f9aaa0a
RS
65int nowait = 0;
66
30be2360
SM
67/* Nonzero means args are expressions to be evaluated. --eval. */
68int eval = 0;
69
92071250
KL
70/* Nonzero means don't open a new frame. --current-frame. */
71int current_frame = 0;
72
77134727
KL
73/* Nonzero means open a new graphical frame. */
74int window_system = 0;
75
30be2360
SM
76/* The display on which Emacs should work. --display. */
77char *display = NULL;
78
9628b887 79/* Nonzero means open a new Emacs frame on the current terminal. */
77134727 80int tty = 0;
9628b887 81
30be2360
SM
82/* If non-NULL, the name of an editor to fallback to if the server
83 is not running. --alternate-editor. */
84const char * alternate_editor = NULL;
85
3db926be 86/* If non-NULL, the filename of the UNIX socket. */
254107e4
RS
87char *socket_name = NULL;
88
7f3bff3e
AS
89void print_help_and_exit ();
90
8f9aaa0a
RS
91struct option longopts[] =
92{
749ae770 93 { "no-wait", no_argument, NULL, 'n' },
30be2360 94 { "eval", no_argument, NULL, 'e' },
8f9aaa0a
RS
95 { "help", no_argument, NULL, 'H' },
96 { "version", no_argument, NULL, 'V' },
b28c910d 97 { "tty", no_argument, NULL, 't' },
e5299d8d 98 { "current-frame", no_argument, NULL, 'c' },
3cf8c6aa 99 { "alternate-editor", required_argument, NULL, 'a' },
254107e4 100 { "socket-name", required_argument, NULL, 's' },
30be2360
SM
101 { "display", required_argument, NULL, 'd' },
102 { 0, 0, 0, 0 }
8f9aaa0a
RS
103};
104
105/* Decode the options from argv and argc.
5212210c 106 The global variable `optind' will say how many arguments we used up. */
8f9aaa0a 107
5212210c 108void
8f9aaa0a
RS
109decode_options (argc, argv)
110 int argc;
111 char **argv;
112{
b6b6d6d2 113 alternate_editor = getenv ("ALTERNATE_EDITOR");
77134727 114 display = getenv ("DISPLAY");
8689463a 115 if (display && strlen (display) == 0)
e5299d8d 116 display = NULL;
0b0d3e0b 117
8f9aaa0a
RS
118 while (1)
119 {
120 int opt = getopt_long (argc, argv,
e5299d8d 121 "VHnea:s:d:tc", longopts, 0);
8f9aaa0a
RS
122
123 if (opt == EOF)
124 break;
125
126 switch (opt)
127 {
128 case 0:
129 /* If getopt returns 0, then it has already processed a
130 long-named option. We should do nothing. */
131 break;
e69233c2 132
97e3214d
GM
133 case 'a':
134 alternate_editor = optarg;
135 break;
e69233c2 136
254107e4
RS
137 case 's':
138 socket_name = optarg;
139 break;
140
30be2360
SM
141 case 'd':
142 display = optarg;
143 break;
144
8f9aaa0a
RS
145 case 'n':
146 nowait = 1;
147 break;
148
30be2360
SM
149 case 'e':
150 eval = 1;
151 break;
152
8f9aaa0a 153 case 'V':
20c396e8 154 printf ("emacsclient %s\n", VERSION);
65396510 155 exit (EXIT_SUCCESS);
8f9aaa0a 156 break;
46cec291 157
819b8f00 158 case 't':
77134727 159 tty = 1;
77134727
KL
160 break;
161
e5299d8d 162 case 'c':
92071250 163 current_frame = 1;
9628b887 164 break;
0b0d3e0b 165
8f9aaa0a 166 case 'H':
8f9aaa0a 167 print_help_and_exit ();
20c396e8
JB
168 break;
169
170 default:
171 fprintf (stderr, "Try `%s --help' for more information\n", progname);
65396510 172 exit (EXIT_FAILURE);
20c396e8 173 break;
8f9aaa0a
RS
174 }
175 }
9628b887 176
92071250
KL
177 if (!tty && display)
178 window_system = 1;
179 else
180 tty = 1;
181
b8ccaf6f
KL
182 /* --no-wait implies --current-frame on ttys when there are file
183 arguments or expressions given. */
184 if (nowait && tty && argc - optind > 0)
92071250
KL
185 current_frame = 1;
186
187 if (current_frame)
188 {
189 tty = 0;
190 window_system = 0;
191 }
192
193 if (tty)
194 window_system = 0;
8f9aaa0a
RS
195}
196
7f3bff3e 197void
8f9aaa0a
RS
198print_help_and_exit ()
199{
20c396e8
JB
200 printf (
201 "Usage: %s [OPTIONS] FILE...\n\
30be2360
SM
202Tell the Emacs server to visit the specified files.\n\
203Every FILE can be either just a FILENAME or [+LINE[:COLUMN]] FILENAME.\n\
20c396e8 204\n\
30be2360
SM
205The following OPTIONS are accepted:\n\
206-V, --version Just print a version info and return\n\
207-H, --help Print this usage information message\n\
819b8f00 208-t, --tty Open a new Emacs frame on the current terminal\n\
e5299d8d 209-c, --current-frame Do not create a new frame; use the current Emacs frame\n\
30be2360
SM
210-n, --no-wait Don't wait for the server to return\n\
211-e, --eval Evaluate the FILE arguments as ELisp expressions\n\
212-d, --display=DISPLAY Visit the file in the given display\n\
254107e4
RS
213-s, --socket-name=FILENAME\n\
214 Set the filename of the UNIX socket for communication\n\
30be2360
SM
215-a, --alternate-editor=EDITOR\n\
216 Editor to fallback to if the server is not running\n\
20c396e8 217\n\
30be2360 218Report bugs to bug-gnu-emacs@gnu.org.\n", progname);
65396510 219 exit (EXIT_SUCCESS);
8f9aaa0a 220}
5212210c 221
9002956f
KL
222/* Like malloc but get fatal error if memory is exhausted. */
223
224long *
225xmalloc (size)
226 unsigned int size;
227{
228 long *result = (long *) malloc (size);
229 if (result == NULL)
230 {
231 perror ("malloc");
ab4b17be 232 exit (EXIT_FAILURE);
9002956f
KL
233 }
234 return result;
235}
236
237/* Like strdup but get a fatal error if memory is exhausted. */
238
239char *
240xstrdup (const char *s)
241{
242 char *result = strdup (s);
243 if (result == NULL)
244 {
245 perror ("strdup");
ab4b17be 246 exit (EXIT_FAILURE);
9002956f
KL
247 }
248 return result;
249}
250
0b0d3e0b 251/* In STR, insert a & before each &, each space, each newline, and
a4cf2096 252 any initial -. Change spaces to underscores, too, so that the
0b0d3e0b
KL
253 return value never contains a space.
254
255 Does not change the string. Outputs the result to STREAM. */
5212210c 256
87209357 257void
0b0d3e0b
KL
258quote_argument (str, stream)
259 char *str;
87209357 260 FILE *stream;
5212210c 261{
9002956f 262 char *copy = (char *) xmalloc (strlen (str) * 2 + 1);
5212210c
RS
263 char *p, *q;
264
0b0d3e0b 265 p = str;
5212210c
RS
266 q = copy;
267 while (*p)
268 {
269 if (*p == ' ')
270 {
f1db6a73 271 *q++ = '&';
5212210c
RS
272 *q++ = '_';
273 p++;
274 }
3cf8c6aa
SM
275 else if (*p == '\n')
276 {
277 *q++ = '&';
278 *q++ = 'n';
279 p++;
280 }
5212210c
RS
281 else
282 {
0b0d3e0b 283 if (*p == '&' || (*p == '-' && p == str))
f1db6a73 284 *q++ = '&';
5212210c
RS
285 *q++ = *p++;
286 }
287 }
f1db6a73 288 *q++ = 0;
5212210c 289
60879731 290 fprintf (stream, "%s", copy);
87209357
EZ
291
292 free (copy);
5212210c 293}
0c76956f 294
0b0d3e0b
KL
295
296/* The inverse of quote_argument. Removes quoting in string STR by
297 modifying the string in place. Returns STR. */
298
299char *
300unquote_argument (str)
301 char *str;
302{
303 char *p, *q;
304
305 if (! str)
306 return str;
307
308 p = str;
309 q = str;
310 while (*p)
311 {
312 if (*p == '&')
313 {
314 p++;
315 if (*p == '&')
316 *p = '&';
317 else if (*p == '_')
318 *p = ' ';
319 else if (*p == 'n')
320 *p = '\n';
321 else if (*p == '-')
322 *p = '-';
323 }
324 *q++ = *p++;
325 }
326 *q = 0;
327 return str;
328}
329
8f9aaa0a 330\f
97e3214d
GM
331/*
332 Try to run a different command, or --if no alternate editor is
333 defined-- exit with an errorcode.
334*/
de073ce3 335void
819b8f00 336fail (void)
97e3214d
GM
337{
338 if (alternate_editor)
339 {
3cf8c6aa 340 int i = optind - 1;
0a125897 341 execvp (alternate_editor, main_argv + i);
23431241 342 return;
97e3214d
GM
343 }
344 else
345 {
65396510 346 exit (EXIT_FAILURE);
97e3214d
GM
347 }
348}
349
0b0d3e0b 350/* The process id of Emacs. */
6548cf00 351int emacs_pid;
9628b887 352
0b0d3e0b
KL
353/* File handles for communicating with Emacs. */
354FILE *out, *in;
355
da8e1115
KL
356/* A signal handler that passes the signal to the Emacs process.
357 Useful for SIGWINCH. */
358
9628b887 359SIGTYPE
428a555e 360pass_signal_to_emacs (int signalnum)
9628b887
KL
361{
362 int old_errno = errno;
363
9f729af5 364 if (emacs_pid)
428a555e 365 kill (emacs_pid, signalnum);
9f729af5 366
428a555e 367 signal (signalnum, pass_signal_to_emacs);
9f729af5
KL
368 errno = old_errno;
369}
370
0b0d3e0b
KL
371/* Signal handler for SIGCONT; notify the Emacs process that it can
372 now resume our tty frame. */
373
374SIGTYPE
375handle_sigcont (int signalnum)
376{
377 int old_errno = errno;
378
379 if (tcgetpgrp (1) == getpgrp ())
380 {
381 /* We are in the foreground. */
382 fprintf (out, "-resume \n");
383 fflush (out);
384 fsync (fileno (out));
385 }
386 else
387 {
388 /* We are in the background; cancel the continue. */
389 kill (getpid (), SIGSTOP);
390 }
c6c53c3e
KL
391
392 signal (signalnum, handle_sigcont);
0b0d3e0b
KL
393 errno = old_errno;
394}
395
396/* Signal handler for SIGTSTP; notify the Emacs process that we are
397 going to sleep. Normally the suspend is initiated by Emacs via
398 server-handle-suspend-tty, but if the server gets out of sync with
399 reality, we may get a SIGTSTP on C-z. Handling this signal and
400 notifying Emacs about it should get things under control again. */
401
402SIGTYPE
403handle_sigtstp (int signalnum)
404{
405 int old_errno = errno;
406 sigset_t set;
407
408 if (out)
409 {
410 fprintf (out, "-suspend \n");
411 fflush (out);
412 fsync (fileno (out));
413 }
414
415 /* Unblock this signal and call the default handler by temprarily
416 changing the handler and resignalling. */
417 sigprocmask (SIG_BLOCK, NULL, &set);
418 sigdelset (&set, signalnum);
419 signal (signalnum, SIG_DFL);
420 kill (getpid (), signalnum);
421 sigprocmask (SIG_SETMASK, &set, NULL); /* Let's the above signal through. */
422 signal (signalnum, handle_sigtstp);
423
424 errno = old_errno;
425}
426
da8e1115 427/* Set up signal handlers before opening a frame on the current tty. */
0b0d3e0b 428
4d553a13
KL
429void
430init_signals (void)
9628b887
KL
431{
432 /* Set up signal handlers. */
428a555e 433 signal (SIGWINCH, pass_signal_to_emacs);
4ca927b4
KL
434
435 /* Don't pass SIGINT and SIGQUIT to Emacs, because it has no way of
436 deciding which terminal the signal came from. C-g is now a
437 normal input event on secondary terminals. */
438#if 0
428a555e
KL
439 signal (SIGINT, pass_signal_to_emacs);
440 signal (SIGQUIT, pass_signal_to_emacs);
4ca927b4 441#endif
0b0d3e0b
KL
442
443 signal (SIGCONT, handle_sigcont);
444 signal (SIGTSTP, handle_sigtstp);
445 signal (SIGTTOU, handle_sigtstp);
9628b887
KL
446}
447
97e3214d 448\f
30be2360 449#if !defined (HAVE_SOCKETS) || defined (NO_SOCKETS_IN_FILE_SYSTEM)
46cec291 450
de073ce3 451int
46cec291
RS
452main (argc, argv)
453 int argc;
454 char **argv;
455{
456 fprintf (stderr, "%s: Sorry, the Emacs server is supported only\n",
457 argv[0]);
30be2360 458 fprintf (stderr, "on systems with Berkeley sockets.\n");
97e3214d 459
819b8f00 460 fail ();
46cec291
RS
461}
462
30be2360 463#else /* HAVE_SOCKETS */
46cec291
RS
464
465#include <sys/types.h>
466#include <sys/socket.h>
467#include <sys/un.h>
efb859b4 468#include <sys/stat.h>
46cec291
RS
469#include <errno.h>
470
92af894f 471extern char *strerror ();
46cec291
RS
472extern int errno;
473
9f637eea
GM
474/* Three possibilities:
475 2 - can't be `stat'ed (sets errno)
476 1 - isn't owned by us
477 0 - success: none of the above */
478
479static int
480socket_status (socket_name)
481 char *socket_name;
482{
483 struct stat statbfr;
484
485 if (stat (socket_name, &statbfr) == -1)
486 return 2;
487
488 if (statbfr.st_uid != geteuid ())
489 return 1;
490
491 return 0;
492}
493
4d553a13
KL
494/* Returns 1 if PREFIX is a prefix of STRING. */
495static int
496strprefix (char *prefix, char *string)
497{
498 int i;
499 if (! prefix)
500 return 1;
501
502 if (!string)
503 return 0;
0b0d3e0b 504
4d553a13
KL
505 for (i = 0; prefix[i]; i++)
506 if (!string[i] || string[i] != prefix[i])
507 return 0;
508 return 1;
509}
510
340ff9de 511int
46cec291
RS
512main (argc, argv)
513 int argc;
514 char **argv;
515{
3cf8c6aa 516 int s, i, needlf = 0;
46cec291 517 struct sockaddr_un server;
571512de 518 char *cwd, *str;
46cec291 519 char string[BUFSIZ];
8f9aaa0a 520
0a125897
KL
521 main_argc = argc;
522 main_argv = argv;
8f9aaa0a 523 progname = argv[0];
46cec291 524
8f9aaa0a 525 /* Process options. */
5212210c 526 decode_options (argc, argv);
46cec291 527
77134727 528 if ((argc - optind < 1) && !eval && !tty && !window_system)
20c396e8
JB
529 {
530 fprintf (stderr, "%s: file name or argument required\n", progname);
531 fprintf (stderr, "Try `%s --help' for more information\n", progname);
65396510 532 exit (EXIT_FAILURE);
20c396e8 533 }
46cec291 534
e69233c2 535 /*
46cec291
RS
536 * Open up an AF_UNIX socket in this person's home directory
537 */
538
539 if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
540 {
541 fprintf (stderr, "%s: ", argv[0]);
542 perror ("socket");
819b8f00 543 fail ();
46cec291 544 }
e69233c2 545
46cec291 546 server.sun_family = AF_UNIX;
c5fee545 547
c5fee545 548 {
9f637eea 549 int sock_status = 0;
5c9659d3 550 int default_sock = !socket_name;
b80bf66e 551 int saved_errno = 0;
0b0d3e0b 552
d3a6748c 553 char *server_name = "server";
0b0d3e0b 554
d3a6748c
KL
555 if (socket_name && !index (socket_name, '/') && !index (socket_name, '\\'))
556 { /* socket_name is a file name component. */
557 server_name = socket_name;
558 socket_name = NULL;
559 default_sock = 1; /* Try both UIDs. */
560 }
efb859b4 561
d3a6748c 562 if (default_sock)
254107e4 563 {
d3a6748c
KL
564 socket_name = alloca (100 + strlen (server_name));
565 sprintf (socket_name, "/tmp/emacs%d/%s",
566 (int) geteuid (), server_name);
254107e4
RS
567 }
568
569 if (strlen (socket_name) < sizeof (server.sun_path))
570 strcpy (server.sun_path, socket_name);
571 else
819b8f00
KL
572 {
573 fprintf (stderr, "%s: socket-name %s too long",
574 argv[0], socket_name);
575 fail ();
576 }
efb859b4 577
9f637eea
GM
578 /* See if the socket exists, and if it's owned by us. */
579 sock_status = socket_status (server.sun_path);
152b6e83 580 saved_errno = errno;
5c9659d3 581 if (sock_status && default_sock)
efb859b4 582 {
9f637eea
GM
583 /* Failing that, see if LOGNAME or USER exist and differ from
584 our euid. If so, look for a socket based on the UID
585 associated with the name. This is reminiscent of the logic
586 that init_editfns uses to set the global Vuser_full_name. */
e69233c2 587
9f637eea 588 char *user_name = (char *) getenv ("LOGNAME");
293f9f2a 589
9f637eea
GM
590 if (!user_name)
591 user_name = (char *) getenv ("USER");
e69233c2 592
9f637eea
GM
593 if (user_name)
594 {
595 struct passwd *pw = getpwnam (user_name);
293f9f2a 596
9f637eea
GM
597 if (pw && (pw->pw_uid != geteuid ()))
598 {
599 /* We're running under su, apparently. */
0734b0d0
SM
600 socket_name = alloca (100 + strlen (server_name));
601 sprintf (socket_name, "/tmp/emacs%d/%s",
602 (int) pw->pw_uid, server_name);
5c9659d3
SM
603
604 if (strlen (socket_name) < sizeof (server.sun_path))
605 strcpy (server.sun_path, socket_name);
606 else
607 {
608 fprintf (stderr, "%s: socket-name %s too long",
609 argv[0], socket_name);
65396510 610 exit (EXIT_FAILURE);
5c9659d3
SM
611 }
612
9f637eea 613 sock_status = socket_status (server.sun_path);
b80bf66e 614 saved_errno = errno;
9f637eea 615 }
293f9f2a
RS
616 else
617 errno = saved_errno;
9f637eea 618 }
efb859b4 619 }
e69233c2 620
9f637eea
GM
621 switch (sock_status)
622 {
623 case 1:
624 /* There's a socket, but it isn't owned by us. This is OK if
625 we are root. */
626 if (0 != geteuid ())
627 {
628 fprintf (stderr, "%s: Invalid socket owner\n", argv[0]);
819b8f00 629 fail ();
9f637eea
GM
630 }
631 break;
e69233c2 632
9f637eea
GM
633 case 2:
634 /* `stat' failed */
152b6e83 635 if (saved_errno == ENOENT)
9f637eea 636 fprintf (stderr,
9002956f 637 "%s: can't find socket; have you started the server?\n\
45adde32 638To start the server in Emacs, type \"M-x server-start\".\n",
9f637eea
GM
639 argv[0]);
640 else
9002956f 641 fprintf (stderr, "%s: can't stat %s: %s\n",
152b6e83 642 argv[0], server.sun_path, strerror (saved_errno));
819b8f00 643 fail ();
9f637eea
GM
644 break;
645 }
efb859b4 646 }
46cec291 647
4e23f2ba
JB
648 if (connect (s, (struct sockaddr *) &server, strlen (server.sun_path) + 2)
649 < 0)
46cec291
RS
650 {
651 fprintf (stderr, "%s: ", argv[0]);
652 perror ("connect");
819b8f00 653 fail ();
46cec291 654 }
23a7488d 655
9002956f 656 /* We use the stream OUT to send our commands to the server. */
46cec291
RS
657 if ((out = fdopen (s, "r+")) == NULL)
658 {
659 fprintf (stderr, "%s: ", argv[0]);
660 perror ("fdopen");
819b8f00 661 fail ();
46cec291
RS
662 }
663
9002956f 664 /* We use the stream IN to read the responses.
23a7488d
RS
665 We used to use just one stream for both output and input
666 on the socket, but reversing direction works nonportably:
667 on some systems, the output appears as the first input;
668 on other systems it does not. */
669 if ((in = fdopen (s, "r+")) == NULL)
670 {
671 fprintf (stderr, "%s: ", argv[0]);
672 perror ("fdopen");
819b8f00 673 fail ();
23a7488d
RS
674 }
675
38732dba 676#ifdef HAVE_GETCWD
ee6a193c 677 cwd = getcwd (string, sizeof string);
38732dba
RS
678#else
679 cwd = getwd (string);
ee6a193c 680#endif
46cec291
RS
681 if (cwd == 0)
682 {
683 /* getwd puts message in STRING if it fails. */
bb5618fe 684
38732dba 685#ifdef HAVE_GETCWD
bb5618fe 686 fprintf (stderr, "%s: %s (%s)\n", argv[0],
9002956f 687 "cannot get current working directory", strerror (errno));
38732dba 688#else
bb5618fe 689 fprintf (stderr, "%s: %s (%s)\n", argv[0], string, strerror (errno));
bd252662 690#endif
819b8f00 691 fail ();
46cec291
RS
692 }
693
a9298135
KL
694 /* First of all, send our version number for verification. */
695 fprintf (out, "-version %s ", VERSION);
0b0d3e0b 696
9002956f 697 /* Send over our environment. */
59e085e0
KL
698 if (!current_frame)
699 {
700 extern char **environ;
701 int i;
702 for (i = 0; environ[i]; i++)
703 {
704 char *name = xstrdup (environ[i]);
705 char *value = strchr (name, '=');
706 fprintf (out, "-env ");
707 quote_argument (environ[i], out);
708 fprintf (out, " ");
709 }
710 }
9002956f 711
6afdd335 712 retry:
5212210c
RS
713 if (nowait)
714 fprintf (out, "-nowait ");
292d74a3 715
92071250
KL
716 if (current_frame)
717 fprintf (out, "-current-frame ");
718
30be2360 719 if (display)
87209357
EZ
720 {
721 fprintf (out, "-display ");
0b0d3e0b 722 quote_argument (display, out);
87209357
EZ
723 fprintf (out, " ");
724 }
30be2360 725
77134727 726 if (tty)
9628b887 727 {
4d553a13 728 char *tty_name = ttyname (fileno (stdin));
2fc0cf2a 729 char *type = getenv ("TERM");
0b0d3e0b 730
4d553a13 731 if (! tty_name)
2fc0cf2a
KL
732 {
733 fprintf (stderr, "%s: could not get terminal name\n", progname);
734 fail ();
735 }
736
737 if (! type)
738 {
739 fprintf (stderr, "%s: please set the TERM variable to your terminal type\n",
740 progname);
741 fail ();
742 }
743
744 if (! strcmp (type, "eterm"))
745 {
746 /* This causes nasty, MULTI_KBOARD-related input lockouts. */
747 fprintf (stderr, "%s: opening a frame in an Emacs term buffer"
748 " is not supported\n", progname);
749 fail ();
750 }
0b0d3e0b 751
4d553a13 752 init_signals ();
0b0d3e0b 753
819b8f00 754 fprintf (out, "-tty ");
0b0d3e0b 755 quote_argument (tty_name, out);
9628b887 756 fprintf (out, " ");
0b0d3e0b 757 quote_argument (type, out);
9628b887
KL
758 fprintf (out, " ");
759 }
77134727
KL
760
761 if (window_system)
762 fprintf (out, "-window-system ");
0b0d3e0b 763
87209357 764 if ((argc - optind > 0))
5212210c 765 {
87209357 766 for (i = optind; i < argc; i++)
46cec291 767 {
0b0d3e0b
KL
768 int relative = 0;
769
87209357 770 if (eval)
0b0d3e0b
KL
771 {
772 /* Don't prepend any cwd or anything like that. */
773 fprintf (out, "-eval ");
774 quote_argument (argv[i], out);
775 fprintf (out, " ");
776 continue;
777 }
778
779 if (*argv[i] == '+')
780 {
87209357
EZ
781 char *p = argv[i] + 1;
782 while (isdigit ((unsigned char) *p) || *p == ':') p++;
0b0d3e0b
KL
783 if (*p == 0)
784 {
785 fprintf (out, "-position ");
786 quote_argument (argv[i], out);
787 fprintf (out, " ");
788 continue;
789 }
790 else
791 relative = 1;
792 }
793 else if (*argv[i] != '/')
794 relative = 1;
795
796 fprintf (out, "-file ");
797 if (relative)
798 {
799 quote_argument (cwd, out);
800 fprintf (out, "/");
801 }
802 quote_argument (argv[i], out);
803 fprintf (out, " ");
804 }
46cec291 805 }
87209357
EZ
806 else
807 {
77134727 808 if (!tty && !window_system)
9628b887
KL
809 {
810 while ((str = fgets (string, BUFSIZ, stdin)))
811 {
0b0d3e0b
KL
812 if (eval)
813 fprintf (out, "-eval ");
814 else
815 fprintf (out, "-file ");
816 quote_argument (str, out);
9628b887
KL
817 }
818 fprintf (out, " ");
819 }
87209357 820 }
0b0d3e0b 821
46cec291
RS
822 fprintf (out, "\n");
823 fflush (out);
0b0d3e0b 824 fsync (fileno (out));
46cec291 825
fc2040c0
KL
826 /* Wait for an answer. */
827 if (!eval && !tty && !nowait)
30be2360
SM
828 {
829 printf ("Waiting for Emacs...");
830 needlf = 2;
831 }
46cec291 832 fflush (stdout);
0b0d3e0b 833 fsync (1);
46cec291 834
3cf8c6aa 835 /* Now, wait for an answer and print any messages. */
e69233c2 836 while ((str = fgets (string, BUFSIZ, in)))
3cf8c6aa 837 {
0b0d3e0b
KL
838 char *p = str + strlen (str) - 1;
839 while (p > str && *p == '\n')
840 *p-- = 0;
841
a9298135
KL
842 if (strprefix ("-good-version ", str))
843 {
6afdd335 844 /* -good-version: The versions match. */
a9298135 845 }
a9298135 846 else if (strprefix ("-emacs-pid ", str))
4d553a13 847 {
6afdd335 848 /* -emacs-pid PID: The process id of the Emacs process. */
77134727
KL
849 emacs_pid = strtol (string + strlen ("-emacs-pid"), NULL, 10);
850 }
6afdd335
KL
851 else if (strprefix ("-window-system-unsupported ", str))
852 {
853 /* -window-system-unsupported: Emacs was compiled without X
854 support. Try again on the terminal. */
855 window_system = 0;
856 nowait = 0;
857 tty = 1;
858 goto retry;
859 }
77134727
KL
860 else if (strprefix ("-print ", str))
861 {
6afdd335 862 /* -print STRING: Print STRING on the terminal. */
0b0d3e0b
KL
863 str = unquote_argument (str + strlen ("-print "));
864 if (needlf)
77134727 865 printf ("\n");
0b0d3e0b
KL
866 printf ("%s", str);
867 needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n';
77134727
KL
868 }
869 else if (strprefix ("-error ", str))
870 {
6afdd335 871 /* -error DESCRIPTION: Signal an error on the terminal. */
0b0d3e0b
KL
872 str = unquote_argument (str + strlen ("-error "));
873 if (needlf)
874 printf ("\n");
875 printf ("*ERROR*: %s", str);
876 needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n';
877 }
878 else if (strprefix ("-suspend ", str))
879 {
6afdd335 880 /* -suspend: Suspend this terminal, i.e., stop the process. */
0b0d3e0b 881 if (needlf)
77134727 882 printf ("\n");
0b0d3e0b
KL
883 needlf = 0;
884 kill (0, SIGSTOP);
4d553a13
KL
885 }
886 else
887 {
6afdd335 888 /* Unknown command. */
0b0d3e0b 889 if (needlf)
4d553a13 890 printf ("\n");
77134727 891 printf ("*ERROR*: Unknown message: %s", str);
4d553a13
KL
892 needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n';
893 }
3cf8c6aa
SM
894 }
895
896 if (needlf)
897 printf ("\n");
898 fflush (stdout);
0b0d3e0b 899 fsync (1);
23a7488d 900
65396510 901 return EXIT_SUCCESS;
46cec291
RS
902}
903
30be2360 904#endif /* HAVE_SOCKETS */
27711600
RM
905\f
906#ifndef HAVE_STRERROR
907char *
908strerror (errnum)
909 int errnum;
910{
911 extern char *sys_errlist[];
912 extern int sys_nerr;
913
914 if (errnum >= 0 && errnum < sys_nerr)
915 return sys_errlist[errnum];
916 return (char *) "Unknown error";
917}
918
919#endif /* ! HAVE_STRERROR */
ab5796a9
MB
920
921/* arch-tag: f39bb9c4-73eb-477e-896d-50832e2ca9a7
922 (do not change this comment) */
65396510
TTN
923
924/* emacsclient.c ends here */