]>
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 # include <sys/types.h>
46 # ifdef HAVE_INET_SOCKETS
47 # include <netinet/in.h>
50 # define INVALID_SOCKET -1
52 # define CLOSE_SOCKET close
55 #endif /* !WINDOWSNT */
71 #else /* not WINDOWSNT */
73 #endif /* not WINDOWSNT */
76 char *getenv (), *getwd ();
80 #define VERSION "unspecified"
83 #define SEND_STRING(data) (send_to_emacs (s, (data)))
84 #define SEND_QUOTED(data) (quote_file_name (s, (data)))
87 #define EXIT_SUCCESS 0
91 #define EXIT_FAILURE 1
106 /* Name used to invoke this program. */
109 /* Nonzero means don't wait for a response from Emacs. --no-wait. */
112 /* Nonzero means args are expressions to be evaluated. --eval. */
115 /* The display on which Emacs should work. --display. */
116 char *display
= NULL
;
118 /* If non-NULL, the name of an editor to fallback to if the server
119 is not running. --alternate-editor. */
120 const char *alternate_editor
= NULL
;
122 /* If non-NULL, the filename of the UNIX socket. */
123 char *socket_name
= NULL
;
125 /* If non-NULL, the filename of the authentication file. */
126 char *server_file
= NULL
;
128 void print_help_and_exit () NO_RETURN
;
130 struct option longopts
[] =
132 { "no-wait", no_argument
, NULL
, 'n' },
133 { "eval", no_argument
, NULL
, 'e' },
134 { "help", no_argument
, NULL
, 'H' },
135 { "version", no_argument
, NULL
, 'V' },
136 { "alternate-editor", required_argument
, NULL
, 'a' },
137 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
138 { "socket-name", required_argument
, NULL
, 's' },
140 { "server-file", required_argument
, NULL
, 'f' },
141 { "display", required_argument
, NULL
, 'd' },
145 /* Decode the options from argv and argc.
146 The global variable `optind' will say how many arguments we used up. */
149 decode_options (argc
, argv
)
153 alternate_editor
= getenv ("ALTERNATE_EDITOR");
157 int opt
= getopt_long (argc
, argv
,
158 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
171 /* If getopt returns 0, then it has already processed a
172 long-named option. We should do nothing. */
176 alternate_editor
= optarg
;
179 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
181 socket_name
= optarg
;
186 server_file
= optarg
;
202 printf ("emacsclient %s\n", VERSION
);
207 print_help_and_exit ();
211 fprintf (stderr
, "Try `%s --help' for more information\n", progname
);
219 print_help_and_exit ()
222 "Usage: %s [OPTIONS] FILE...\n\
223 Tell the Emacs server to visit the specified files.\n\
224 Every FILE can be either just a FILENAME or [+LINE[:COLUMN]] FILENAME.\n\
226 The following OPTIONS are accepted:\n\
227 -V, --version Just print a version info and return\n\
228 -H, --help Print this usage information message\n\
229 -n, --no-wait Don't wait for the server to return\n\
230 -e, --eval Evaluate the FILE arguments as ELisp expressions\n\
231 -d, --display=DISPLAY Visit the file in the given display\n"
232 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
233 "-s, --socket-name=FILENAME\n\
234 Set the filename of the UNIX socket for communication\n"
236 "-f, --server-file=FILENAME\n\
237 Set the filename of the TCP configuration file\n\
238 -a, --alternate-editor=EDITOR\n\
239 Editor to fallback to if the server is not running\n\
241 Report bugs to bug-gnu-emacs@gnu.org.\n", progname
);
247 Try to run a different command, or --if no alternate editor is
248 defined-- exit with an errorcode.
255 if (alternate_editor
)
259 argv
[i
] = (char *)alternate_editor
;
261 execvp (alternate_editor
, argv
+ i
);
262 fprintf (stderr
, "%s: error executing alternate editor \"%s\"\n",
263 progname
, alternate_editor
);
269 #if !defined (HAVE_SOCKETS) || !defined (HAVE_INET_SOCKETS)
276 fprintf (stderr
, "%s: Sorry, the Emacs server is supported only\n",
278 fprintf (stderr
, "on systems with Berkeley sockets.\n");
283 #else /* HAVE_SOCKETS && HAVE_INET_SOCKETS */
286 # include <winsock2.h>
288 # include <sys/types.h>
289 # include <sys/socket.h>
291 # include <sys/stat.h>
295 #define AUTH_KEY_LENGTH 64
296 #define SEND_BUFFER_SIZE 4096
298 extern char *strerror ();
301 /* Buffer to accumulate data to send in TCP connections. */
302 char send_buffer
[SEND_BUFFER_SIZE
+ 1];
303 int sblen
= 0; /* Fill pointer for the send buffer. */
305 /* Let's send the data to Emacs when either
306 - the data ends in "\n", or
307 - the buffer is full (but this shouldn't happen)
308 Otherwise, we just accumulate it. */
310 send_to_emacs (s
, data
)
316 int dlen
= strlen (data
);
317 if (dlen
+ sblen
>= SEND_BUFFER_SIZE
)
319 int part
= SEND_BUFFER_SIZE
- sblen
;
320 strncpy (&send_buffer
[sblen
], data
, part
);
322 sblen
= SEND_BUFFER_SIZE
;
326 strcpy (&send_buffer
[sblen
], data
);
333 if (sblen
== SEND_BUFFER_SIZE
334 || (sblen
> 0 && send_buffer
[sblen
-1] == '\n'))
336 int sent
= send (s
, send_buffer
, sblen
, 0);
338 strcpy (send_buffer
, &send_buffer
[sent
]);
344 /* In NAME, insert a & before each &, each space, each newline, and
345 any initial -. Change spaces to underscores, too, so that the
346 return value never contains a space. */
348 quote_file_name (s
, name
)
352 char *copy
= (char *) malloc (strlen (name
) * 2 + 1);
373 if (*p
== '&' || (*p
== '-' && p
== name
))
386 file_name_absolute_p (filename
)
387 const unsigned char *filename
;
389 /* Sanity check, it shouldn't happen. */
390 if (! filename
) return FALSE
;
392 /* /xxx is always an absolute path. */
393 if (filename
[0] == '/') return TRUE
;
395 /* Empty filenames (which shouldn't happen) are relative. */
396 if (filename
[0] == '\0') return FALSE
;
399 /* X:\xxx is always absolute; X:xxx is an error and will fail. */
400 if (islower (tolower (filename
[0]))
401 && filename
[1] == ':' && filename
[2] == '\\')
404 /* Both \xxx and \\xxx\yyy are absolute. */
405 if (filename
[0] == '\\') return TRUE
;
412 /* Wrapper to make WSACleanup a cdecl, as required by atexit(). */
414 __cdecl
close_winsock ()
419 /* Initialize the WinSock2 library. */
421 initialize_sockets ()
425 if (WSAStartup (MAKEWORD (2, 0), &wsaData
))
427 fprintf (stderr
, "%s: error initializing WinSock2", progname
);
431 atexit (close_winsock
);
433 #endif /* WINDOWSNT */
436 * Read the information needed to set up a TCP comm channel with
437 * the Emacs server: host, port, pid and authentication string.
440 get_server_config (server
, authentication
)
441 struct sockaddr_in
*server
;
442 char *authentication
;
449 if (file_name_absolute_p (server_file
))
450 config
= fopen (server_file
, "rb");
453 char *home
= getenv ("HOME");
457 char *path
= alloca (32 + strlen (home
) + strlen (server_file
));
458 sprintf (path
, "%s/.emacs.d/server/%s", home
, server_file
);
459 config
= fopen (path
, "rb");
462 if (!config
&& (home
= getenv ("APPDATA")))
464 char *path
= alloca (32 + strlen (home
) + strlen (server_file
));
465 sprintf (path
, "%s/.emacs.d/server/%s", home
, server_file
);
466 config
= fopen (path
, "rb");
474 if (fgets (dotted
, sizeof dotted
, config
)
475 && (port
= strchr (dotted
, ':'))
476 && (pid
= strchr (port
, ' ')))
483 fprintf (stderr
, "%s: invalid configuration info", progname
);
487 server
->sin_family
= AF_INET
;
488 server
->sin_addr
.s_addr
= inet_addr (dotted
);
489 server
->sin_port
= htons (atoi (port
));
491 if (! fread (authentication
, AUTH_KEY_LENGTH
, 1, config
))
493 fprintf (stderr
, "%s: cannot read authentication info", progname
);
501 Modern Windows restrict which processes can set the foreground window.
502 So, for emacsclient to be able to force Emacs into the foreground, we
503 have to call AllowSetForegroundWindow(). Unfortunately, older Windows
504 (W95, W98 and NT) don't have this function, so we have to check first.
506 We're doing this here because it has to be done before sending info
507 to Emacs, and otherwise we'll need a global variable just to pass around
508 the pid, which is also inelegant.
513 if (hUser32
= LoadLibrary ("user32.dll"))
516 if (set_fg
= GetProcAddress (hUser32
, "AllowSetForegroundWindow"))
518 FreeLibrary (hUser32
);
530 struct sockaddr_in server
;
531 struct linger l_arg
= {1, 1};
532 char auth_string
[AUTH_KEY_LENGTH
+ 1];
534 if (! get_server_config (&server
, auth_string
))
535 return INVALID_SOCKET
;
537 if (server
.sin_addr
.s_addr
!= inet_addr ("127.0.0.1"))
538 fprintf (stderr
, "%s: connected to remote socket at %s\n",
539 progname
, inet_ntoa (server
.sin_addr
));
542 * Open up an AF_INET socket
544 if ((s
= socket (AF_INET
, SOCK_STREAM
, IPPROTO_TCP
)) < 0)
546 fprintf (stderr
, "%s: ", progname
);
548 return INVALID_SOCKET
;
554 if (connect (s
, (struct sockaddr
*) &server
, sizeof server
) < 0)
556 fprintf (stderr
, "%s: ", progname
);
558 return INVALID_SOCKET
;
561 setsockopt (s
, SOL_SOCKET
, SO_LINGER
, (char *) &l_arg
, sizeof l_arg
);
564 * Send the authentication
566 auth_string
[AUTH_KEY_LENGTH
] = '\0';
568 SEND_STRING ("-auth ");
569 SEND_STRING (auth_string
);
575 #if !defined (NO_SOCKETS_IN_FILE_SYSTEM)
577 /* Three possibilities:
578 2 - can't be `stat'ed (sets errno)
579 1 - isn't owned by us
580 0 - success: none of the above */
583 socket_status (socket_name
)
588 if (stat (socket_name
, &statbfr
) == -1)
591 if (statbfr
.st_uid
!= geteuid ())
601 struct sockaddr_un server
;
604 * Open up an AF_UNIX socket in this person's home directory
607 if ((s
= socket (AF_UNIX
, SOCK_STREAM
, 0)) < 0)
609 fprintf (stderr
, "%s: ", progname
);
611 return INVALID_SOCKET
;
614 server
.sun_family
= AF_UNIX
;
618 int default_sock
= !socket_name
;
620 char *server_name
= "server";
622 if (socket_name
&& !index (socket_name
, '/') && !index (socket_name
, '\\'))
623 { /* socket_name is a file name component. */
624 server_name
= socket_name
;
626 default_sock
= 1; /* Try both UIDs. */
631 socket_name
= alloca (100 + strlen (server_name
));
632 sprintf (socket_name
, "/tmp/emacs%d/%s",
633 (int) geteuid (), server_name
);
636 if (strlen (socket_name
) < sizeof (server
.sun_path
))
637 strcpy (server
.sun_path
, socket_name
);
640 fprintf (stderr
, "%s: socket-name %s too long",
641 progname
, socket_name
);
645 /* See if the socket exists, and if it's owned by us. */
646 sock_status
= socket_status (server
.sun_path
);
648 if (sock_status
&& default_sock
)
650 /* Failing that, see if LOGNAME or USER exist and differ from
651 our euid. If so, look for a socket based on the UID
652 associated with the name. This is reminiscent of the logic
653 that init_editfns uses to set the global Vuser_full_name. */
655 char *user_name
= (char *) getenv ("LOGNAME");
658 user_name
= (char *) getenv ("USER");
662 struct passwd
*pw
= getpwnam (user_name
);
664 if (pw
&& (pw
->pw_uid
!= geteuid ()))
666 /* We're running under su, apparently. */
667 socket_name
= alloca (100 + strlen (server_name
));
668 sprintf (socket_name
, "/tmp/emacs%d/%s",
669 (int) pw
->pw_uid
, server_name
);
671 if (strlen (socket_name
) < sizeof (server
.sun_path
))
672 strcpy (server
.sun_path
, socket_name
);
675 fprintf (stderr
, "%s: socket-name %s too long",
676 progname
, socket_name
);
680 sock_status
= socket_status (server
.sun_path
);
691 /* There's a socket, but it isn't owned by us. This is OK if
695 fprintf (stderr
, "%s: Invalid socket owner\n", progname
);
696 return INVALID_SOCKET
;
702 if (saved_errno
== ENOENT
)
704 "%s: can't find socket; have you started the server?\n\
705 To start the server in Emacs, type \"M-x server-start\".\n",
708 fprintf (stderr
, "%s: can't stat %s: %s\n",
709 progname
, server
.sun_path
, strerror (saved_errno
));
710 return INVALID_SOCKET
;
714 if (connect (s
, (struct sockaddr
*) &server
, strlen (server
.sun_path
) + 2)
717 fprintf (stderr
, "%s: ", progname
);
719 return INVALID_SOCKET
;
724 #endif /* ! NO_SOCKETS_IN_FILE_SYSTEM */
733 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
734 /* Explicit --socket-name argument. */
737 s
= set_local_socket ();
738 if ((s
!= INVALID_SOCKET
) || alternate_editor
)
741 fprintf (stderr
, "%s: error accessing socket \"%s\"",
742 progname
, socket_name
);
747 /* Explicit --server-file arg or EMACS_SERVER_FILE variable. */
749 server_file
= getenv ("EMACS_SERVER_FILE");
753 s
= set_tcp_socket ();
754 if ((s
!= INVALID_SOCKET
) || alternate_editor
)
757 fprintf (stderr
, "%s: error accessing server file \"%s\"",
758 progname
, server_file
);
762 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
763 /* Implicit local socket. */
764 s
= set_local_socket ();
765 if (s
!= INVALID_SOCKET
)
769 /* Implicit server file. */
770 server_file
= "server";
771 s
= set_tcp_socket ();
772 if ((s
!= INVALID_SOCKET
) || alternate_editor
)
775 /* No implicit or explicit socket, and no alternate editor. */
776 fprintf (stderr
, "%s: No socket or alternate editor. Please use:\n\n"
777 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
780 "\t--server-file (or environment variable EMACS_SERVER_FILE)\n\
781 \t--alternate-editor (or environment variable ALTERNATE_EDITOR)\n",
792 int i
, rl
, needlf
= 0;
794 char string
[BUFSIZ
+1];
798 /* Process options. */
799 decode_options (argc
, argv
);
801 if ((argc
- optind
< 1) && !eval
)
803 fprintf (stderr
, "%s: file name or argument required\n", progname
);
804 fprintf (stderr
, "Try `%s --help' for more information\n", progname
);
808 if ((s
= set_socket ()) == INVALID_SOCKET
)
812 cwd
= getcwd (string
, sizeof string
);
814 cwd
= getwd (string
);
818 /* getwd puts message in STRING if it fails. */
820 fprintf (stderr
, "%s: %s (%s)\n", progname
,
821 "Cannot get current working directory", strerror (errno
));
823 fprintf (stderr
, "%s: %s (%s)\n", progname
, string
, strerror (errno
));
829 SEND_STRING ("-nowait ");
832 SEND_STRING ("-eval ");
836 SEND_STRING ("-display ");
837 SEND_QUOTED (display
);
841 if ((argc
- optind
> 0))
843 for (i
= optind
; i
< argc
; i
++)
846 ; /* Don't prepend any cwd or anything like that. */
847 else if (*argv
[i
] == '+')
849 char *p
= argv
[i
] + 1;
850 while (isdigit ((unsigned char) *p
) || *p
== ':') p
++;
857 else if (! file_name_absolute_p (argv
[i
]))
863 SEND_QUOTED (argv
[i
]);
869 while (fgets (string
, BUFSIZ
, stdin
))
871 SEND_QUOTED (string
);
878 /* Maybe wait for an answer. */
883 printf ("Waiting for Emacs...");
888 /* Now, wait for an answer and print any messages. */
889 while ((rl
= recv (s
, string
, BUFSIZ
, 0)) > 0)
894 printf ("%s", string
);
895 needlf
= string
[0] == '\0' ? needlf
: string
[strlen (string
) - 1] != '\n';
907 #endif /* HAVE_SOCKETS && HAVE_INET_SOCKETS */
909 #ifndef HAVE_STRERROR
914 extern char *sys_errlist
[];
917 if (errnum
>= 0 && errnum
< sys_nerr
)
918 return sys_errlist
[errnum
];
919 return (char *) "Unknown error";
922 #endif /* ! HAVE_STRERROR */
924 /* arch-tag: f39bb9c4-73eb-477e-896d-50832e2ca9a7
925 (do not change this comment) */
927 /* emacsclient.c ends here */