]>
code.delx.au - gnu-emacs/blob - lib-src/emacsclient.c
2ad3701e07a4d0183f84a25c27ca19032684c0f4
1 /* Client process that communicates with GNU Emacs acting as server.
2 Copyright (C) 1986, 1987, 1994, 1999, 2000, 2001, 2002, 2003, 2004,
3 2005, 2006 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
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)
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.
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., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
35 # define HAVE_INET_SOCKETS
36 # define NO_SOCKETS_IN_FILE_SYSTEM
38 # define HSOCKET SOCKET
39 # define CLOSE_SOCKET closesocket
40 # define INITIALIZE() (initialize_sockets ())
42 #else /* !WINDOWSNT */
44 # ifdef HAVE_INET_SOCKETS
45 # include <netinet/in.h>
48 # define INVALID_SOCKET -1
50 # define CLOSE_SOCKET close
53 #endif /* !WINDOWSNT */
69 #else /* not WINDOWSNT */
71 #endif /* not WINDOWSNT */
74 char *getenv (), *getwd ();
78 #define VERSION "unspecified"
81 #define SEND_STRING(data) (send_to_emacs (s, (data)))
82 #define SEND_QUOTED(data) (quote_file_name (s, (data)))
85 #define EXIT_SUCCESS 0
89 #define EXIT_FAILURE 1
104 /* Name used to invoke this program. */
107 /* Nonzero means don't wait for a response from Emacs. --no-wait. */
110 /* Nonzero means args are expressions to be evaluated. --eval. */
113 /* The display on which Emacs should work. --display. */
114 char *display
= NULL
;
116 /* If non-NULL, the name of an editor to fallback to if the server
117 is not running. --alternate-editor. */
118 const char *alternate_editor
= NULL
;
120 /* If non-NULL, the filename of the UNIX socket. */
121 char *socket_name
= NULL
;
123 /* If non-NULL, the filename of the authentication file. */
124 char *server_file
= NULL
;
126 void print_help_and_exit () NO_RETURN
;
128 struct option longopts
[] =
130 { "no-wait", no_argument
, NULL
, 'n' },
131 { "eval", no_argument
, NULL
, 'e' },
132 { "help", no_argument
, NULL
, 'H' },
133 { "version", no_argument
, NULL
, 'V' },
134 { "alternate-editor", required_argument
, NULL
, 'a' },
135 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
136 { "socket-name", required_argument
, NULL
, 's' },
138 { "server-file", required_argument
, NULL
, 'f' },
139 { "display", required_argument
, NULL
, 'd' },
143 /* Decode the options from argv and argc.
144 The global variable `optind' will say how many arguments we used up. */
147 decode_options (argc
, argv
)
151 alternate_editor
= getenv ("ALTERNATE_EDITOR");
155 int opt
= getopt_long (argc
, argv
,
156 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
169 /* If getopt returns 0, then it has already processed a
170 long-named option. We should do nothing. */
174 alternate_editor
= optarg
;
177 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
179 socket_name
= optarg
;
184 server_file
= optarg
;
200 printf ("emacsclient %s\n", VERSION
);
205 print_help_and_exit ();
209 fprintf (stderr
, "Try `%s --help' for more information\n", progname
);
217 print_help_and_exit ()
220 "Usage: %s [OPTIONS] FILE...\n\
221 Tell the Emacs server to visit the specified files.\n\
222 Every FILE can be either just a FILENAME or [+LINE[:COLUMN]] FILENAME.\n\
224 The following OPTIONS are accepted:\n\
225 -V, --version Just print a version info and return\n\
226 -H, --help Print this usage information message\n\
227 -n, --no-wait Don't wait for the server to return\n\
228 -e, --eval Evaluate the FILE arguments as ELisp expressions\n\
229 -d, --display=DISPLAY Visit the file in the given display\n"
230 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
231 "-s, --socket-name=FILENAME\n\
232 Set the filename of the UNIX socket for communication\n"
234 "-f, --server-file=FILENAME\n\
235 Set the filename of the TCP configuration file\n\
236 -a, --alternate-editor=EDITOR\n\
237 Editor to fallback to if the server is not running\n\
239 Report bugs to bug-gnu-emacs@gnu.org.\n", progname
);
245 Try to run a different command, or --if no alternate editor is
246 defined-- exit with an errorcode.
253 if (alternate_editor
)
257 argv
[i
] = (char *)alternate_editor
;
259 execvp (alternate_editor
, argv
+ i
);
260 fprintf (stderr
, "%s: error executing alternate editor \"%s\"\n",
261 progname
, alternate_editor
);
267 #if !defined (HAVE_SOCKETS) || !defined (HAVE_INET_SOCKETS)
274 fprintf (stderr
, "%s: Sorry, the Emacs server is supported only\n",
276 fprintf (stderr
, "on systems with Berkeley sockets.\n");
281 #else /* HAVE_SOCKETS && HAVE_INET_SOCKETS */
284 # include <winsock2.h>
286 # include <sys/types.h>
287 # include <sys/socket.h>
289 # include <sys/stat.h>
293 #define AUTH_KEY_LENGTH 64
294 #define SEND_BUFFER_SIZE 4096
296 extern char *strerror ();
299 /* Buffer to accumulate data to send in TCP connections. */
300 char send_buffer
[SEND_BUFFER_SIZE
+ 1];
301 int sblen
= 0; /* Fill pointer for the send buffer. */
303 /* Let's send the data to Emacs when either
304 - the data ends in "\n", or
305 - the buffer is full (but this shouldn't happen)
306 Otherwise, we just accumulate it. */
308 send_to_emacs (s
, data
)
314 int dlen
= strlen (data
);
315 if (dlen
+ sblen
>= SEND_BUFFER_SIZE
)
317 int part
= SEND_BUFFER_SIZE
- sblen
;
318 strncpy (&send_buffer
[sblen
], data
, part
);
320 sblen
= SEND_BUFFER_SIZE
;
324 strcpy (&send_buffer
[sblen
], data
);
331 if (sblen
== SEND_BUFFER_SIZE
332 || (sblen
> 0 && send_buffer
[sblen
-1] == '\n'))
334 int sent
= send (s
, send_buffer
, sblen
, 0);
336 strcpy (send_buffer
, &send_buffer
[sent
]);
342 /* In NAME, insert a & before each &, each space, each newline, and
343 any initial -. Change spaces to underscores, too, so that the
344 return value never contains a space. */
346 quote_file_name (s
, name
)
350 char *copy
= (char *) malloc (strlen (name
) * 2 + 1);
371 if (*p
== '&' || (*p
== '-' && p
== name
))
384 file_name_absolute_p (filename
)
385 const unsigned char *filename
;
387 /* Sanity check, it shouldn't happen. */
388 if (! filename
) return FALSE
;
390 /* /xxx is always an absolute path. */
391 if (filename
[0] == '/') return TRUE
;
393 /* Empty filenames (which shouldn't happen) are relative. */
394 if (filename
[0] == '\0') return FALSE
;
397 /* X:\xxx is always absolute; X:xxx is an error and will fail. */
398 if (islower (tolower (filename
[0]))
399 && filename
[1] == ':' && filename
[2] == '\\')
402 /* Both \xxx and \\xxx\yyy are absolute. */
403 if (filename
[0] == '\\') return TRUE
;
410 /* Wrapper to make WSACleanup a cdecl, as required by atexit(). */
412 __cdecl
close_winsock ()
417 /* Initialize the WinSock2 library. */
419 initialize_sockets ()
423 if (WSAStartup (MAKEWORD (2, 0), &wsaData
))
425 fprintf (stderr
, "%s: error initializing WinSock2", progname
);
429 atexit (close_winsock
);
431 #endif /* WINDOWSNT */
434 * Read the information needed to set up a TCP comm channel with
435 * the Emacs server: host, port, pid and authentication string.
438 get_server_config (server
, authentication
)
439 struct sockaddr_in
*server
;
440 char *authentication
;
447 if (file_name_absolute_p (server_file
))
448 config
= fopen (server_file
, "rb");
451 char *home
= getenv ("HOME");
455 char *path
= alloca (32 + strlen (home
) + strlen (server_file
));
456 sprintf (path
, "%s/.emacs.d/server/%s", home
, server_file
);
457 config
= fopen (path
, "rb");
460 if (!config
&& (home
= getenv ("APPDATA")))
462 char *path
= alloca (32 + strlen (home
) + strlen (server_file
));
463 sprintf (path
, "%s/.emacs.d/server/%s", home
, server_file
);
464 config
= fopen (path
, "rb");
472 if (fgets (dotted
, sizeof dotted
, config
)
473 && (port
= strchr (dotted
, ':'))
474 && (pid
= strchr (port
, ' ')))
481 fprintf (stderr
, "%s: invalid configuration info", progname
);
485 server
->sin_family
= AF_INET
;
486 server
->sin_addr
.s_addr
= inet_addr (dotted
);
487 server
->sin_port
= htons (atoi (port
));
489 if (! fread (authentication
, AUTH_KEY_LENGTH
, 1, config
))
491 fprintf (stderr
, "%s: cannot read authentication info", progname
);
499 Modern Windows restrict which processes can set the foreground window.
500 So, for emacsclient to be able to force Emacs into the foreground, we
501 have to call AllowSetForegroundWindow(). Unfortunately, older Windows
502 (W95, W98 and NT) don't have this function, so we have to check first.
504 We're doing this here because it has to be done before sending info
505 to Emacs, and otherwise we'll need a global variable just to pass around
506 the pid, which is also inelegant.
511 if (hUser32
= LoadLibrary ("user32.dll"))
514 if (set_fg
= GetProcAddress (hUser32
, "AllowSetForegroundWindow"))
516 FreeLibrary (hUser32
);
528 struct sockaddr_in server
;
529 struct linger l_arg
= {1, 1};
530 char auth_string
[AUTH_KEY_LENGTH
+ 1];
532 if (! get_server_config (&server
, auth_string
))
533 return INVALID_SOCKET
;
535 if (server
.sin_addr
.s_addr
!= inet_addr ("127.0.0.1"))
536 fprintf (stderr
, "%s: connected to remote socket at %s\n",
537 progname
, inet_ntoa (server
.sin_addr
));
540 * Open up an AF_INET socket
542 if ((s
= socket (AF_INET
, SOCK_STREAM
, IPPROTO_TCP
)) < 0)
544 fprintf (stderr
, "%s: ", progname
);
546 return INVALID_SOCKET
;
552 if (connect (s
, (struct sockaddr
*) &server
, sizeof server
) < 0)
554 fprintf (stderr
, "%s: ", progname
);
556 return INVALID_SOCKET
;
559 setsockopt (s
, SOL_SOCKET
, SO_LINGER
, (char *) &l_arg
, sizeof l_arg
);
562 * Send the authentication
564 auth_string
[AUTH_KEY_LENGTH
] = '\0';
566 SEND_STRING ("-auth ");
567 SEND_STRING (auth_string
);
573 #if !defined (NO_SOCKETS_IN_FILE_SYSTEM)
575 /* Three possibilities:
576 2 - can't be `stat'ed (sets errno)
577 1 - isn't owned by us
578 0 - success: none of the above */
581 socket_status (socket_name
)
586 if (stat (socket_name
, &statbfr
) == -1)
589 if (statbfr
.st_uid
!= geteuid ())
599 struct sockaddr_un server
;
602 * Open up an AF_UNIX socket in this person's home directory
605 if ((s
= socket (AF_UNIX
, SOCK_STREAM
, 0)) < 0)
607 fprintf (stderr
, "%s: ", progname
);
609 return INVALID_SOCKET
;
612 server
.sun_family
= AF_UNIX
;
616 int default_sock
= !socket_name
;
618 char *server_name
= "server";
620 if (socket_name
&& !index (socket_name
, '/') && !index (socket_name
, '\\'))
621 { /* socket_name is a file name component. */
622 server_name
= socket_name
;
624 default_sock
= 1; /* Try both UIDs. */
629 socket_name
= alloca (100 + strlen (server_name
));
630 sprintf (socket_name
, "/tmp/emacs%d/%s",
631 (int) geteuid (), server_name
);
634 if (strlen (socket_name
) < sizeof (server
.sun_path
))
635 strcpy (server
.sun_path
, socket_name
);
638 fprintf (stderr
, "%s: socket-name %s too long",
639 progname
, socket_name
);
643 /* See if the socket exists, and if it's owned by us. */
644 sock_status
= socket_status (server
.sun_path
);
646 if (sock_status
&& default_sock
)
648 /* Failing that, see if LOGNAME or USER exist and differ from
649 our euid. If so, look for a socket based on the UID
650 associated with the name. This is reminiscent of the logic
651 that init_editfns uses to set the global Vuser_full_name. */
653 char *user_name
= (char *) getenv ("LOGNAME");
656 user_name
= (char *) getenv ("USER");
660 struct passwd
*pw
= getpwnam (user_name
);
662 if (pw
&& (pw
->pw_uid
!= geteuid ()))
664 /* We're running under su, apparently. */
665 socket_name
= alloca (100 + strlen (server_name
));
666 sprintf (socket_name
, "/tmp/emacs%d/%s",
667 (int) pw
->pw_uid
, server_name
);
669 if (strlen (socket_name
) < sizeof (server
.sun_path
))
670 strcpy (server
.sun_path
, socket_name
);
673 fprintf (stderr
, "%s: socket-name %s too long",
674 progname
, socket_name
);
678 sock_status
= socket_status (server
.sun_path
);
689 /* There's a socket, but it isn't owned by us. This is OK if
693 fprintf (stderr
, "%s: Invalid socket owner\n", progname
);
694 return INVALID_SOCKET
;
700 if (saved_errno
== ENOENT
)
702 "%s: can't find socket; have you started the server?\n\
703 To start the server in Emacs, type \"M-x server-start\".\n",
706 fprintf (stderr
, "%s: can't stat %s: %s\n",
707 progname
, server
.sun_path
, strerror (saved_errno
));
708 return INVALID_SOCKET
;
712 if (connect (s
, (struct sockaddr
*) &server
, strlen (server
.sun_path
) + 2)
715 fprintf (stderr
, "%s: ", progname
);
717 return INVALID_SOCKET
;
722 #endif /* ! NO_SOCKETS_IN_FILE_SYSTEM */
731 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
732 /* Explicit --socket-name argument. */
735 s
= set_local_socket ();
736 if ((s
!= INVALID_SOCKET
) || alternate_editor
)
739 fprintf (stderr
, "%s: error accessing socket \"%s\"",
740 progname
, socket_name
);
745 /* Explicit --server-file arg or EMACS_SERVER_FILE variable. */
747 server_file
= getenv ("EMACS_SERVER_FILE");
751 s
= set_tcp_socket ();
752 if ((s
!= INVALID_SOCKET
) || alternate_editor
)
755 fprintf (stderr
, "%s: error accessing server file \"%s\"",
756 progname
, server_file
);
760 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
761 /* Implicit local socket. */
762 s
= set_local_socket ();
763 if (s
!= INVALID_SOCKET
)
767 /* Implicit server file. */
768 server_file
= "server";
769 s
= set_tcp_socket ();
770 if ((s
!= INVALID_SOCKET
) || alternate_editor
)
773 /* No implicit or explicit socket, and no alternate editor. */
774 fprintf (stderr
, "%s: No socket or alternate editor. Please use:\n\n"
775 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
778 "\t--server-file (or environment variable EMACS_SERVER_FILE)\n\
779 \t--alternate-editor (or environment variable ALTERNATE_EDITOR)\n",
790 int i
, rl
, needlf
= 0;
792 char string
[BUFSIZ
+1];
796 /* Process options. */
797 decode_options (argc
, argv
);
799 if ((argc
- optind
< 1) && !eval
)
801 fprintf (stderr
, "%s: file name or argument required\n", progname
);
802 fprintf (stderr
, "Try `%s --help' for more information\n", progname
);
806 if ((s
= set_socket ()) == INVALID_SOCKET
)
810 cwd
= getcwd (string
, sizeof string
);
812 cwd
= getwd (string
);
816 /* getwd puts message in STRING if it fails. */
818 fprintf (stderr
, "%s: %s (%s)\n", progname
,
819 "Cannot get current working directory", strerror (errno
));
821 fprintf (stderr
, "%s: %s (%s)\n", progname
, string
, strerror (errno
));
827 SEND_STRING ("-nowait ");
830 SEND_STRING ("-eval ");
834 SEND_STRING ("-display ");
835 SEND_QUOTED (display
);
839 if ((argc
- optind
> 0))
841 for (i
= optind
; i
< argc
; i
++)
844 ; /* Don't prepend any cwd or anything like that. */
845 else if (*argv
[i
] == '+')
847 char *p
= argv
[i
] + 1;
848 while (isdigit ((unsigned char) *p
) || *p
== ':') p
++;
855 else if (! file_name_absolute_p (argv
[i
]))
861 SEND_QUOTED (argv
[i
]);
867 while (fgets (string
, BUFSIZ
, stdin
))
869 SEND_QUOTED (string
);
876 /* Maybe wait for an answer. */
881 printf ("Waiting for Emacs...");
886 /* Now, wait for an answer and print any messages. */
887 while ((rl
= recv (s
, string
, BUFSIZ
, 0)) > 0)
892 printf ("%s", string
);
893 needlf
= string
[0] == '\0' ? needlf
: string
[strlen (string
) - 1] != '\n';
905 #endif /* HAVE_SOCKETS && HAVE_INET_SOCKETS */
907 #ifndef HAVE_STRERROR
912 extern char *sys_errlist
[];
915 if (errnum
>= 0 && errnum
< sys_nerr
)
916 return sys_errlist
[errnum
];
917 return (char *) "Unknown error";
920 #endif /* ! HAVE_STRERROR */
922 /* arch-tag: f39bb9c4-73eb-477e-896d-50832e2ca9a7
923 (do not change this comment) */
925 /* emacsclient.c ends here */