Fix crashes in xdialog_show (and other places) with xterm-mouse-mode.
[bpt/emacs.git] / lib-src / emacsclient.c
CommitLineData
efb859b4 1/* Client process that communicates with GNU Emacs acting as server.
92b47a4a
TTN
2 Copyright (C) 1986, 1987, 1994, 1999, 2000, 2001, 2002, 2003, 2004,
3 2005 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
182 /* `emacsclient --no-wait' should open a new permanent frame, then exit.
183 Otherwise, --no-wait always implies --current-frame. */
184 if (nowait && argc - optind > 0)
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
KL
697 /* Send over our environment. */
698 {
699 extern char **environ;
700 int i;
701 for (i = 0; environ[i]; i++)
702 {
703 char *name = xstrdup (environ[i]);
704 char *value = strchr (name, '=');
705 if (value && strlen (value) > 1)
706 {
707 *value++ = 0;
708 fprintf (out, "-env ");
709 quote_argument (name, out);
710 fprintf (out, " ");
711 quote_argument (value, out);
712 fprintf (out, " ");
713 fflush (out);
714 }
715 free (name);
716 }
717 }
718
6afdd335 719 retry:
5212210c
RS
720 if (nowait)
721 fprintf (out, "-nowait ");
292d74a3 722
92071250
KL
723 if (current_frame)
724 fprintf (out, "-current-frame ");
725
30be2360 726 if (display)
87209357
EZ
727 {
728 fprintf (out, "-display ");
0b0d3e0b 729 quote_argument (display, out);
87209357
EZ
730 fprintf (out, " ");
731 }
30be2360 732
77134727 733 if (tty)
9628b887 734 {
4d553a13 735 char *tty_name = ttyname (fileno (stdin));
2fc0cf2a 736 char *type = getenv ("TERM");
0b0d3e0b 737
4d553a13 738 if (! tty_name)
2fc0cf2a
KL
739 {
740 fprintf (stderr, "%s: could not get terminal name\n", progname);
741 fail ();
742 }
743
744 if (! type)
745 {
746 fprintf (stderr, "%s: please set the TERM variable to your terminal type\n",
747 progname);
748 fail ();
749 }
750
751 if (! strcmp (type, "eterm"))
752 {
753 /* This causes nasty, MULTI_KBOARD-related input lockouts. */
754 fprintf (stderr, "%s: opening a frame in an Emacs term buffer"
755 " is not supported\n", progname);
756 fail ();
757 }
0b0d3e0b 758
4d553a13 759 init_signals ();
0b0d3e0b 760
819b8f00 761 fprintf (out, "-tty ");
0b0d3e0b 762 quote_argument (tty_name, out);
9628b887 763 fprintf (out, " ");
0b0d3e0b 764 quote_argument (type, out);
9628b887
KL
765 fprintf (out, " ");
766 }
77134727
KL
767
768 if (window_system)
769 fprintf (out, "-window-system ");
0b0d3e0b 770
87209357 771 if ((argc - optind > 0))
5212210c 772 {
87209357 773 for (i = optind; i < argc; i++)
46cec291 774 {
0b0d3e0b
KL
775 int relative = 0;
776
87209357 777 if (eval)
0b0d3e0b
KL
778 {
779 /* Don't prepend any cwd or anything like that. */
780 fprintf (out, "-eval ");
781 quote_argument (argv[i], out);
782 fprintf (out, " ");
783 continue;
784 }
785
786 if (*argv[i] == '+')
787 {
87209357
EZ
788 char *p = argv[i] + 1;
789 while (isdigit ((unsigned char) *p) || *p == ':') p++;
0b0d3e0b
KL
790 if (*p == 0)
791 {
792 fprintf (out, "-position ");
793 quote_argument (argv[i], out);
794 fprintf (out, " ");
795 continue;
796 }
797 else
798 relative = 1;
799 }
800 else if (*argv[i] != '/')
801 relative = 1;
802
803 fprintf (out, "-file ");
804 if (relative)
805 {
806 quote_argument (cwd, out);
807 fprintf (out, "/");
808 }
809 quote_argument (argv[i], out);
810 fprintf (out, " ");
811 }
46cec291 812 }
87209357
EZ
813 else
814 {
77134727 815 if (!tty && !window_system)
9628b887
KL
816 {
817 while ((str = fgets (string, BUFSIZ, stdin)))
818 {
0b0d3e0b
KL
819 if (eval)
820 fprintf (out, "-eval ");
821 else
822 fprintf (out, "-file ");
823 quote_argument (str, out);
9628b887
KL
824 }
825 fprintf (out, " ");
826 }
87209357 827 }
0b0d3e0b 828
46cec291
RS
829 fprintf (out, "\n");
830 fflush (out);
0b0d3e0b 831 fsync (fileno (out));
46cec291 832
fc2040c0
KL
833 /* Wait for an answer. */
834 if (!eval && !tty && !nowait)
30be2360
SM
835 {
836 printf ("Waiting for Emacs...");
837 needlf = 2;
838 }
46cec291 839 fflush (stdout);
0b0d3e0b 840 fsync (1);
46cec291 841
3cf8c6aa 842 /* Now, wait for an answer and print any messages. */
e69233c2 843 while ((str = fgets (string, BUFSIZ, in)))
3cf8c6aa 844 {
0b0d3e0b
KL
845 char *p = str + strlen (str) - 1;
846 while (p > str && *p == '\n')
847 *p-- = 0;
848
a9298135
KL
849 if (strprefix ("-good-version ", str))
850 {
6afdd335 851 /* -good-version: The versions match. */
a9298135 852 }
a9298135 853 else if (strprefix ("-emacs-pid ", str))
4d553a13 854 {
6afdd335 855 /* -emacs-pid PID: The process id of the Emacs process. */
77134727
KL
856 emacs_pid = strtol (string + strlen ("-emacs-pid"), NULL, 10);
857 }
6afdd335
KL
858 else if (strprefix ("-window-system-unsupported ", str))
859 {
860 /* -window-system-unsupported: Emacs was compiled without X
861 support. Try again on the terminal. */
862 window_system = 0;
863 nowait = 0;
864 tty = 1;
865 goto retry;
866 }
77134727
KL
867 else if (strprefix ("-print ", str))
868 {
6afdd335 869 /* -print STRING: Print STRING on the terminal. */
0b0d3e0b
KL
870 str = unquote_argument (str + strlen ("-print "));
871 if (needlf)
77134727 872 printf ("\n");
0b0d3e0b
KL
873 printf ("%s", str);
874 needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n';
77134727
KL
875 }
876 else if (strprefix ("-error ", str))
877 {
6afdd335 878 /* -error DESCRIPTION: Signal an error on the terminal. */
0b0d3e0b
KL
879 str = unquote_argument (str + strlen ("-error "));
880 if (needlf)
881 printf ("\n");
882 printf ("*ERROR*: %s", str);
883 needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n';
884 }
885 else if (strprefix ("-suspend ", str))
886 {
6afdd335 887 /* -suspend: Suspend this terminal, i.e., stop the process. */
0b0d3e0b 888 if (needlf)
77134727 889 printf ("\n");
0b0d3e0b
KL
890 needlf = 0;
891 kill (0, SIGSTOP);
4d553a13
KL
892 }
893 else
894 {
6afdd335 895 /* Unknown command. */
0b0d3e0b 896 if (needlf)
4d553a13 897 printf ("\n");
77134727 898 printf ("*ERROR*: Unknown message: %s", str);
4d553a13
KL
899 needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n';
900 }
3cf8c6aa
SM
901 }
902
903 if (needlf)
904 printf ("\n");
905 fflush (stdout);
0b0d3e0b 906 fsync (1);
23a7488d 907
65396510 908 return EXIT_SUCCESS;
46cec291
RS
909}
910
30be2360 911#endif /* HAVE_SOCKETS */
27711600
RM
912\f
913#ifndef HAVE_STRERROR
914char *
915strerror (errnum)
916 int errnum;
917{
918 extern char *sys_errlist[];
919 extern int sys_nerr;
920
921 if (errnum >= 0 && errnum < sys_nerr)
922 return sys_errlist[errnum];
923 return (char *) "Unknown error";
924}
925
926#endif /* ! HAVE_STRERROR */
ab5796a9
MB
927
928/* arch-tag: f39bb9c4-73eb-477e-896d-50832e2ca9a7
929 (do not change this comment) */
65396510
TTN
930
931/* emacsclient.c ends here */