]>
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, 2007 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 3, 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. */
31 /* config.h defines these, which disables sockets altogether! */
39 # define NO_SOCKETS_IN_FILE_SYSTEM
41 # define HSOCKET SOCKET
42 # define CLOSE_SOCKET closesocket
43 # define INITIALIZE() (initialize_sockets ())
45 #else /* !WINDOWSNT */
47 # include <sys/types.h>
49 # ifdef HAVE_INET_SOCKETS
50 # include <netinet/in.h>
53 # define INVALID_SOCKET -1
55 # define CLOSE_SOCKET close
58 #endif /* !WINDOWSNT */
75 #else /* not WINDOWSNT */
77 #endif /* not WINDOWSNT */
86 #define DIRECTORY_SEP '/'
88 #ifndef IS_DIRECTORY_SEP
89 #define IS_DIRECTORY_SEP(_c_) ((_c_) == DIRECTORY_SEP)
93 #define IS_DEVICE_SEP(_c_) 0
95 #define IS_DEVICE_SEP(_c_) ((_c_) == DEVICE_SEP)
99 #define IS_ANY_SEP(_c_) (IS_DIRECTORY_SEP (_c_))
104 char *getenv (), *getwd ();
108 #define VERSION "unspecified"
113 #define EXIT_SUCCESS 0
117 #define EXIT_FAILURE 1
132 /* Name used to invoke this program. */
135 /* The first argument to main. */
138 /* The second argument to main. */
141 /* Nonzero means don't wait for a response from Emacs. --no-wait. */
144 /* Nonzero means args are expressions to be evaluated. --eval. */
147 /* Nonzero means don't open a new frame. --current-frame. */
148 int current_frame
= 0;
150 /* Nonzero means open a new graphical frame. */
151 int window_system
= 0;
153 /* The display on which Emacs should work. --display. */
154 char *display
= NULL
;
156 /* Nonzero means open a new Emacs frame on the current terminal. */
159 /* If non-NULL, the name of an editor to fallback to if the server
160 is not running. --alternate-editor. */
161 const char *alternate_editor
= NULL
;
163 /* If non-NULL, the filename of the UNIX socket. */
164 char *socket_name
= NULL
;
166 /* If non-NULL, the filename of the authentication file. */
167 char *server_file
= NULL
;
169 /* PID of the Emacs server process. */
172 void print_help_and_exit () NO_RETURN
;
174 struct option longopts
[] =
176 { "no-wait", no_argument
, NULL
, 'n' },
177 { "eval", no_argument
, NULL
, 'e' },
178 { "help", no_argument
, NULL
, 'H' },
179 { "version", no_argument
, NULL
, 'V' },
180 { "tty", no_argument
, NULL
, 't' },
181 { "current-frame", no_argument
, NULL
, 'c' },
182 { "alternate-editor", required_argument
, NULL
, 'a' },
183 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
184 { "socket-name", required_argument
, NULL
, 's' },
186 { "server-file", required_argument
, NULL
, 'f' },
187 { "display", required_argument
, NULL
, 'd' },
192 /* Like malloc but get fatal error if memory is exhausted. */
198 long *result
= (long *) malloc (size
);
207 /* Like strdup but get a fatal error if memory is exhausted. */
210 xstrdup (const char *s
)
212 char *result
= strdup (s
);
222 #if !defined (HAVE_GET_CURRENT_DIR_NAME) || defined (BROKEN_GET_CURRENT_DIR_NAME)
224 /* Return the current working directory. Returns NULL on errors.
225 Any other returned value must be freed with free. This is used
226 only when get_current_dir_name is not defined on the system. */
228 get_current_dir_name ()
232 struct stat dotstat
, pwdstat
;
233 /* If PWD is accurate, use it instead of calling getwd. PWD is
234 sometimes a nicer name, and using it may avoid a fatal error if a
235 parent directory is searchable but not readable. */
236 if ((pwd
= getenv ("PWD")) != 0
237 && (IS_DIRECTORY_SEP (*pwd
) || (*pwd
&& IS_DEVICE_SEP (pwd
[1])))
238 && stat (pwd
, &pwdstat
) == 0
239 && stat (".", &dotstat
) == 0
240 && dotstat
.st_ino
== pwdstat
.st_ino
241 && dotstat
.st_dev
== pwdstat
.st_dev
243 && strlen (pwd
) < MAXPATHLEN
247 buf
= (char *) xmalloc (strlen (pwd
) + 1);
255 size_t buf_size
= 1024;
256 buf
= (char *) xmalloc (buf_size
);
261 if (getcwd (buf
, buf_size
) == buf
)
265 int tmp_errno
= errno
;
271 buf
= (char *) realloc (buf
, buf_size
);
279 /* We need MAXPATHLEN here. */
280 buf
= (char *) xmalloc (MAXPATHLEN
+ 1);
283 if (getwd (buf
) == NULL
)
285 int tmp_errno
= errno
;
296 /* Message functions. */
302 static int window_app
= -1;
303 char szTitle
[MAX_PATH
];
306 /* Checking for STDOUT does not work; it's a valid handle also in
307 nonconsole apps. Testing for the console title seems to work. */
308 window_app
= (GetConsoleTitleA (szTitle
, MAX_PATH
) == 0);
314 execvp wrapper for Windows. Quotes arguments with embedded spaces.
316 This is necessary due to the broken implementation of exec* routines in
317 the Microsoft libraries: they concatenate the arguments together without
318 quoting special characters, and pass the result to CreateProcess, with
319 predictably bad results. By contrast, Posix execvp passes the arguments
320 directly into the argv array of the child process.
323 w32_execvp (path
, argv
)
329 /* Required to allow a .BAT script as alternate editor. */
330 argv
[0] = (char *) alternate_editor
;
332 for (i
= 0; argv
[i
]; i
++)
333 if (strchr (argv
[i
], ' '))
335 char *quoted
= alloca (strlen (argv
[i
]) + 3);
336 sprintf (quoted
, "\"%s\"", argv
[i
]);
340 return execvp (path
, argv
);
344 #define execvp w32_execvp
346 #endif /* WINDOWSNT */
349 message (int is_error
, char *message
, ...)
354 va_start (args
, message
);
355 vsprintf (msg
, message
, args
);
359 if (w32_window_app ())
362 MessageBox (NULL
, msg
, "Emacsclient ERROR", MB_ICONERROR
);
364 MessageBox (NULL
, msg
, "Emacsclient", MB_ICONINFORMATION
);
369 FILE *f
= is_error
? stderr
: stdout
;
376 /* Decode the options from argv and argc.
377 The global variable `optind' will say how many arguments we used up. */
380 decode_options (argc
, argv
)
384 alternate_editor
= getenv ("ALTERNATE_EDITOR");
385 display
= getenv ("DISPLAY");
386 if (display
&& strlen (display
) == 0)
391 int opt
= getopt_long (argc
, argv
,
392 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
405 /* If getopt returns 0, then it has already processed a
406 long-named option. We should do nothing. */
410 alternate_editor
= optarg
;
413 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
415 socket_name
= optarg
;
420 server_file
= optarg
;
436 message (FALSE
, "emacsclient %s\n", VERSION
);
449 print_help_and_exit ();
453 message (TRUE
, "Try `%s --help' for more information\n", progname
);
461 #if !defined (WINDOWSNT) && !defined (HAVE_CARBON)
466 /* --no-wait implies --current-frame on ttys when there are file
467 arguments or expressions given. */
468 if (nowait
&& tty
&& argc
- optind
> 0)
483 print_help_and_exit ()
485 /* Spaces and tabs are significant in this message; they're chosen so the
486 message aligns properly both in a tty and in a Windows message box.
487 Please try to preserve them; otherwise the output is very hard to read
488 when using emacsclientw. */
490 "Usage: %s [OPTIONS] FILE...\n\
491 Tell the Emacs server to visit the specified files.\n\
492 Every FILE can be either just a FILENAME or [+LINE[:COLUMN]] FILENAME.\n\
494 The following OPTIONS are accepted:\n\
495 -V, --version Just print version info and return\n\
496 -H, --help Print this usage information message\n\
497 -t, --tty Open a new Emacs frame on the current terminal\n\
498 -c, --current-frame Do not create a new frame;\n\
499 use the current Emacs frame\n\
500 -e, --eval Evaluate the FILE arguments as ELisp expressions\n\
501 -n, --no-wait Don't wait for the server to return\n\
502 -d, --display=DISPLAY Visit the file in the given display\n"
503 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
504 "-s, --socket-name=FILENAME\n\
505 Set filename of the UNIX socket for communication\n"
507 "-f, --server-file=FILENAME\n\
508 Set filename of the TCP authentication file\n\
509 -a, --alternate-editor=EDITOR\n\
510 Editor to fallback to if the server is not running\n\
512 Report bugs to bug-gnu-emacs@gnu.org.\n", progname
);
517 Try to run a different command, or --if no alternate editor is
518 defined-- exit with an errorcode.
523 if (alternate_editor
)
527 execvp (alternate_editor
, main_argv
+ i
);
528 message (TRUE
, "%s: error executing alternate editor \"%s\"\n",
529 progname
, alternate_editor
);
535 #if !defined (HAVE_SOCKETS) || !defined (HAVE_INET_SOCKETS)
545 message (TRUE
, "%s: Sorry, the Emacs server is supported only\n"
546 "on systems with Berkeley sockets.\n",
551 #else /* HAVE_SOCKETS && HAVE_INET_SOCKETS */
554 # include <winsock2.h>
556 # include <sys/types.h>
557 # include <sys/socket.h>
559 # include <sys/stat.h>
563 #define AUTH_KEY_LENGTH 64
564 #define SEND_BUFFER_SIZE 4096
566 extern char *strerror ();
569 /* Buffer to accumulate data to send in TCP connections. */
570 char send_buffer
[SEND_BUFFER_SIZE
+ 1];
571 int sblen
= 0; /* Fill pointer for the send buffer. */
572 /* Socket used to communicate with the Emacs server process. */
573 HSOCKET emacs_socket
= 0;
575 /* Let's send the data to Emacs when either
576 - the data ends in "\n", or
577 - the buffer is full (but this shouldn't happen)
578 Otherwise, we just accumulate it. */
580 send_to_emacs (s
, data
)
586 int dlen
= strlen (data
);
587 if (dlen
+ sblen
>= SEND_BUFFER_SIZE
)
589 int part
= SEND_BUFFER_SIZE
- sblen
;
590 strncpy (&send_buffer
[sblen
], data
, part
);
592 sblen
= SEND_BUFFER_SIZE
;
596 strcpy (&send_buffer
[sblen
], data
);
603 if (sblen
== SEND_BUFFER_SIZE
604 || (sblen
> 0 && send_buffer
[sblen
-1] == '\n'))
606 int sent
= send (s
, send_buffer
, sblen
, 0);
608 strcpy (send_buffer
, &send_buffer
[sent
]);
615 /* In STR, insert a & before each &, each space, each newline, and
616 any initial -. Change spaces to underscores, too, so that the
617 return value never contains a space.
619 Does not change the string. Outputs the result to STREAM. */
621 quote_argument (s
, str
)
625 char *copy
= (char *) xmalloc (strlen (str
) * 2 + 1);
646 if (*p
== '&' || (*p
== '-' && p
== str
))
653 send_to_emacs (s
, copy
);
659 /* The inverse of quote_argument. Removes quoting in string STR by
660 modifying the string in place. Returns STR. */
663 unquote_argument (str
)
695 file_name_absolute_p (filename
)
696 const unsigned char *filename
;
698 /* Sanity check, it shouldn't happen. */
699 if (! filename
) return FALSE
;
701 /* /xxx is always an absolute path. */
702 if (filename
[0] == '/') return TRUE
;
704 /* Empty filenames (which shouldn't happen) are relative. */
705 if (filename
[0] == '\0') return FALSE
;
708 /* X:\xxx is always absolute. */
709 if (isalpha (filename
[0])
710 && filename
[1] == ':' && (filename
[2] == '\\' || filename
[2] == '/'))
713 /* Both \xxx and \\xxx\yyy are absolute. */
714 if (filename
[0] == '\\') return TRUE
;
717 FIXME: There's a corner case not dealt with, "x:y", where:
719 1) x is a valid drive designation (usually a letter in the A-Z range)
720 and y is a path, relative to the current directory on drive x. This
721 is absolute, *after* fixing the y part to include the current
724 2) x is a relative file name, and y is an NTFS stream name. This is a
725 correct relative path, but it is very unusual.
727 The trouble is that first case items are also valid examples of the
728 second case, i.e., "c:test" can be understood as drive:path or as
731 The "right" fix would involve checking whether
732 - the current drive/partition is NTFS,
733 - x is a valid (and accesible) drive designator,
734 - x:y already exists as a file:stream in the current directory,
735 - y already exists on the current directory of drive x,
736 - the auspices are favorable,
737 and then taking an "informed decision" based on the above.
739 Whatever the result, Emacs currently does a very bad job of dealing
740 with NTFS file:streams: it cannot visit them, and the only way to
741 create one is by setting `buffer-file-name' to point to it (either
742 manually or with emacsclient). So perhaps resorting to 1) and ignoring
743 2) for now is the right thing to do.
745 Anyway, something to decide After the Release.
753 /* Wrapper to make WSACleanup a cdecl, as required by atexit. */
755 __cdecl
close_winsock ()
760 /* Initialize the WinSock2 library. */
762 initialize_sockets ()
766 if (WSAStartup (MAKEWORD (2, 0), &wsaData
))
768 message (TRUE
, "%s: error initializing WinSock2", progname
);
772 atexit (close_winsock
);
774 #endif /* WINDOWSNT */
778 * Read the information needed to set up a TCP comm channel with
779 * the Emacs server: host, port, pid and authentication string.
782 get_server_config (server
, authentication
)
783 struct sockaddr_in
*server
;
784 char *authentication
;
791 if (file_name_absolute_p (server_file
))
792 config
= fopen (server_file
, "rb");
795 char *home
= getenv ("HOME");
799 char *path
= alloca (32 + strlen (home
) + strlen (server_file
));
800 sprintf (path
, "%s/.emacs.d/server/%s", home
, server_file
);
801 config
= fopen (path
, "rb");
804 if (!config
&& (home
= getenv ("APPDATA")))
806 char *path
= alloca (32 + strlen (home
) + strlen (server_file
));
807 sprintf (path
, "%s/.emacs.d/server/%s", home
, server_file
);
808 config
= fopen (path
, "rb");
816 if (fgets (dotted
, sizeof dotted
, config
)
817 && (port
= strchr (dotted
, ':'))
818 && (pid
= strchr (port
, ' ')))
825 message (TRUE
, "%s: invalid configuration info", progname
);
829 server
->sin_family
= AF_INET
;
830 server
->sin_addr
.s_addr
= inet_addr (dotted
);
831 server
->sin_port
= htons (atoi (port
));
833 if (! fread (authentication
, AUTH_KEY_LENGTH
, 1, config
))
835 message (TRUE
, "%s: cannot read authentication info", progname
);
841 emacs_pid
= atoi (pid
);
850 struct sockaddr_in server
;
851 struct linger l_arg
= {1, 1};
852 char auth_string
[AUTH_KEY_LENGTH
+ 1];
854 if (! get_server_config (&server
, auth_string
))
855 return INVALID_SOCKET
;
857 if (server
.sin_addr
.s_addr
!= inet_addr ("127.0.0.1"))
858 message (FALSE
, "%s: connected to remote socket at %s\n",
859 progname
, inet_ntoa (server
.sin_addr
));
862 * Open up an AF_INET socket
864 if ((s
= socket (AF_INET
, SOCK_STREAM
, IPPROTO_TCP
)) < 0)
866 message (TRUE
, "%s: socket: %s\n", progname
, strerror (errno
));
867 return INVALID_SOCKET
;
873 if (connect (s
, (struct sockaddr
*) &server
, sizeof server
) < 0)
875 message (TRUE
, "%s: connect: %s\n", progname
, strerror (errno
));
876 return INVALID_SOCKET
;
879 setsockopt (s
, SOL_SOCKET
, SO_LINGER
, (char *) &l_arg
, sizeof l_arg
);
882 * Send the authentication
884 auth_string
[AUTH_KEY_LENGTH
] = '\0';
886 send_to_emacs (s
, "-auth ");
887 send_to_emacs (s
, auth_string
);
888 send_to_emacs (s
, "\n");
894 /* Returns 1 if PREFIX is a prefix of STRING. */
896 strprefix (char *prefix
, char *string
)
905 for (i
= 0; prefix
[i
]; i
++)
906 if (!string
[i
] || string
[i
] != prefix
[i
])
912 #if !defined (NO_SOCKETS_IN_FILE_SYSTEM)
914 /* Three possibilities:
915 2 - can't be `stat'ed (sets errno)
916 1 - isn't owned by us
917 0 - success: none of the above */
920 socket_status (socket_name
)
925 if (stat (socket_name
, &statbfr
) == -1)
928 if (statbfr
.st_uid
!= geteuid ())
935 /* A signal handler that passes the signal to the Emacs process.
936 Useful for SIGWINCH. */
939 pass_signal_to_emacs (int signalnum
)
941 int old_errno
= errno
;
944 kill (emacs_pid
, signalnum
);
946 signal (signalnum
, pass_signal_to_emacs
);
950 /* Signal handler for SIGCONT; notify the Emacs process that it can
951 now resume our tty frame. */
954 handle_sigcont (int signalnum
)
956 int old_errno
= errno
;
958 if (tcgetpgrp (1) == getpgrp ())
960 /* We are in the foreground. */
961 send_to_emacs (emacs_socket
, "-resume \n");
965 /* We are in the background; cancel the continue. */
966 kill (getpid (), SIGSTOP
);
969 signal (signalnum
, handle_sigcont
);
973 /* Signal handler for SIGTSTP; notify the Emacs process that we are
974 going to sleep. Normally the suspend is initiated by Emacs via
975 server-handle-suspend-tty, but if the server gets out of sync with
976 reality, we may get a SIGTSTP on C-z. Handling this signal and
977 notifying Emacs about it should get things under control again. */
980 handle_sigtstp (int signalnum
)
982 int old_errno
= errno
;
986 send_to_emacs (emacs_socket
, "-suspend \n");
988 /* Unblock this signal and call the default handler by temprarily
989 changing the handler and resignalling. */
990 sigprocmask (SIG_BLOCK
, NULL
, &set
);
991 sigdelset (&set
, signalnum
);
992 signal (signalnum
, SIG_DFL
);
993 kill (getpid (), signalnum
);
994 sigprocmask (SIG_SETMASK
, &set
, NULL
); /* Let's the above signal through. */
995 signal (signalnum
, handle_sigtstp
);
999 /* Set up signal handlers before opening a frame on the current tty. */
1004 /* Set up signal handlers. */
1005 signal (SIGWINCH
, pass_signal_to_emacs
);
1007 /* Don't pass SIGINT and SIGQUIT to Emacs, because it has no way of
1008 deciding which terminal the signal came from. C-g is now a
1009 normal input event on secondary terminals. */
1011 signal (SIGINT
, pass_signal_to_emacs
);
1012 signal (SIGQUIT
, pass_signal_to_emacs
);
1015 signal (SIGCONT
, handle_sigcont
);
1016 signal (SIGTSTP
, handle_sigtstp
);
1017 signal (SIGTTOU
, handle_sigtstp
);
1025 struct sockaddr_un server
;
1028 * Open up an AF_UNIX socket in this person's home directory
1031 if ((s
= socket (AF_UNIX
, SOCK_STREAM
, 0)) < 0)
1033 message (TRUE
, "%s: socket: %s\n", progname
, strerror (errno
));
1034 return INVALID_SOCKET
;
1037 server
.sun_family
= AF_UNIX
;
1040 int sock_status
= 0;
1041 int default_sock
= !socket_name
;
1042 int saved_errno
= 0;
1044 char *server_name
= "server";
1046 if (socket_name
&& !index (socket_name
, '/') && !index (socket_name
, '\\'))
1047 { /* socket_name is a file name component. */
1048 server_name
= socket_name
;
1050 default_sock
= 1; /* Try both UIDs. */
1055 socket_name
= alloca (100 + strlen (server_name
));
1056 sprintf (socket_name
, "/tmp/emacs%d/%s",
1057 (int) geteuid (), server_name
);
1060 if (strlen (socket_name
) < sizeof (server
.sun_path
))
1061 strcpy (server
.sun_path
, socket_name
);
1064 message (TRUE
, "%s: socket-name %s too long",
1065 progname
, socket_name
);
1069 /* See if the socket exists, and if it's owned by us. */
1070 sock_status
= socket_status (server
.sun_path
);
1071 saved_errno
= errno
;
1072 if (sock_status
&& default_sock
)
1074 /* Failing that, see if LOGNAME or USER exist and differ from
1075 our euid. If so, look for a socket based on the UID
1076 associated with the name. This is reminiscent of the logic
1077 that init_editfns uses to set the global Vuser_full_name. */
1079 char *user_name
= (char *) getenv ("LOGNAME");
1082 user_name
= (char *) getenv ("USER");
1086 struct passwd
*pw
= getpwnam (user_name
);
1088 if (pw
&& (pw
->pw_uid
!= geteuid ()))
1090 /* We're running under su, apparently. */
1091 socket_name
= alloca (100 + strlen (server_name
));
1092 sprintf (socket_name
, "/tmp/emacs%d/%s",
1093 (int) pw
->pw_uid
, server_name
);
1095 if (strlen (socket_name
) < sizeof (server
.sun_path
))
1096 strcpy (server
.sun_path
, socket_name
);
1099 message (TRUE
, "%s: socket-name %s too long",
1100 progname
, socket_name
);
1101 exit (EXIT_FAILURE
);
1104 sock_status
= socket_status (server
.sun_path
);
1105 saved_errno
= errno
;
1108 errno
= saved_errno
;
1112 switch (sock_status
)
1115 /* There's a socket, but it isn't owned by us. This is OK if
1117 if (0 != geteuid ())
1119 message (TRUE
, "%s: Invalid socket owner\n", progname
);
1120 return INVALID_SOCKET
;
1126 if (saved_errno
== ENOENT
)
1128 "%s: can't find socket; have you started the server?\n\
1129 To start the server in Emacs, type \"M-x server-start\".\n",
1132 message (TRUE
, "%s: can't stat %s: %s\n",
1133 progname
, server
.sun_path
, strerror (saved_errno
));
1134 return INVALID_SOCKET
;
1138 if (connect (s
, (struct sockaddr
*) &server
, strlen (server
.sun_path
) + 2)
1141 message (TRUE
, "%s: connect: %s\n", progname
, strerror (errno
));
1142 return INVALID_SOCKET
;
1147 #endif /* ! NO_SOCKETS_IN_FILE_SYSTEM */
1156 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
1157 /* Explicit --socket-name argument. */
1160 s
= set_local_socket ();
1161 if ((s
!= INVALID_SOCKET
) || alternate_editor
)
1163 message (TRUE
, "%s: error accessing socket \"%s\"",
1164 progname
, socket_name
);
1165 exit (EXIT_FAILURE
);
1169 /* Explicit --server-file arg or EMACS_SERVER_FILE variable. */
1171 server_file
= getenv ("EMACS_SERVER_FILE");
1175 s
= set_tcp_socket ();
1176 if ((s
!= INVALID_SOCKET
) || alternate_editor
)
1179 message (TRUE
, "%s: error accessing server file \"%s\"",
1180 progname
, server_file
);
1181 exit (EXIT_FAILURE
);
1184 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
1185 /* Implicit local socket. */
1186 s
= set_local_socket ();
1187 if (s
!= INVALID_SOCKET
)
1191 /* Implicit server file. */
1192 server_file
= "server";
1193 s
= set_tcp_socket ();
1194 if ((s
!= INVALID_SOCKET
) || alternate_editor
)
1197 /* No implicit or explicit socket, and no alternate editor. */
1198 message (TRUE
, "%s: No socket or alternate editor. Please use:\n\n"
1199 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
1202 "\t--server-file (or environment variable EMACS_SERVER_FILE)\n\
1203 \t--alternate-editor (or environment variable ALTERNATE_EDITOR)\n",
1205 exit (EXIT_FAILURE
);
1209 FARPROC set_fg
; /* Pointer to AllowSetForegroundWindow. */
1210 FARPROC get_wc
; /* Pointer to RealGetWindowClassA. */
1213 w32_find_emacs_process (hWnd
, lParam
)
1220 /* Reject any window not of class "Emacs". */
1221 if (! get_wc (hWnd
, class, sizeof (class))
1222 || strcmp (class, "Emacs"))
1225 /* We only need the process id, not the thread id. */
1226 (void) GetWindowThreadProcessId (hWnd
, &pid
);
1228 /* Not the one we're looking for. */
1229 if (pid
!= (DWORD
) emacs_pid
) return TRUE
;
1231 /* OK, let's raise it. */
1234 /* Stop enumeration. */
1239 * Search for a window of class "Emacs" and owned by a process with
1240 * process id = emacs_pid. If found, allow it to grab the focus.
1247 /* It shouldn't happen when dealing with TCP sockets. */
1248 if (!emacs_pid
) return;
1250 if (!(hUser32
= LoadLibrary ("user32.dll"))) return;
1252 /* Modern Windows restrict which processes can set the foreground window.
1253 emacsclient can allow Emacs to grab the focus by calling the function
1254 AllowSetForegroundWindow. Unfortunately, older Windows (W95, W98 and
1255 NT) lack this function, so we have to check its availability. */
1256 if ((set_fg
= GetProcAddress (hUser32
, "AllowSetForegroundWindow"))
1257 && (get_wc
= GetProcAddress (hUser32
, "RealGetWindowClassA")))
1258 EnumWindows (w32_find_emacs_process
, (LPARAM
) 0);
1260 FreeLibrary (hUser32
);
1269 int i
, rl
, needlf
= 0;
1271 char string
[BUFSIZ
+1];
1277 /* Process options. */
1278 decode_options (argc
, argv
);
1280 if ((argc
- optind
< 1) && !eval
&& !tty
&& !window_system
)
1282 message (TRUE
, "%s: file name or argument required\n"
1283 "Try `%s --help' for more information\n",
1284 progname
, progname
);
1285 exit (EXIT_FAILURE
);
1288 if ((emacs_socket
= set_socket ()) == INVALID_SOCKET
)
1292 cwd
= get_current_dir_name ();
1295 /* getwd puts message in STRING if it fails. */
1296 message (TRUE
, "%s: %s\n", progname
,
1297 "Cannot get current working directory");
1305 /* First of all, send our version number for verification. */
1306 send_to_emacs (emacs_socket
, "-version ");
1307 send_to_emacs (emacs_socket
, VERSION
);
1308 send_to_emacs (emacs_socket
, " ");
1310 /* Send over our environment. */
1313 extern char **environ
;
1315 for (i
= 0; environ
[i
]; i
++)
1317 char *name
= xstrdup (environ
[i
]);
1318 char *value
= strchr (name
, '=');
1319 send_to_emacs (emacs_socket
, "-env ");
1320 quote_argument (emacs_socket
, environ
[i
]);
1321 send_to_emacs (emacs_socket
, " ");
1325 /* Send over our current directory. */
1328 send_to_emacs (emacs_socket
, "-dir ");
1329 quote_argument (emacs_socket
, cwd
);
1330 send_to_emacs (emacs_socket
, "/");
1331 send_to_emacs (emacs_socket
, " ");
1336 send_to_emacs (emacs_socket
, "-nowait ");
1339 send_to_emacs (emacs_socket
, "-current-frame ");
1343 send_to_emacs (emacs_socket
, "-display ");
1344 quote_argument (emacs_socket
, display
);
1345 send_to_emacs (emacs_socket
, " ");
1350 char *type
= getenv ("TERM");
1351 char *tty_name
= NULL
;
1353 tty_name
= ttyname (fileno (stdin
));
1358 message (TRUE
, "%s: could not get terminal name\n", progname
);
1364 message (TRUE
, "%s: please set the TERM variable to your terminal type\n",
1369 if (! strcmp (type
, "eterm"))
1371 /* This causes nasty, MULTI_KBOARD-related input lockouts. */
1372 message (TRUE
, "%s: opening a frame in an Emacs term buffer"
1373 " is not supported\n", progname
);
1376 #if !defined (NO_SOCKETS_IN_FILE_SYSTEM)
1380 send_to_emacs (emacs_socket
, "-tty ");
1381 quote_argument (emacs_socket
, tty_name
);
1382 send_to_emacs (emacs_socket
, " ");
1383 quote_argument (emacs_socket
, type
);
1384 send_to_emacs (emacs_socket
, " ");
1388 send_to_emacs (emacs_socket
, "-window-system ");
1390 if ((argc
- optind
> 0))
1392 for (i
= optind
; i
< argc
; i
++)
1398 /* Don't prepend cwd or anything like that. */
1399 send_to_emacs (emacs_socket
, "-eval ");
1400 quote_argument (emacs_socket
, argv
[i
]);
1401 send_to_emacs (emacs_socket
, " ");
1405 if (*argv
[i
] == '+')
1407 char *p
= argv
[i
] + 1;
1408 while (isdigit ((unsigned char) *p
) || *p
== ':') p
++;
1411 send_to_emacs (emacs_socket
, "-position ");
1412 quote_argument (emacs_socket
, argv
[i
]);
1413 send_to_emacs (emacs_socket
, " ");
1419 else if (! file_name_absolute_p (argv
[i
]))
1422 send_to_emacs (emacs_socket
, "-file ");
1425 quote_argument (emacs_socket
, cwd
);
1426 send_to_emacs (emacs_socket
, "/");
1428 quote_argument (emacs_socket
, argv
[i
]);
1429 send_to_emacs (emacs_socket
, " ");
1434 if (!tty
&& !window_system
)
1436 while ((str
= fgets (string
, BUFSIZ
, stdin
)))
1439 send_to_emacs (emacs_socket
, "-eval ");
1441 send_to_emacs (emacs_socket
, "-file ");
1442 quote_argument (emacs_socket
, str
);
1444 send_to_emacs (emacs_socket
, " ");
1448 send_to_emacs (emacs_socket
, "\n");
1450 /* Wait for an answer. */
1451 if (!eval
&& !tty
&& !nowait
)
1453 printf ("Waiting for Emacs...");
1459 /* Now, wait for an answer and print any messages. */
1460 while ((rl
= recv (emacs_socket
, string
, BUFSIZ
, 0)) > 0)
1465 p
= string
+ strlen (string
) - 1;
1466 while (p
> string
&& *p
== '\n')
1469 if (strprefix ("-good-version ", string
))
1471 /* -good-version: The versions match. */
1473 else if (strprefix ("-emacs-pid ", string
))
1475 /* -emacs-pid PID: The process id of the Emacs process. */
1476 emacs_pid
= strtol (string
+ strlen ("-emacs-pid"), NULL
, 10);
1478 else if (strprefix ("-window-system-unsupported ", string
))
1480 /* -window-system-unsupported: Emacs was compiled without X
1481 support. Try again on the terminal. */
1487 else if (strprefix ("-print ", string
))
1489 /* -print STRING: Print STRING on the terminal. */
1490 str
= unquote_argument (string
+ strlen ("-print "));
1494 needlf
= str
[0] == '\0' ? needlf
: str
[strlen (str
) - 1] != '\n';
1496 else if (strprefix ("-error ", string
))
1498 /* -error DESCRIPTION: Signal an error on the terminal. */
1499 str
= unquote_argument (string
+ strlen ("-error "));
1502 fprintf (stderr
, "*ERROR*: %s", str
);
1503 needlf
= str
[0] == '\0' ? needlf
: str
[strlen (str
) - 1] != '\n';
1506 else if (strprefix ("-suspend ", string
))
1508 /* -suspend: Suspend this terminal, i.e., stop the process. */
1517 /* Unknown command. */
1520 printf ("*ERROR*: Unknown message: %s", string
);
1521 needlf
= string
[0] == '\0' ? needlf
: string
[strlen (string
) - 1] != '\n';
1530 CLOSE_SOCKET (emacs_socket
);
1531 return EXIT_SUCCESS
;
1534 #endif /* HAVE_SOCKETS && HAVE_INET_SOCKETS */
1537 #ifndef HAVE_STRERROR
1542 extern char *sys_errlist
[];
1543 extern int sys_nerr
;
1545 if (errnum
>= 0 && errnum
< sys_nerr
)
1546 return sys_errlist
[errnum
];
1547 return (char *) "Unknown error";
1550 #endif /* ! HAVE_STRERROR */
1552 /* arch-tag: f39bb9c4-73eb-477e-896d-50832e2ca9a7
1553 (do not change this comment) */
1555 /* emacsclient.c ends here */