aboutsummaryrefslogtreecommitdiffstats
path: root/lib-src/emacsclient.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib-src/emacsclient.c')
-rw-r--r--lib-src/emacsclient.c575
1 files changed, 258 insertions, 317 deletions
diff --git a/lib-src/emacsclient.c b/lib-src/emacsclient.c
index 5e1c2d61b89..021ac6eb247 100644
--- a/lib-src/emacsclient.c
+++ b/lib-src/emacsclient.c
@@ -1,5 +1,6 @@
1/* Client process that communicates with GNU Emacs acting as server. 1/* Client process that communicates with GNU Emacs acting as server.
2 Copyright (C) 1986-1987, 1994, 1999-2011 Free Software Foundation, Inc. 2
3Copyright (C) 1986-1987, 1994, 1999-2012 Free Software Foundation, Inc.
3 4
4This file is part of GNU Emacs. 5This file is part of GNU Emacs.
5 6
@@ -21,7 +22,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21 22
22#ifdef WINDOWSNT 23#ifdef WINDOWSNT
23 24
24/* config.h defines these, which disables sockets altogether! */ 25/* ms-w32.h defines these, which disables sockets altogether! */
25# undef _WINSOCKAPI_ 26# undef _WINSOCKAPI_
26# undef _WINSOCK_H 27# undef _WINSOCK_H
27 28
@@ -43,6 +44,10 @@ char *w32_getenv (char *);
43 44
44#else /* !WINDOWSNT */ 45#else /* !WINDOWSNT */
45 46
47# ifdef HAVE_NTGUI
48# include <windows.h>
49# endif /* HAVE_NTGUI */
50
46# include "syswait.h" 51# include "syswait.h"
47 52
48# ifdef HAVE_INET_SOCKETS 53# ifdef HAVE_INET_SOCKETS
@@ -83,10 +88,7 @@ char *w32_getenv (char *);
83 88
84 89
85 90
86char *getenv (const char *), *getwd (char *); 91char *getenv (const char *);
87#ifdef HAVE_GETCWD
88char *(getcwd) (char *, size_t);
89#endif
90 92
91#ifndef VERSION 93#ifndef VERSION
92#define VERSION "unspecified" 94#define VERSION "unspecified"
@@ -112,12 +114,10 @@ char *(getcwd) (char *, size_t);
112/* Additional space when allocating buffers for filenames, etc. */ 114/* Additional space when allocating buffers for filenames, etc. */
113#define EXTRA_SPACE 100 115#define EXTRA_SPACE 100
114 116
115/* Use this to suppress gcc's `...may be used before initialized' warnings. */ 117#ifdef min
116#ifdef lint 118#undef min
117# define IF_LINT(Code) Code
118#else
119# define IF_LINT(Code) /* empty */
120#endif 119#endif
120#define min(x, y) (((x) < (y)) ? (x) : (y))
121 121
122 122
123/* Name used to invoke this program. */ 123/* Name used to invoke this program. */
@@ -141,6 +141,9 @@ int current_frame = 1;
141/* The display on which Emacs should work. --display. */ 141/* The display on which Emacs should work. --display. */
142const char *display = NULL; 142const char *display = NULL;
143 143
144/* The alternate display we should try if Emacs does not support display. */
145const char *alt_display = NULL;
146
144/* The parent window ID, if we are opening a frame via XEmbed. */ 147/* The parent window ID, if we are opening a frame via XEmbed. */
145char *parent_id = NULL; 148char *parent_id = NULL;
146 149
@@ -152,7 +155,7 @@ int tty = 0;
152const char *alternate_editor = NULL; 155const char *alternate_editor = NULL;
153 156
154/* If non-NULL, the filename of the UNIX socket. */ 157/* If non-NULL, the filename of the UNIX socket. */
155char *socket_name = NULL; 158const char *socket_name = NULL;
156 159
157/* If non-NULL, the filename of the authentication file. */ 160/* If non-NULL, the filename of the authentication file. */
158const char *server_file = NULL; 161const char *server_file = NULL;
@@ -164,8 +167,7 @@ int emacs_pid = 0;
164 be used for the new frame */ 167 be used for the new frame */
165const char *frame_parameters = NULL; 168const char *frame_parameters = NULL;
166 169
167static void print_help_and_exit (void) NO_RETURN; 170static _Noreturn void print_help_and_exit (void);
168static void fail (void) NO_RETURN;
169 171
170 172
171struct option longopts[] = 173struct option longopts[] =
@@ -184,9 +186,7 @@ struct option longopts[] =
184 { "socket-name", required_argument, NULL, 's' }, 186 { "socket-name", required_argument, NULL, 's' },
185#endif 187#endif
186 { "server-file", required_argument, NULL, 'f' }, 188 { "server-file", required_argument, NULL, 'f' },
187#ifndef WINDOWSNT
188 { "display", required_argument, NULL, 'd' }, 189 { "display", required_argument, NULL, 'd' },
189#endif
190 { "parent-id", required_argument, NULL, 'p' }, 190 { "parent-id", required_argument, NULL, 'p' },
191 { 0, 0, 0, 0 } 191 { 0, 0, 0, 0 }
192}; 192};
@@ -209,21 +209,6 @@ xmalloc (size_t size)
209/* From sysdep.c */ 209/* From sysdep.c */
210#if !defined (HAVE_GET_CURRENT_DIR_NAME) || defined (BROKEN_GET_CURRENT_DIR_NAME) 210#if !defined (HAVE_GET_CURRENT_DIR_NAME) || defined (BROKEN_GET_CURRENT_DIR_NAME)
211 211
212/* From lisp.h */
213#ifndef DIRECTORY_SEP
214#define DIRECTORY_SEP '/'
215#endif
216#ifndef IS_DIRECTORY_SEP
217#define IS_DIRECTORY_SEP(_c_) ((_c_) == DIRECTORY_SEP)
218#endif
219#ifndef IS_DEVICE_SEP
220#ifndef DEVICE_SEP
221#define IS_DEVICE_SEP(_c_) 0
222#else
223#define IS_DEVICE_SEP(_c_) ((_c_) == DEVICE_SEP)
224#endif
225#endif
226
227char *get_current_dir_name (void); 212char *get_current_dir_name (void);
228 213
229/* Return the current working directory. Returns NULL on errors. 214/* Return the current working directory. Returns NULL on errors.
@@ -235,7 +220,7 @@ get_current_dir_name (void)
235 char *buf; 220 char *buf;
236 const char *pwd; 221 const char *pwd;
237 struct stat dotstat, pwdstat; 222 struct stat dotstat, pwdstat;
238 /* If PWD is accurate, use it instead of calling getwd. PWD is 223 /* If PWD is accurate, use it instead of calling getcwd. PWD is
239 sometimes a nicer name, and using it may avoid a fatal error if a 224 sometimes a nicer name, and using it may avoid a fatal error if a
240 parent directory is searchable but not readable. */ 225 parent directory is searchable but not readable. */
241 if ((pwd = egetenv ("PWD")) != 0 226 if ((pwd = egetenv ("PWD")) != 0
@@ -252,7 +237,6 @@ get_current_dir_name (void)
252 buf = (char *) xmalloc (strlen (pwd) + 1); 237 buf = (char *) xmalloc (strlen (pwd) + 1);
253 strcpy (buf, pwd); 238 strcpy (buf, pwd);
254 } 239 }
255#ifdef HAVE_GETCWD
256 else 240 else
257 { 241 {
258 size_t buf_size = 1024; 242 size_t buf_size = 1024;
@@ -279,20 +263,6 @@ get_current_dir_name (void)
279 } 263 }
280 } 264 }
281 } 265 }
282#else
283 else
284 {
285 /* We need MAXPATHLEN here. */
286 buf = (char *) xmalloc (MAXPATHLEN + 1);
287 if (getwd (buf) == NULL)
288 {
289 int tmp_errno = errno;
290 free (buf);
291 errno = tmp_errno;
292 return NULL;
293 }
294 }
295#endif
296 return buf; 266 return buf;
297} 267}
298#endif 268#endif
@@ -402,32 +372,6 @@ w32_getenv (char *envvar)
402 return NULL; 372 return NULL;
403} 373}
404 374
405void
406w32_set_user_model_id (void)
407{
408 HMODULE shell;
409 HRESULT (WINAPI * set_user_model) (wchar_t * id);
410
411 /* On Windows 7 and later, we need to set the user model ID
412 to associate emacsclient launched files with Emacs frames
413 in the UI. */
414 shell = LoadLibrary ("shell32.dll");
415 if (shell)
416 {
417 set_user_model
418 = (void *) GetProcAddress (shell,
419 "SetCurrentProcessExplicitAppUserModelID");
420 /* If the function is defined, then we are running on Windows 7
421 or newer, and the UI uses this to group related windows
422 together. Since emacs, runemacs, emacsclient are related, we
423 want them grouped even though the executables are different,
424 so we need to set a consistent ID between them. */
425 if (set_user_model)
426 set_user_model (L"GNU.Emacs");
427
428 FreeLibrary (shell);
429 }
430}
431 375
432int 376int
433w32_window_app (void) 377w32_window_app (void)
@@ -447,19 +391,19 @@ w32_window_app (void)
447 return window_app; 391 return window_app;
448} 392}
449 393
450/* 394/* execvp wrapper for Windows. Quotes arguments with embedded spaces.
451 execvp wrapper for Windows. Quotes arguments with embedded spaces.
452 395
453 This is necessary due to the broken implementation of exec* routines in 396 This is necessary due to the broken implementation of exec* routines in
454 the Microsoft libraries: they concatenate the arguments together without 397 the Microsoft libraries: they concatenate the arguments together without
455 quoting special characters, and pass the result to CreateProcess, with 398 quoting special characters, and pass the result to CreateProcess, with
456 predictably bad results. By contrast, POSIX execvp passes the arguments 399 predictably bad results. By contrast, POSIX execvp passes the arguments
457 directly into the argv array of the child process. 400 directly into the argv array of the child process. */
458*/ 401
459int 402int
460w32_execvp (const char *path, char **argv) 403w32_execvp (const char *path, char **argv)
461{ 404{
462 int i; 405 int i;
406 extern int execvp (const char*, char **);
463 407
464 /* Required to allow a .BAT script as alternate editor. */ 408 /* Required to allow a .BAT script as alternate editor. */
465 argv[0] = (char *) alternate_editor; 409 argv[0] = (char *) alternate_editor;
@@ -622,48 +566,52 @@ decode_options (int argc, char **argv)
622 Without the -c option, we used to set `display' to $DISPLAY by 566 Without the -c option, we used to set `display' to $DISPLAY by
623 default, but this changed the default behavior and is sometimes 567 default, but this changed the default behavior and is sometimes
624 inconvenient. So we force users to use "--display $DISPLAY" if 568 inconvenient. So we force users to use "--display $DISPLAY" if
625 they want Emacs to connect to their current display. */ 569 they want Emacs to connect to their current display.
570
571 Some window systems have a notion of default display not
572 reflected in the DISPLAY variable. If the user didn't give us an
573 explicit display, try this platform-specific after trying the
574 display in DISPLAY (if any). */
626 if (!current_frame && !tty && !display) 575 if (!current_frame && !tty && !display)
627 { 576 {
628 display = egetenv ("DISPLAY"); 577 /* Set these here so we use a default_display only when the user
629#ifdef NS_IMPL_COCOA 578 didn't give us an explicit display. */
630 /* Under Cocoa, we don't really use displays the same way as in X, 579#if defined (NS_IMPL_COCOA)
631 so provide a dummy. */ 580 alt_display = "ns";
632 if (!display || strlen (display) == 0) 581#elif defined (HAVE_NTGUI)
633 display = "ns"; 582 alt_display = "w32";
634#endif 583#endif
584
585 display = egetenv ("DISPLAY");
586 }
587
588 if (!display)
589 {
590 display = alt_display;
591 alt_display = NULL;
635 } 592 }
636 593
637 /* A null-string display is invalid. */ 594 /* A null-string display is invalid. */
638 if (display && strlen (display) == 0) 595 if (display && strlen (display) == 0)
639 display = NULL; 596 display = NULL;
640 597
641#ifdef WINDOWSNT
642 /* Emacs on Windows does not support GUI and console frames in the same
643 instance. So, it makes sense to treat the -t and -c options as
644 equivalent, and open a new frame regardless of whether the running
645 instance is GUI or console. Ideally, we would only set tty = 1 when
646 the instance is running in a console, but alas we don't know that.
647 The simplest workaround is to always ask for a tty frame, and let
648 server.el check whether it makes sense. */
649 if (tty || !current_frame)
650 {
651 display = (const char *) ttyname;
652 current_frame = 0;
653 tty = 1;
654 }
655#endif
656
657 /* If no display is available, new frames are tty frames. */ 598 /* If no display is available, new frames are tty frames. */
658 if (!current_frame && !display) 599 if (!current_frame && !display)
659 tty = 1; 600 tty = 1;
660 601
661 /* --no-wait implies --current-frame on ttys when there are file
662 arguments or expressions given. */
663 if (nowait && tty && argc - optind > 0)
664 current_frame = 1;
665
666#ifdef WINDOWSNT 602#ifdef WINDOWSNT
603 /* Emacs on Windows does not support graphical and text terminal
604 frames in the same instance. So, treat the -t and -c options as
605 equivalent, and open a new frame on the server's terminal.
606 Ideally, we would only set tty = 1 when the serve is running in a
607 console, but alas we don't know that. As a workaround, always
608 ask for a tty frame, and let server.el figure it out. */
609 if (!current_frame)
610 {
611 display = NULL;
612 tty = 1;
613 }
614
667 if (alternate_editor && alternate_editor[0] == '\0') 615 if (alternate_editor && alternate_editor[0] == '\0')
668 { 616 {
669 message (TRUE, "--alternate-editor argument or ALTERNATE_EDITOR variable cannot be\n\ 617 message (TRUE, "--alternate-editor argument or ALTERNATE_EDITOR variable cannot be\n\
@@ -674,7 +622,7 @@ an empty string");
674} 622}
675 623
676 624
677static void 625static _Noreturn void
678print_help_and_exit (void) 626print_help_and_exit (void)
679{ 627{
680 /* Spaces and tabs are significant in this message; they're chosen so the 628 /* Spaces and tabs are significant in this message; they're chosen so the
@@ -717,12 +665,11 @@ Report bugs with M-x report-emacs-bug.\n", progname);
717 exit (EXIT_SUCCESS); 665 exit (EXIT_SUCCESS);
718} 666}
719 667
720/* 668/* Try to run a different command, or --if no alternate editor is
721 Try to run a different command, or --if no alternate editor is 669 defined-- exit with an errorcode.
722 defined-- exit with an errorcode. 670 Uses argv, but gets it from the global variable main_argv. */
723 Uses argv, but gets it from the global variable main_argv. 671
724*/ 672static _Noreturn void
725static void
726fail (void) 673fail (void)
727{ 674{
728 if (alternate_editor) 675 if (alternate_editor)
@@ -755,16 +702,15 @@ main (int argc, char **argv)
755#define AUTH_KEY_LENGTH 64 702#define AUTH_KEY_LENGTH 64
756#define SEND_BUFFER_SIZE 4096 703#define SEND_BUFFER_SIZE 4096
757 704
758extern char *strerror (int);
759
760/* Buffer to accumulate data to send in TCP connections. */ 705/* Buffer to accumulate data to send in TCP connections. */
761char send_buffer[SEND_BUFFER_SIZE + 1]; 706char send_buffer[SEND_BUFFER_SIZE + 1];
762int sblen = 0; /* Fill pointer for the send buffer. */ 707int sblen = 0; /* Fill pointer for the send buffer. */
763/* Socket used to communicate with the Emacs server process. */ 708/* Socket used to communicate with the Emacs server process. */
764HSOCKET emacs_socket = 0; 709HSOCKET emacs_socket = 0;
765 710
766/* On Windows, the socket library was historically separate from the standard 711/* On Windows, the socket library was historically separate from the
767 C library, so errors are handled differently. */ 712 standard C library, so errors are handled differently. */
713
768static void 714static void
769sock_err_message (const char *function_name) 715sock_err_message (const char *function_name)
770{ 716{
@@ -792,33 +738,35 @@ sock_err_message (const char *function_name)
792static void 738static void
793send_to_emacs (HSOCKET s, const char *data) 739send_to_emacs (HSOCKET s, const char *data)
794{ 740{
795 while (data) 741 size_t dlen;
742
743 if (!data)
744 return;
745
746 dlen = strlen (data);
747 while (*data)
796 { 748 {
797 size_t dlen = strlen (data); 749 size_t part = min (dlen, SEND_BUFFER_SIZE - sblen);
798 if (dlen + sblen >= SEND_BUFFER_SIZE) 750 memcpy (&send_buffer[sblen], data, part);
799 { 751 data += part;
800 int part = SEND_BUFFER_SIZE - sblen; 752 sblen += part;
801 strncpy (&send_buffer[sblen], data, part);
802 data += part;
803 sblen = SEND_BUFFER_SIZE;
804 }
805 else if (dlen)
806 {
807 strcpy (&send_buffer[sblen], data);
808 data = NULL;
809 sblen += dlen;
810 }
811 else
812 break;
813 753
814 if (sblen == SEND_BUFFER_SIZE 754 if (sblen == SEND_BUFFER_SIZE
815 || (sblen > 0 && send_buffer[sblen-1] == '\n')) 755 || (sblen > 0 && send_buffer[sblen-1] == '\n'))
816 { 756 {
817 int sent = send (s, send_buffer, sblen, 0); 757 int sent = send (s, send_buffer, sblen, 0);
758 if (sent < 0)
759 {
760 message (TRUE, "%s: failed to send %d bytes to socket: %s\n",
761 progname, sblen, strerror (errno));
762 fail ();
763 }
818 if (sent != sblen) 764 if (sent != sblen)
819 strcpy (send_buffer, &send_buffer[sent]); 765 memmove (send_buffer, &send_buffer[sent], sblen - sent);
820 sblen -= sent; 766 sblen -= sent;
821 } 767 }
768
769 dlen -= part;
822 } 770 }
823} 771}
824 772
@@ -867,7 +815,7 @@ quote_argument (HSOCKET s, const char *str)
867 815
868 816
869/* The inverse of quote_argument. Removes quoting in string STR by 817/* The inverse of quote_argument. Removes quoting in string STR by
870 modifying the string in place. Returns STR. */ 818 modifying the string in place. Returns STR. */
871 819
872static char * 820static char *
873unquote_argument (char *str) 821unquote_argument (char *str)
@@ -950,41 +898,41 @@ initialize_sockets (void)
950#endif /* WINDOWSNT */ 898#endif /* WINDOWSNT */
951 899
952 900
953/* 901/* Read the information needed to set up a TCP comm channel with
954 * Read the information needed to set up a TCP comm channel with 902 the Emacs server: host, port, and authentication string. */
955 * the Emacs server: host, port, and authentication string. 903
956 */
957static int 904static int
958get_server_config (struct sockaddr_in *server, char *authentication) 905get_server_config (const char *config_file, struct sockaddr_in *server,
906 char *authentication)
959{ 907{
960 char dotted[32]; 908 char dotted[32];
961 char *port; 909 char *port;
962 FILE *config = NULL; 910 FILE *config = NULL;
963 911
964 if (file_name_absolute_p (server_file)) 912 if (file_name_absolute_p (config_file))
965 config = fopen (server_file, "rb"); 913 config = fopen (config_file, "rb");
966 else 914 else
967 { 915 {
968 const char *home = egetenv ("HOME"); 916 const char *home = egetenv ("HOME");
969 917
970 if (home) 918 if (home)
971 { 919 {
972 char *path = xmalloc (strlen (home) + strlen (server_file) 920 char *path = xmalloc (strlen (home) + strlen (config_file)
973 + EXTRA_SPACE); 921 + EXTRA_SPACE);
974 strcpy (path, home); 922 strcpy (path, home);
975 strcat (path, "/.emacs.d/server/"); 923 strcat (path, "/.emacs.d/server/");
976 strcat (path, server_file); 924 strcat (path, config_file);
977 config = fopen (path, "rb"); 925 config = fopen (path, "rb");
978 free (path); 926 free (path);
979 } 927 }
980#ifdef WINDOWSNT 928#ifdef WINDOWSNT
981 if (!config && (home = egetenv ("APPDATA"))) 929 if (!config && (home = egetenv ("APPDATA")))
982 { 930 {
983 char *path = xmalloc (strlen (home) + strlen (server_file) 931 char *path = xmalloc (strlen (home) + strlen (config_file)
984 + EXTRA_SPACE); 932 + EXTRA_SPACE);
985 strcpy (path, home); 933 strcpy (path, home);
986 strcat (path, "/.emacs.d/server/"); 934 strcat (path, "/.emacs.d/server/");
987 strcat (path, server_file); 935 strcat (path, config_file);
988 config = fopen (path, "rb"); 936 config = fopen (path, "rb");
989 free (path); 937 free (path);
990 } 938 }
@@ -1019,32 +967,28 @@ get_server_config (struct sockaddr_in *server, char *authentication)
1019} 967}
1020 968
1021static HSOCKET 969static HSOCKET
1022set_tcp_socket (void) 970set_tcp_socket (const char *local_server_file)
1023{ 971{
1024 HSOCKET s; 972 HSOCKET s;
1025 struct sockaddr_in server; 973 struct sockaddr_in server;
1026 struct linger l_arg = {1, 1}; 974 struct linger l_arg = {1, 1};
1027 char auth_string[AUTH_KEY_LENGTH + 1]; 975 char auth_string[AUTH_KEY_LENGTH + 1];
1028 976
1029 if (! get_server_config (&server, auth_string)) 977 if (! get_server_config (local_server_file, &server, auth_string))
1030 return INVALID_SOCKET; 978 return INVALID_SOCKET;
1031 979
1032 if (server.sin_addr.s_addr != inet_addr ("127.0.0.1") && !quiet) 980 if (server.sin_addr.s_addr != inet_addr ("127.0.0.1") && !quiet)
1033 message (FALSE, "%s: connected to remote socket at %s\n", 981 message (FALSE, "%s: connected to remote socket at %s\n",
1034 progname, inet_ntoa (server.sin_addr)); 982 progname, inet_ntoa (server.sin_addr));
1035 983
1036 /* 984 /* Open up an AF_INET socket. */
1037 * Open up an AF_INET socket
1038 */
1039 if ((s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) 985 if ((s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
1040 { 986 {
1041 sock_err_message ("socket"); 987 sock_err_message ("socket");
1042 return INVALID_SOCKET; 988 return INVALID_SOCKET;
1043 } 989 }
1044 990
1045 /* 991 /* Set up the socket. */
1046 * Set up the socket
1047 */
1048 if (connect (s, (struct sockaddr *) &server, sizeof server) < 0) 992 if (connect (s, (struct sockaddr *) &server, sizeof server) < 0)
1049 { 993 {
1050 sock_err_message ("connect"); 994 sock_err_message ("connect");
@@ -1053,9 +997,7 @@ set_tcp_socket (void)
1053 997
1054 setsockopt (s, SOL_SOCKET, SO_LINGER, (char *) &l_arg, sizeof l_arg); 998 setsockopt (s, SOL_SOCKET, SO_LINGER, (char *) &l_arg, sizeof l_arg);
1055 999
1056 /* 1000 /* Send the authentication. */
1057 * Send the authentication
1058 */
1059 auth_string[AUTH_KEY_LENGTH] = '\0'; 1001 auth_string[AUTH_KEY_LENGTH] = '\0';
1060 1002
1061 send_to_emacs (s, "-auth "); 1003 send_to_emacs (s, "-auth ");
@@ -1178,7 +1120,7 @@ handle_sigcont (int signalnum)
1178 else 1120 else
1179 { 1121 {
1180 /* We are in the background; cancel the continue. */ 1122 /* We are in the background; cancel the continue. */
1181 kill (getpid (), SIGSTOP); 1123 raise (SIGSTOP);
1182 } 1124 }
1183 1125
1184 signal (signalnum, handle_sigcont); 1126 signal (signalnum, handle_sigcont);
@@ -1189,7 +1131,7 @@ handle_sigcont (int signalnum)
1189 going to sleep. Normally the suspend is initiated by Emacs via 1131 going to sleep. Normally the suspend is initiated by Emacs via
1190 server-handle-suspend-tty, but if the server gets out of sync with 1132 server-handle-suspend-tty, but if the server gets out of sync with
1191 reality, we may get a SIGTSTP on C-z. Handling this signal and 1133 reality, we may get a SIGTSTP on C-z. Handling this signal and
1192 notifying Emacs about it should get things under control again. */ 1134 notifying Emacs about it should get things under control again. */
1193 1135
1194static void 1136static void
1195handle_sigtstp (int signalnum) 1137handle_sigtstp (int signalnum)
@@ -1205,7 +1147,7 @@ handle_sigtstp (int signalnum)
1205 sigprocmask (SIG_BLOCK, NULL, &set); 1147 sigprocmask (SIG_BLOCK, NULL, &set);
1206 sigdelset (&set, signalnum); 1148 sigdelset (&set, signalnum);
1207 signal (signalnum, SIG_DFL); 1149 signal (signalnum, SIG_DFL);
1208 kill (getpid (), signalnum); 1150 raise (signalnum);
1209 sigprocmask (SIG_SETMASK, &set, NULL); /* Let's the above signal through. */ 1151 sigprocmask (SIG_SETMASK, &set, NULL); /* Let's the above signal through. */
1210 signal (signalnum, handle_sigtstp); 1152 signal (signalnum, handle_sigtstp);
1211 1153
@@ -1236,15 +1178,12 @@ init_signals (void)
1236 1178
1237 1179
1238static HSOCKET 1180static HSOCKET
1239set_local_socket (void) 1181set_local_socket (const char *local_socket_name)
1240{ 1182{
1241 HSOCKET s; 1183 HSOCKET s;
1242 struct sockaddr_un server; 1184 struct sockaddr_un server;
1243 1185
1244 /* 1186 /* Open up an AF_UNIX socket in this person's home directory. */
1245 * Open up an AF_UNIX socket in this person's home directory
1246 */
1247
1248 if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) 1187 if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
1249 { 1188 {
1250 message (TRUE, "%s: socket: %s\n", progname, strerror (errno)); 1189 message (TRUE, "%s: socket: %s\n", progname, strerror (errno));
@@ -1254,27 +1193,20 @@ set_local_socket (void)
1254 server.sun_family = AF_UNIX; 1193 server.sun_family = AF_UNIX;
1255 1194
1256 { 1195 {
1257 int sock_status = 0; 1196 int sock_status;
1258 int default_sock = !socket_name; 1197 int use_tmpdir = 0;
1259 int saved_errno = 0; 1198 int saved_errno;
1260 const char *server_name = "server"; 1199 const char *server_name = local_socket_name;
1261 const char *tmpdir IF_LINT ( = NULL); 1200 const char *tmpdir IF_LINT ( = NULL);
1262 char *tmpdir_storage = NULL; 1201 char *tmpdir_storage = NULL;
1263 char *socket_name_storage = NULL; 1202 char *socket_name_storage = NULL;
1264 1203
1265 if (socket_name && !strchr (socket_name, '/') 1204 if (!strchr (local_socket_name, '/') && !strchr (local_socket_name, '\\'))
1266 && !strchr (socket_name, '\\'))
1267 { 1205 {
1268 /* socket_name is a file name component. */ 1206 /* socket_name is a file name component. */
1269 server_name = socket_name;
1270 socket_name = NULL;
1271 default_sock = 1; /* Try both UIDs. */
1272 }
1273
1274 if (default_sock)
1275 {
1276 long uid = geteuid (); 1207 long uid = geteuid ();
1277 ptrdiff_t tmpdirlen; 1208 ptrdiff_t tmpdirlen;
1209 use_tmpdir = 1;
1278 tmpdir = egetenv ("TMPDIR"); 1210 tmpdir = egetenv ("TMPDIR");
1279 if (!tmpdir) 1211 if (!tmpdir)
1280 { 1212 {
@@ -1286,33 +1218,34 @@ set_local_socket (void)
1286 if (n > 0) 1218 if (n > 0)
1287 { 1219 {
1288 tmpdir = tmpdir_storage = xmalloc (n); 1220 tmpdir = tmpdir_storage = xmalloc (n);
1289 confstr (_CS_DARWIN_USER_TEMP_DIR, tmpdir, n); 1221 confstr (_CS_DARWIN_USER_TEMP_DIR, tmpdir_storage, n);
1290 } 1222 }
1291 else 1223 else
1292#endif 1224#endif
1293 tmpdir = "/tmp"; 1225 tmpdir = "/tmp";
1294 } 1226 }
1295 tmpdirlen = strlen (tmpdir); 1227 tmpdirlen = strlen (tmpdir);
1296 socket_name = socket_name_storage = 1228 socket_name_storage =
1297 xmalloc (tmpdirlen + strlen (server_name) + EXTRA_SPACE); 1229 xmalloc (tmpdirlen + strlen (server_name) + EXTRA_SPACE);
1298 strcpy (socket_name, tmpdir); 1230 strcpy (socket_name_storage, tmpdir);
1299 sprintf (socket_name + tmpdirlen, "/emacs%ld/", uid); 1231 sprintf (socket_name_storage + tmpdirlen, "/emacs%ld/", uid);
1300 strcat (socket_name + tmpdirlen, server_name); 1232 strcat (socket_name_storage + tmpdirlen, server_name);
1233 local_socket_name = socket_name_storage;
1301 } 1234 }
1302 1235
1303 if (strlen (socket_name) < sizeof (server.sun_path)) 1236 if (strlen (local_socket_name) < sizeof (server.sun_path))
1304 strcpy (server.sun_path, socket_name); 1237 strcpy (server.sun_path, local_socket_name);
1305 else 1238 else
1306 { 1239 {
1307 message (TRUE, "%s: socket-name %s too long\n", 1240 message (TRUE, "%s: socket-name %s too long\n",
1308 progname, socket_name); 1241 progname, local_socket_name);
1309 fail (); 1242 fail ();
1310 } 1243 }
1311 1244
1312 /* See if the socket exists, and if it's owned by us. */ 1245 /* See if the socket exists, and if it's owned by us. */
1313 sock_status = socket_status (server.sun_path); 1246 sock_status = socket_status (server.sun_path);
1314 saved_errno = errno; 1247 saved_errno = errno;
1315 if (sock_status && default_sock) 1248 if (sock_status && use_tmpdir)
1316 { 1249 {
1317 /* Failing that, see if LOGNAME or USER exist and differ from 1250 /* Failing that, see if LOGNAME or USER exist and differ from
1318 our euid. If so, look for a socket based on the UID 1251 our euid. If so, look for a socket based on the UID
@@ -1333,21 +1266,21 @@ set_local_socket (void)
1333 /* We're running under su, apparently. */ 1266 /* We're running under su, apparently. */
1334 long uid = pw->pw_uid; 1267 long uid = pw->pw_uid;
1335 ptrdiff_t tmpdirlen = strlen (tmpdir); 1268 ptrdiff_t tmpdirlen = strlen (tmpdir);
1336 socket_name = xmalloc (tmpdirlen + strlen (server_name) 1269 char *user_socket_name
1337 + EXTRA_SPACE); 1270 = xmalloc (tmpdirlen + strlen (server_name) + EXTRA_SPACE);
1338 strcpy (socket_name, tmpdir); 1271 strcpy (user_socket_name, tmpdir);
1339 sprintf (socket_name + tmpdirlen, "/emacs%ld/", uid); 1272 sprintf (user_socket_name + tmpdirlen, "/emacs%ld/", uid);
1340 strcat (socket_name + tmpdirlen, server_name); 1273 strcat (user_socket_name + tmpdirlen, server_name);
1341 1274
1342 if (strlen (socket_name) < sizeof (server.sun_path)) 1275 if (strlen (user_socket_name) < sizeof (server.sun_path))
1343 strcpy (server.sun_path, socket_name); 1276 strcpy (server.sun_path, user_socket_name);
1344 else 1277 else
1345 { 1278 {
1346 message (TRUE, "%s: socket-name %s too long\n", 1279 message (TRUE, "%s: socket-name %s too long\n",
1347 progname, socket_name); 1280 progname, user_socket_name);
1348 exit (EXIT_FAILURE); 1281 exit (EXIT_FAILURE);
1349 } 1282 }
1350 free (socket_name); 1283 free (user_socket_name);
1351 1284
1352 sock_status = socket_status (server.sun_path); 1285 sock_status = socket_status (server.sun_path);
1353 saved_errno = errno; 1286 saved_errno = errno;
@@ -1401,6 +1334,7 @@ static HSOCKET
1401set_socket (int no_exit_if_error) 1334set_socket (int no_exit_if_error)
1402{ 1335{
1403 HSOCKET s; 1336 HSOCKET s;
1337 const char *local_server_file = server_file;
1404 1338
1405 INITIALIZE (); 1339 INITIALIZE ();
1406 1340
@@ -1408,7 +1342,7 @@ set_socket (int no_exit_if_error)
1408 /* Explicit --socket-name argument. */ 1342 /* Explicit --socket-name argument. */
1409 if (socket_name) 1343 if (socket_name)
1410 { 1344 {
1411 s = set_local_socket (); 1345 s = set_local_socket (socket_name);
1412 if ((s != INVALID_SOCKET) || no_exit_if_error) 1346 if ((s != INVALID_SOCKET) || no_exit_if_error)
1413 return s; 1347 return s;
1414 message (TRUE, "%s: error accessing socket \"%s\"\n", 1348 message (TRUE, "%s: error accessing socket \"%s\"\n",
@@ -1418,30 +1352,29 @@ set_socket (int no_exit_if_error)
1418#endif 1352#endif
1419 1353
1420 /* Explicit --server-file arg or EMACS_SERVER_FILE variable. */ 1354 /* Explicit --server-file arg or EMACS_SERVER_FILE variable. */
1421 if (!server_file) 1355 if (!local_server_file)
1422 server_file = egetenv ("EMACS_SERVER_FILE"); 1356 local_server_file = egetenv ("EMACS_SERVER_FILE");
1423 1357
1424 if (server_file) 1358 if (local_server_file)
1425 { 1359 {
1426 s = set_tcp_socket (); 1360 s = set_tcp_socket (local_server_file);
1427 if ((s != INVALID_SOCKET) || no_exit_if_error) 1361 if ((s != INVALID_SOCKET) || no_exit_if_error)
1428 return s; 1362 return s;
1429 1363
1430 message (TRUE, "%s: error accessing server file \"%s\"\n", 1364 message (TRUE, "%s: error accessing server file \"%s\"\n",
1431 progname, server_file); 1365 progname, local_server_file);
1432 exit (EXIT_FAILURE); 1366 exit (EXIT_FAILURE);
1433 } 1367 }
1434 1368
1435#ifndef NO_SOCKETS_IN_FILE_SYSTEM 1369#ifndef NO_SOCKETS_IN_FILE_SYSTEM
1436 /* Implicit local socket. */ 1370 /* Implicit local socket. */
1437 s = set_local_socket (); 1371 s = set_local_socket ("server");
1438 if (s != INVALID_SOCKET) 1372 if (s != INVALID_SOCKET)
1439 return s; 1373 return s;
1440#endif 1374#endif
1441 1375
1442 /* Implicit server file. */ 1376 /* Implicit server file. */
1443 server_file = "server"; 1377 s = set_tcp_socket ("server");
1444 s = set_tcp_socket ();
1445 if ((s != INVALID_SOCKET) || no_exit_if_error) 1378 if ((s != INVALID_SOCKET) || no_exit_if_error)
1446 return s; 1379 return s;
1447 1380
@@ -1456,10 +1389,37 @@ set_socket (int no_exit_if_error)
1456 exit (EXIT_FAILURE); 1389 exit (EXIT_FAILURE);
1457} 1390}
1458 1391
1459#ifdef WINDOWSNT 1392#ifdef HAVE_NTGUI
1460FARPROC set_fg; /* Pointer to AllowSetForegroundWindow. */ 1393FARPROC set_fg; /* Pointer to AllowSetForegroundWindow. */
1461FARPROC get_wc; /* Pointer to RealGetWindowClassA. */ 1394FARPROC get_wc; /* Pointer to RealGetWindowClassA. */
1462 1395
1396void
1397w32_set_user_model_id (void)
1398{
1399 HMODULE shell;
1400 HRESULT (WINAPI * set_user_model) (wchar_t * id);
1401
1402 /* On Windows 7 and later, we need to set the user model ID
1403 to associate emacsclient launched files with Emacs frames
1404 in the UI. */
1405 shell = LoadLibrary ("shell32.dll");
1406 if (shell)
1407 {
1408 set_user_model
1409 = (void *) GetProcAddress (shell,
1410 "SetCurrentProcessExplicitAppUserModelID");
1411 /* If the function is defined, then we are running on Windows 7
1412 or newer, and the UI uses this to group related windows
1413 together. Since emacs, runemacs, emacsclient are related, we
1414 want them grouped even though the executables are different,
1415 so we need to set a consistent ID between them. */
1416 if (set_user_model)
1417 set_user_model (L"GNU.Emacs");
1418
1419 FreeLibrary (shell);
1420 }
1421}
1422
1463BOOL CALLBACK 1423BOOL CALLBACK
1464w32_find_emacs_process (HWND hWnd, LPARAM lParam) 1424w32_find_emacs_process (HWND hWnd, LPARAM lParam)
1465{ 1425{
@@ -1484,10 +1444,9 @@ w32_find_emacs_process (HWND hWnd, LPARAM lParam)
1484 return FALSE; 1444 return FALSE;
1485} 1445}
1486 1446
1487/* 1447/* Search for a window of class "Emacs" and owned by a process with
1488 * Search for a window of class "Emacs" and owned by a process with 1448 process id = emacs_pid. If found, allow it to grab the focus. */
1489 * process id = emacs_pid. If found, allow it to grab the focus. 1449
1490 */
1491void 1450void
1492w32_give_focus (void) 1451w32_give_focus (void)
1493{ 1452{
@@ -1509,7 +1468,7 @@ w32_give_focus (void)
1509 && (get_wc = GetProcAddress (user32, "RealGetWindowClassA"))) 1468 && (get_wc = GetProcAddress (user32, "RealGetWindowClassA")))
1510 EnumWindows (w32_find_emacs_process, (LPARAM) 0); 1469 EnumWindows (w32_find_emacs_process, (LPARAM) 0);
1511} 1470}
1512#endif 1471#endif /* HAVE_NTGUI */
1513 1472
1514/* Start the emacs daemon and try to connect to it. */ 1473/* Start the emacs daemon and try to connect to it. */
1515 1474
@@ -1573,19 +1532,19 @@ main (int argc, char **argv)
1573 int rl = 0, needlf = 0; 1532 int rl = 0, needlf = 0;
1574 char *cwd, *str; 1533 char *cwd, *str;
1575 char string[BUFSIZ+1]; 1534 char string[BUFSIZ+1];
1576 int null_socket_name IF_LINT ( = 0);
1577 int null_server_file IF_LINT ( = 0);
1578 int start_daemon_if_needed; 1535 int start_daemon_if_needed;
1579 int exit_status = EXIT_SUCCESS; 1536 int exit_status = EXIT_SUCCESS;
1580 1537
1581 main_argv = argv; 1538 main_argv = argv;
1582 progname = argv[0]; 1539 progname = argv[0];
1583 1540
1584#ifdef WINDOWSNT 1541#ifdef HAVE_NTGUI
1585 /* On Windows 7 and later, we need to explicitly associate emacsclient 1542 /* On Windows 7 and later, we need to explicitly associate
1586 with emacs so the UI behaves sensibly. */ 1543 emacsclient with emacs so the UI behaves sensibly. This
1544 association does no harm if we're not actually connecting to an
1545 Emacs using a window display. */
1587 w32_set_user_model_id (); 1546 w32_set_user_model_id ();
1588#endif 1547#endif /* HAVE_NTGUI */
1589 1548
1590 /* Process options. */ 1549 /* Process options. */
1591 decode_options (argc, argv); 1550 decode_options (argc, argv);
@@ -1602,14 +1561,6 @@ main (int argc, char **argv)
1602 in case of failure to connect. */ 1561 in case of failure to connect. */
1603 start_daemon_if_needed = (alternate_editor 1562 start_daemon_if_needed = (alternate_editor
1604 && (alternate_editor[0] == '\0')); 1563 && (alternate_editor[0] == '\0'));
1605 if (start_daemon_if_needed)
1606 {
1607 /* set_socket changes the values for socket_name and
1608 server_file, we need to reset them, if they were NULL before
1609 for the second call to set_socket. */
1610 null_socket_name = (socket_name == NULL);
1611 null_server_file = (server_file == NULL);
1612 }
1613 1564
1614 emacs_socket = set_socket (alternate_editor || start_daemon_if_needed); 1565 emacs_socket = set_socket (alternate_editor || start_daemon_if_needed);
1615 if (emacs_socket == INVALID_SOCKET) 1566 if (emacs_socket == INVALID_SOCKET)
@@ -1617,37 +1568,25 @@ main (int argc, char **argv)
1617 if (! start_daemon_if_needed) 1568 if (! start_daemon_if_needed)
1618 fail (); 1569 fail ();
1619 1570
1620 /* Reset socket_name and server_file if they were NULL
1621 before the set_socket call. */
1622 if (null_socket_name)
1623 socket_name = NULL;
1624 if (null_server_file)
1625 server_file = NULL;
1626
1627 start_daemon_and_retry_set_socket (); 1571 start_daemon_and_retry_set_socket ();
1628 } 1572 }
1629 1573
1630 cwd = get_current_dir_name (); 1574 cwd = get_current_dir_name ();
1631 if (cwd == 0) 1575 if (cwd == 0)
1632 { 1576 {
1633 /* getwd puts message in STRING if it fails. */
1634 message (TRUE, "%s: %s\n", progname, 1577 message (TRUE, "%s: %s\n", progname,
1635 "Cannot get current working directory"); 1578 "Cannot get current working directory");
1636 fail (); 1579 fail ();
1637 } 1580 }
1638 1581
1639#ifdef WINDOWSNT 1582#ifdef HAVE_NTGUI
1583 if (display && !strcmp (display, "w32"))
1640 w32_give_focus (); 1584 w32_give_focus ();
1641#endif 1585#endif /* HAVE_NTGUI */
1642 1586
1643 /* Send over our environment and current directory. */ 1587 /* Send over our environment and current directory. */
1644 if (!current_frame) 1588 if (!current_frame)
1645 { 1589 {
1646#ifndef WINDOWSNT
1647 /* This is defined in stdlib.h on MS-Windows. It's defined in
1648 unistd.h on some POSIX hosts, but not all (Bug#10155). */
1649 extern char **environ;
1650#endif
1651 int i; 1590 int i;
1652 for (i = 0; environ[i]; i++) 1591 for (i = 0; environ[i]; i++)
1653 { 1592 {
@@ -1689,10 +1628,10 @@ main (int argc, char **argv)
1689 send_to_emacs (emacs_socket, " "); 1628 send_to_emacs (emacs_socket, " ");
1690 } 1629 }
1691 1630
1692 /* If using the current frame, send tty information to Emacs anyway. 1631 /* Unless we are certain we don't want to occupy the tty, send our
1693 In daemon mode, Emacs may need to occupy this tty if no other 1632 tty information to Emacs. For example, in daemon mode Emacs may
1694 frame is available. */ 1633 need to occupy this tty if no other frame is available. */
1695 if (tty || (current_frame && !eval)) 1634 if (!current_frame || !eval)
1696 { 1635 {
1697 const char *tty_type, *tty_name; 1636 const char *tty_type, *tty_name;
1698 1637
@@ -1790,7 +1729,7 @@ main (int argc, char **argv)
1790 /* Now, wait for an answer and print any messages. */ 1729 /* Now, wait for an answer and print any messages. */
1791 while (exit_status == EXIT_SUCCESS) 1730 while (exit_status == EXIT_SUCCESS)
1792 { 1731 {
1793 char *p; 1732 char *p, *end_p;
1794 do 1733 do
1795 { 1734 {
1796 errno = 0; 1735 errno = 0;
@@ -1805,61 +1744,82 @@ main (int argc, char **argv)
1805 1744
1806 string[rl] = '\0'; 1745 string[rl] = '\0';
1807 1746
1808 p = string + strlen (string) - 1; 1747 /* Loop over all NL-terminated messages. */
1809 while (p > string && *p == '\n') 1748 for (end_p = p = string; end_p != NULL && *end_p != '\0'; p = end_p)
1810 *p-- = 0; 1749 {
1750 end_p = strchr (p, '\n');
1751 if (end_p != NULL)
1752 *end_p++ = '\0';
1811 1753
1812 if (strprefix ("-emacs-pid ", string)) 1754 if (strprefix ("-emacs-pid ", p))
1813 { 1755 {
1814 /* -emacs-pid PID: The process id of the Emacs process. */ 1756 /* -emacs-pid PID: The process id of the Emacs process. */
1815 emacs_pid = strtol (string + strlen ("-emacs-pid"), NULL, 10); 1757 emacs_pid = strtol (p + strlen ("-emacs-pid"), NULL, 10);
1816 } 1758 }
1817 else if (strprefix ("-window-system-unsupported ", string)) 1759 else if (strprefix ("-window-system-unsupported ", p))
1818 { 1760 {
1819 /* -window-system-unsupported: Emacs was compiled without X 1761 /* -window-system-unsupported: Emacs was compiled without support
1820 support. Try again on the terminal. */ 1762 for whatever window system we tried. Try the alternate
1821 nowait = 0; 1763 display, or, failing that, try the terminal. */
1822 tty = 1; 1764 if (alt_display)
1823 goto retry; 1765 {
1824 } 1766 display = alt_display;
1825 else if (strprefix ("-print ", string)) 1767 alt_display = NULL;
1826 { 1768 }
1827 /* -print STRING: Print STRING on the terminal. */ 1769 else
1828 str = unquote_argument (string + strlen ("-print ")); 1770 {
1829 if (needlf) 1771 nowait = 0;
1830 printf ("\n"); 1772 tty = 1;
1831 printf ("%s", str); 1773 }
1832 needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n'; 1774
1833 } 1775 goto retry;
1834 else if (strprefix ("-error ", string)) 1776 }
1835 { 1777 else if (strprefix ("-print ", p))
1836 /* -error DESCRIPTION: Signal an error on the terminal. */ 1778 {
1837 str = unquote_argument (string + strlen ("-error ")); 1779 /* -print STRING: Print STRING on the terminal. */
1838 if (needlf) 1780 str = unquote_argument (p + strlen ("-print "));
1839 printf ("\n"); 1781 if (needlf)
1840 fprintf (stderr, "*ERROR*: %s", str); 1782 printf ("\n");
1841 needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n'; 1783 printf ("%s", str);
1842 exit_status = EXIT_FAILURE; 1784 needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n';
1843 } 1785 }
1786 else if (strprefix ("-print-nonl ", p))
1787 {
1788 /* -print-nonl STRING: Print STRING on the terminal.
1789 Used to continue a preceding -print command. */
1790 str = unquote_argument (p + strlen ("-print-nonl "));
1791 printf ("%s", str);
1792 needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n';
1793 }
1794 else if (strprefix ("-error ", p))
1795 {
1796 /* -error DESCRIPTION: Signal an error on the terminal. */
1797 str = unquote_argument (p + strlen ("-error "));
1798 if (needlf)
1799 printf ("\n");
1800 fprintf (stderr, "*ERROR*: %s", str);
1801 needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n';
1802 exit_status = EXIT_FAILURE;
1803 }
1844#ifdef SIGSTOP 1804#ifdef SIGSTOP
1845 else if (strprefix ("-suspend ", string)) 1805 else if (strprefix ("-suspend ", p))
1846 { 1806 {
1847 /* -suspend: Suspend this terminal, i.e., stop the process. */ 1807 /* -suspend: Suspend this terminal, i.e., stop the process. */
1848 if (needlf) 1808 if (needlf)
1849 printf ("\n"); 1809 printf ("\n");
1850 needlf = 0; 1810 needlf = 0;
1851 kill (0, SIGSTOP); 1811 kill (0, SIGSTOP);
1852 } 1812 }
1853#endif 1813#endif
1854 else 1814 else
1855 { 1815 {
1856 /* Unknown command. */ 1816 /* Unknown command. */
1857 if (needlf) 1817 if (needlf)
1858 printf ("\n"); 1818 printf ("\n");
1859 printf ("*ERROR*: Unknown message: %s", string); 1819 needlf = 0;
1860 needlf = string[0] 1820 printf ("*ERROR*: Unknown message: %s\n", p);
1861 == '\0' ? needlf : string[strlen (string) - 1] != '\n'; 1821 }
1862 } 1822 }
1863 } 1823 }
1864 1824
1865 if (needlf) 1825 if (needlf)
@@ -1875,22 +1835,3 @@ main (int argc, char **argv)
1875} 1835}
1876 1836
1877#endif /* HAVE_SOCKETS && HAVE_INET_SOCKETS */ 1837#endif /* HAVE_SOCKETS && HAVE_INET_SOCKETS */
1878
1879
1880#ifndef HAVE_STRERROR
1881char *
1882strerror (errnum)
1883 int errnum;
1884{
1885 extern char *sys_errlist[];
1886 extern int sys_nerr;
1887
1888 if (errnum >= 0 && errnum < sys_nerr)
1889 return sys_errlist[errnum];
1890 return (char *) "Unknown error";
1891}
1892
1893#endif /* ! HAVE_STRERROR */
1894
1895
1896/* emacsclient.c ends here */