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