]>
code.delx.au - gnu-emacs/blob - lib-src/emacsclient.c
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");
454 home
= getenv ("APPDATA");
458 char *path
= alloca (32 + strlen (home
) + strlen (server_file
));
459 sprintf (path
, "%s/.emacs.d/server/%s", home
, server_file
);
460 config
= fopen (path
, "rb");
467 if (fgets (dotted
, sizeof dotted
, config
)
468 && (port
= strchr (dotted
, ':'))
469 && (pid
= strchr (port
, ' ')))
476 fprintf (stderr
, "%s: invalid configuration info", progname
);
480 server
->sin_family
= AF_INET
;
481 server
->sin_addr
.s_addr
= inet_addr (dotted
);
482 server
->sin_port
= htons (atoi (port
));
484 if (! fread (authentication
, AUTH_KEY_LENGTH
, 1, config
))
486 fprintf (stderr
, "%s: cannot read authentication info", progname
);
494 Modern Windows restrict which processes can set the foreground window.
495 So, for emacsclient to be able to force Emacs into the foreground, we
496 have to call AllowSetForegroundWindow(). Unfortunately, older Windows
497 (W95, W98 and NT) don't have this function, so we have to check first.
499 We're doing this here because it has to be done before sending info
500 to Emacs, and otherwise we'll need a global variable just to pass around
501 the pid, which is also inelegant.
506 if (hUser32
= LoadLibrary ("user32.dll"))
508 void (*set_fg
)(DWORD
);
509 if (set_fg
= GetProcAddress (hUser32
, "AllowSetForegroundWindow"))
511 FreeLibrary (hUser32
);
523 struct sockaddr_in server
;
524 struct linger l_arg
= {1, 1};
525 char auth_string
[AUTH_KEY_LENGTH
+ 1];
527 if (! get_server_config (&server
, auth_string
))
528 return INVALID_SOCKET
;
530 if (server
.sin_addr
.s_addr
!= inet_addr ("127.0.0.1"))
531 fprintf (stderr
, "%s: connected to remote socket at %s\n",
532 progname
, inet_ntoa (server
.sin_addr
));
535 * Open up an AF_INET socket
537 if ((s
= socket (AF_INET
, SOCK_STREAM
, IPPROTO_TCP
)) < 0)
539 fprintf (stderr
, "%s: ", progname
);
541 return INVALID_SOCKET
;
547 if (connect (s
, (struct sockaddr
*) &server
, sizeof server
) < 0)
549 fprintf (stderr
, "%s: ", progname
);
551 return INVALID_SOCKET
;
554 setsockopt (s
, SOL_SOCKET
, SO_LINGER
, (char *) &l_arg
, sizeof l_arg
);
557 * Send the authentication
559 auth_string
[AUTH_KEY_LENGTH
] = '\0';
561 SEND_STRING ("-auth ");
562 SEND_STRING (auth_string
);
568 #if !defined (NO_SOCKETS_IN_FILE_SYSTEM)
570 /* Three possibilities:
571 2 - can't be `stat'ed (sets errno)
572 1 - isn't owned by us
573 0 - success: none of the above */
576 socket_status (socket_name
)
581 if (stat (socket_name
, &statbfr
) == -1)
584 if (statbfr
.st_uid
!= geteuid ())
594 struct sockaddr_un server
;
597 * Open up an AF_UNIX socket in this person's home directory
600 if ((s
= socket (AF_UNIX
, SOCK_STREAM
, 0)) < 0)
602 fprintf (stderr
, "%s: ", progname
);
604 return INVALID_SOCKET
;
607 server
.sun_family
= AF_UNIX
;
611 int default_sock
= !socket_name
;
613 char *server_name
= "server";
615 if (socket_name
&& !index (socket_name
, '/') && !index (socket_name
, '\\'))
616 { /* socket_name is a file name component. */
617 server_name
= socket_name
;
619 default_sock
= 1; /* Try both UIDs. */
624 socket_name
= alloca (100 + strlen (server_name
));
625 sprintf (socket_name
, "/tmp/emacs%d/%s",
626 (int) geteuid (), server_name
);
629 if (strlen (socket_name
) < sizeof (server
.sun_path
))
630 strcpy (server
.sun_path
, socket_name
);
633 fprintf (stderr
, "%s: socket-name %s too long",
634 progname
, socket_name
);
638 /* See if the socket exists, and if it's owned by us. */
639 sock_status
= socket_status (server
.sun_path
);
641 if (sock_status
&& default_sock
)
643 /* Failing that, see if LOGNAME or USER exist and differ from
644 our euid. If so, look for a socket based on the UID
645 associated with the name. This is reminiscent of the logic
646 that init_editfns uses to set the global Vuser_full_name. */
648 char *user_name
= (char *) getenv ("LOGNAME");
651 user_name
= (char *) getenv ("USER");
655 struct passwd
*pw
= getpwnam (user_name
);
657 if (pw
&& (pw
->pw_uid
!= geteuid ()))
659 /* We're running under su, apparently. */
660 socket_name
= alloca (100 + strlen (server_name
));
661 sprintf (socket_name
, "/tmp/emacs%d/%s",
662 (int) pw
->pw_uid
, server_name
);
664 if (strlen (socket_name
) < sizeof (server
.sun_path
))
665 strcpy (server
.sun_path
, socket_name
);
668 fprintf (stderr
, "%s: socket-name %s too long",
669 progname
, socket_name
);
673 sock_status
= socket_status (server
.sun_path
);
684 /* There's a socket, but it isn't owned by us. This is OK if
688 fprintf (stderr
, "%s: Invalid socket owner\n", progname
);
689 return INVALID_SOCKET
;
695 if (saved_errno
== ENOENT
)
697 "%s: can't find socket; have you started the server?\n\
698 To start the server in Emacs, type \"M-x server-start\".\n",
701 fprintf (stderr
, "%s: can't stat %s: %s\n",
702 progname
, server
.sun_path
, strerror (saved_errno
));
703 return INVALID_SOCKET
;
707 if (connect (s
, (struct sockaddr
*) &server
, strlen (server
.sun_path
) + 2)
710 fprintf (stderr
, "%s: ", progname
);
712 return INVALID_SOCKET
;
717 #endif /* ! NO_SOCKETS_IN_FILE_SYSTEM */
726 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
727 /* Explicit --socket-name argument. */
730 s
= set_local_socket ();
731 if ((s
!= INVALID_SOCKET
) || alternate_editor
)
734 fprintf (stderr
, "%s: error accessing socket \"%s\"",
735 progname
, socket_name
);
740 /* Explicit --server-file arg or EMACS_SERVER_FILE variable. */
742 server_file
= getenv ("EMACS_SERVER_FILE");
746 s
= set_tcp_socket ();
747 if ((s
!= INVALID_SOCKET
) || alternate_editor
)
750 fprintf (stderr
, "%s: error accessing server file \"%s\"",
751 progname
, server_file
);
755 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
756 /* Implicit local socket. */
757 s
= set_local_socket ();
758 if (s
!= INVALID_SOCKET
)
762 /* Implicit server file. */
763 server_file
= "server";
764 s
= set_tcp_socket ();
765 if ((s
!= INVALID_SOCKET
) || alternate_editor
)
768 /* No implicit or explicit socket, and no alternate editor. */
769 fprintf (stderr
, "%s: No socket or alternate editor. Please use:\n\n"
770 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
773 "\t--server-file (or environment variable EMACS_SERVER_FILE)\n\
774 \t--alternate-editor (or environment variable ALTERNATE_EDITOR)\n",
785 int i
, rl
, needlf
= 0;
787 char string
[BUFSIZ
+1];
791 /* Process options. */
792 decode_options (argc
, argv
);
794 if ((argc
- optind
< 1) && !eval
)
796 fprintf (stderr
, "%s: file name or argument required\n", progname
);
797 fprintf (stderr
, "Try `%s --help' for more information\n", progname
);
801 if ((s
= set_socket ()) == INVALID_SOCKET
)
805 cwd
= getcwd (string
, sizeof string
);
807 cwd
= getwd (string
);
811 /* getwd puts message in STRING if it fails. */
813 fprintf (stderr
, "%s: %s (%s)\n", progname
,
814 "Cannot get current working directory", strerror (errno
));
816 fprintf (stderr
, "%s: %s (%s)\n", progname
, string
, strerror (errno
));
822 SEND_STRING ("-nowait ");
825 SEND_STRING ("-eval ");
829 SEND_STRING ("-display ");
830 SEND_QUOTED (display
);
834 if ((argc
- optind
> 0))
836 for (i
= optind
; i
< argc
; i
++)
839 ; /* Don't prepend any cwd or anything like that. */
840 else if (*argv
[i
] == '+')
842 char *p
= argv
[i
] + 1;
843 while (isdigit ((unsigned char) *p
) || *p
== ':') p
++;
850 else if (! file_name_absolute_p (argv
[i
]))
856 SEND_QUOTED (argv
[i
]);
862 while (fgets (string
, BUFSIZ
, stdin
))
864 SEND_QUOTED (string
);
871 /* Maybe wait for an answer. */
876 printf ("Waiting for Emacs...");
881 /* Now, wait for an answer and print any messages. */
882 while ((rl
= recv (s
, string
, BUFSIZ
, 0)) > 0)
887 printf ("%s", string
);
888 needlf
= string
[0] == '\0' ? needlf
: string
[strlen (string
) - 1] != '\n';
900 #endif /* HAVE_SOCKETS && HAVE_INET_SOCKETS */
902 #ifndef HAVE_STRERROR
907 extern char *sys_errlist
[];
910 if (errnum
>= 0 && errnum
< sys_nerr
)
911 return sys_errlist
[errnum
];
912 return (char *) "Unknown error";
915 #endif /* ! HAVE_STRERROR */
917 /* arch-tag: f39bb9c4-73eb-477e-896d-50832e2ca9a7
918 (do not change this comment) */
920 /* emacsclient.c ends here */