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