Merge from emacs--rel--22
[bpt/emacs.git] / 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, 2008 Free Software Foundation, Inc.
4
5 This file is part of GNU Emacs.
6
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)
10 any later version.
11
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.
16
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. */
21
22
23 #define NO_SHORTNAMES
24
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28
29 #ifdef WINDOWSNT
30
31 /* config.h defines these, which disables sockets altogether! */
32 # undef _WINSOCKAPI_
33 # undef _WINSOCK_H
34
35 # include <malloc.h>
36 # include <stdlib.h>
37 # include <windows.h>
38 # include <commctrl.h>
39
40 # define NO_SOCKETS_IN_FILE_SYSTEM
41
42 # define HSOCKET SOCKET
43 # define CLOSE_SOCKET closesocket
44 # define INITIALIZE() (initialize_sockets ())
45
46 #else /* !WINDOWSNT */
47
48 # include <sys/types.h>
49
50 # ifdef HAVE_INET_SOCKETS
51 # include <netinet/in.h>
52 # endif
53
54 # define INVALID_SOCKET -1
55 # define HSOCKET int
56 # define CLOSE_SOCKET close
57 # define INITIALIZE()
58
59 #endif /* !WINDOWSNT */
60
61 #undef signal
62
63 #include <stdarg.h>
64 #include <ctype.h>
65 #include <stdio.h>
66 #include "getopt.h"
67 #ifdef HAVE_UNISTD_H
68 #include <unistd.h>
69 #endif
70
71 #ifdef VMS
72 # include "vms-pwd.h"
73 #else /* not VMS */
74 #ifdef WINDOWSNT
75 # include <io.h>
76 #else /* not WINDOWSNT */
77 # include <pwd.h>
78 #endif /* not WINDOWSNT */
79 #endif /* not VMS */
80 #include <sys/stat.h>
81
82 #include <signal.h>
83 #include <errno.h>
84
85 \f
86 char *getenv (), *getwd ();
87 char *(getcwd) ();
88
89 #ifdef WINDOWSNT
90 char *w32_getenv ();
91 #define egetenv(VAR) w32_getenv(VAR)
92 #else
93 #define egetenv(VAR) getenv(VAR)
94 #endif
95
96 #ifndef VERSION
97 #define VERSION "unspecified"
98 #endif
99 \f
100
101 #ifndef EXIT_SUCCESS
102 #define EXIT_SUCCESS 0
103 #endif
104
105 #ifndef EXIT_FAILURE
106 #define EXIT_FAILURE 1
107 #endif
108
109 #ifndef FALSE
110 #define FALSE 0
111 #endif
112
113 #ifndef TRUE
114 #define TRUE 1
115 #endif
116
117 #ifndef NO_RETURN
118 #define NO_RETURN
119 #endif
120 \f
121 /* Name used to invoke this program. */
122 char *progname;
123
124 /* The second argument to main. */
125 char **main_argv;
126
127 /* Nonzero means don't wait for a response from Emacs. --no-wait. */
128 int nowait = 0;
129
130 /* Nonzero means args are expressions to be evaluated. --eval. */
131 int eval = 0;
132
133 /* Nonzero means don't open a new frame. Inverse of --create-frame. */
134 int current_frame = 1;
135
136 /* Nonzero means open a new graphical frame. */
137 int window_system = 0;
138
139 /* The display on which Emacs should work. --display. */
140 char *display = NULL;
141
142 /* Nonzero means open a new Emacs frame on the current terminal. */
143 int tty = 0;
144
145 /* If non-NULL, the name of an editor to fallback to if the server
146 is not running. --alternate-editor. */
147 const char *alternate_editor = NULL;
148
149 /* If non-NULL, the filename of the UNIX socket. */
150 char *socket_name = NULL;
151
152 /* If non-NULL, the filename of the authentication file. */
153 char *server_file = NULL;
154
155 /* PID of the Emacs server process. */
156 int emacs_pid = 0;
157
158 void print_help_and_exit () NO_RETURN;
159
160 struct option longopts[] =
161 {
162 { "no-wait", no_argument, NULL, 'n' },
163 { "eval", no_argument, NULL, 'e' },
164 { "help", no_argument, NULL, 'H' },
165 { "version", no_argument, NULL, 'V' },
166 { "tty", no_argument, NULL, 't' },
167 { "create-frame", no_argument, NULL, 'c' },
168 { "alternate-editor", required_argument, NULL, 'a' },
169 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
170 { "socket-name", required_argument, NULL, 's' },
171 #endif
172 { "server-file", required_argument, NULL, 'f' },
173 #ifndef WINDOWSNT
174 { "display", required_argument, NULL, 'd' },
175 #endif
176 { 0, 0, 0, 0 }
177 };
178
179 \f
180 /* Like malloc but get fatal error if memory is exhausted. */
181
182 long *
183 xmalloc (size)
184 unsigned int size;
185 {
186 long *result = (long *) malloc (size);
187 if (result == NULL)
188 {
189 perror ("malloc");
190 exit (EXIT_FAILURE);
191 }
192 return result;
193 }
194
195 /* Like strdup but get a fatal error if memory is exhausted. */
196
197 char *
198 xstrdup (const char *s)
199 {
200 char *result = strdup (s);
201 if (result == NULL)
202 {
203 perror ("strdup");
204 exit (EXIT_FAILURE);
205 }
206 return result;
207 }
208
209 /* From sysdep.c */
210 #if !defined (HAVE_GET_CURRENT_DIR_NAME) || defined (BROKEN_GET_CURRENT_DIR_NAME)
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 #ifndef IS_ANY_SEP
227 #define IS_ANY_SEP(_c_) (IS_DIRECTORY_SEP (_c_))
228 #endif
229
230
231 /* Return the current working directory. Returns NULL on errors.
232 Any other returned value must be freed with free. This is used
233 only when get_current_dir_name is not defined on the system. */
234 char*
235 get_current_dir_name ()
236 {
237 char *buf;
238 char *pwd;
239 struct stat dotstat, pwdstat;
240 /* If PWD is accurate, use it instead of calling getwd. PWD is
241 sometimes a nicer name, and using it may avoid a fatal error if a
242 parent directory is searchable but not readable. */
243 if ((pwd = egetenv ("PWD")) != 0
244 && (IS_DIRECTORY_SEP (*pwd) || (*pwd && IS_DEVICE_SEP (pwd[1])))
245 && stat (pwd, &pwdstat) == 0
246 && stat (".", &dotstat) == 0
247 && dotstat.st_ino == pwdstat.st_ino
248 && dotstat.st_dev == pwdstat.st_dev
249 #ifdef MAXPATHLEN
250 && strlen (pwd) < MAXPATHLEN
251 #endif
252 )
253 {
254 buf = (char *) xmalloc (strlen (pwd) + 1);
255 if (!buf)
256 return NULL;
257 strcpy (buf, pwd);
258 }
259 #ifdef HAVE_GETCWD
260 else
261 {
262 size_t buf_size = 1024;
263 buf = (char *) xmalloc (buf_size);
264 if (!buf)
265 return NULL;
266 for (;;)
267 {
268 if (getcwd (buf, buf_size) == buf)
269 break;
270 if (errno != ERANGE)
271 {
272 int tmp_errno = errno;
273 free (buf);
274 errno = tmp_errno;
275 return NULL;
276 }
277 buf_size *= 2;
278 buf = (char *) realloc (buf, buf_size);
279 if (!buf)
280 return NULL;
281 }
282 }
283 #else
284 else
285 {
286 /* We need MAXPATHLEN here. */
287 buf = (char *) xmalloc (MAXPATHLEN + 1);
288 if (!buf)
289 return NULL;
290 if (getwd (buf) == NULL)
291 {
292 int tmp_errno = errno;
293 free (buf);
294 errno = tmp_errno;
295 return NULL;
296 }
297 }
298 #endif
299 return buf;
300 }
301 #endif
302
303 #ifdef WINDOWSNT
304
305 #define REG_ROOT "SOFTWARE\\GNU\\Emacs"
306
307 /* Retrieve an environment variable from the Emacs subkeys of the registry.
308 Return NULL if the variable was not found, or it was empty.
309 This code is based on w32_get_resource (w32.c). */
310 char *
311 w32_get_resource (predefined, key, type)
312 HKEY predefined;
313 char *key;
314 LPDWORD type;
315 {
316 HKEY hrootkey = NULL;
317 char *result = NULL;
318 DWORD cbData;
319
320 if (RegOpenKeyEx (predefined, REG_ROOT, 0, KEY_READ, &hrootkey) == ERROR_SUCCESS)
321 {
322 if (RegQueryValueEx (hrootkey, key, NULL, NULL, NULL, &cbData) == ERROR_SUCCESS)
323 {
324 result = (char *) xmalloc (cbData);
325
326 if ((RegQueryValueEx (hrootkey, key, NULL, type, result, &cbData) != ERROR_SUCCESS) ||
327 (*result == 0))
328 {
329 free (result);
330 result = NULL;
331 }
332 }
333
334 RegCloseKey (hrootkey);
335 }
336
337 return result;
338 }
339
340 /*
341 getenv wrapper for Windows
342
343 This is needed to duplicate Emacs's behavior, which is to look for enviroment
344 variables in the registry if they don't appear in the environment.
345 */
346 char *
347 w32_getenv (envvar)
348 char *envvar;
349 {
350 char *value;
351 DWORD dwType;
352
353 if (value = getenv (envvar))
354 /* Found in the environment. */
355 return value;
356
357 if (! (value = w32_get_resource (HKEY_CURRENT_USER, envvar, &dwType)) &&
358 ! (value = w32_get_resource (HKEY_LOCAL_MACHINE, envvar, &dwType)))
359 /* Not found in the registry. */
360 return NULL;
361
362 if (dwType == REG_SZ)
363 /* Registry; no need to expand. */
364 return value;
365
366 if (dwType == REG_EXPAND_SZ)
367 {
368 DWORD size;
369
370 if (size = ExpandEnvironmentStrings (value, NULL, 0))
371 {
372 char *buffer = (char *) xmalloc (size);
373 if (ExpandEnvironmentStrings (value, buffer, size))
374 {
375 /* Found and expanded. */
376 free (value);
377 return buffer;
378 }
379
380 /* Error expanding. */
381 free (buffer);
382 }
383 }
384
385 /* Not the right type, or not correctly expanded. */
386 free (value);
387 return NULL;
388 }
389
390 int
391 w32_window_app ()
392 {
393 static int window_app = -1;
394 char szTitle[MAX_PATH];
395
396 if (window_app < 0)
397 {
398 /* Checking for STDOUT does not work; it's a valid handle also in
399 nonconsole apps. Testing for the console title seems to work. */
400 window_app = (GetConsoleTitleA (szTitle, MAX_PATH) == 0);
401 if (window_app)
402 InitCommonControls();
403 }
404
405 return window_app;
406 }
407
408 /*
409 execvp wrapper for Windows. Quotes arguments with embedded spaces.
410
411 This is necessary due to the broken implementation of exec* routines in
412 the Microsoft libraries: they concatenate the arguments together without
413 quoting special characters, and pass the result to CreateProcess, with
414 predictably bad results. By contrast, Posix execvp passes the arguments
415 directly into the argv array of the child process.
416 */
417 int
418 w32_execvp (path, argv)
419 char *path;
420 char **argv;
421 {
422 int i;
423
424 /* Required to allow a .BAT script as alternate editor. */
425 argv[0] = (char *) alternate_editor;
426
427 for (i = 0; argv[i]; i++)
428 if (strchr (argv[i], ' '))
429 {
430 char *quoted = alloca (strlen (argv[i]) + 3);
431 sprintf (quoted, "\"%s\"", argv[i]);
432 argv[i] = quoted;
433 }
434
435 return execvp (path, argv);
436 }
437
438 #undef execvp
439 #define execvp w32_execvp
440
441 #endif /* WINDOWSNT */
442
443 /* Display a normal or error message.
444 On Windows, use a message box if compiled as a Windows app. */
445 void
446 message (int is_error, char *message, ...)
447 {
448 char msg [2048];
449 va_list args;
450
451 va_start (args, message);
452 vsprintf (msg, message, args);
453 va_end (args);
454
455 #ifdef WINDOWSNT
456 if (w32_window_app ())
457 {
458 if (is_error)
459 MessageBox (NULL, msg, "Emacsclient ERROR", MB_ICONERROR);
460 else
461 MessageBox (NULL, msg, "Emacsclient", MB_ICONINFORMATION);
462 }
463 else
464 #endif
465 {
466 FILE *f = is_error ? stderr : stdout;
467
468 fputs (msg, f);
469 fflush (f);
470 }
471 }
472
473 /* Decode the options from argv and argc.
474 The global variable `optind' will say how many arguments we used up. */
475
476 void
477 decode_options (argc, argv)
478 int argc;
479 char **argv;
480 {
481 alternate_editor = egetenv ("ALTERNATE_EDITOR");
482
483 /* We used to set `display' to $DISPLAY by default, but this changed the
484 default behavior and is sometimes inconvenient. So instead of forcing
485 users to say "--display ''" when they want to use Emacs's existing tty
486 or display connection, we force them to use "--display $DISPLAY" if
487 they want Emacs to connect to their current display. */
488 #if 0
489 display = egetenv ("DISPLAY");
490 #endif
491
492 while (1)
493 {
494 int opt = getopt_long (argc, argv,
495 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
496 "VHnea:s:f:d:tc",
497 #else
498 "VHnea:f:d:tc",
499 #endif
500 longopts, 0);
501
502 if (opt == EOF)
503 break;
504
505 switch (opt)
506 {
507 case 0:
508 /* If getopt returns 0, then it has already processed a
509 long-named option. We should do nothing. */
510 break;
511
512 case 'a':
513 alternate_editor = optarg;
514 break;
515
516 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
517 case 's':
518 socket_name = optarg;
519 break;
520 #endif
521
522 case 'f':
523 server_file = optarg;
524 break;
525
526 /* We used to disallow this argument in w32, but it seems better
527 to allow it, for the occasional case where the user is
528 connecting with a w32 client to a server compiled with X11
529 support. */
530 #if 1 /* !defined WINDOWS */
531 case 'd':
532 display = optarg;
533 break;
534 #endif
535
536 case 'n':
537 nowait = 1;
538 break;
539
540 case 'e':
541 eval = 1;
542 break;
543
544 case 'V':
545 message (FALSE, "emacsclient %s\n", VERSION);
546 exit (EXIT_SUCCESS);
547 break;
548
549 case 't':
550 tty = 1;
551 current_frame = 0;
552 break;
553
554 case 'c':
555 current_frame = 0;
556 break;
557
558 case 'H':
559 print_help_and_exit ();
560 break;
561
562 default:
563 message (TRUE, "Try `%s --help' for more information\n", progname);
564 exit (EXIT_FAILURE);
565 break;
566 }
567 }
568
569 if (display && strlen (display) == 0)
570 display = NULL;
571
572 if (!tty && display)
573 window_system = 1;
574 #if !defined (WINDOWSNT) && !defined (HAVE_CARBON)
575 else
576 tty = 1;
577 #endif
578
579 /* --no-wait implies --current-frame on ttys when there are file
580 arguments or expressions given. */
581 if (nowait && tty && argc - optind > 0)
582 current_frame = 1;
583
584 if (current_frame)
585 {
586 tty = 0;
587 window_system = 0;
588 }
589
590 if (tty)
591 window_system = 0;
592 }
593
594 \f
595 void
596 print_help_and_exit ()
597 {
598 /* Spaces and tabs are significant in this message; they're chosen so the
599 message aligns properly both in a tty and in a Windows message box.
600 Please try to preserve them; otherwise the output is very hard to read
601 when using emacsclientw. */
602 message (FALSE,
603 "Usage: %s [OPTIONS] FILE...\n\
604 Tell the Emacs server to visit the specified files.\n\
605 Every FILE can be either just a FILENAME or [+LINE[:COLUMN]] FILENAME.\n\
606 \n\
607 The following OPTIONS are accepted:\n\
608 -V, --version Just print version info and return\n\
609 -H, --help Print this usage information message\n\
610 -t, --tty Open a new Emacs frame on the current terminal\n\
611 -c, --create-frame Create a new frame instead of trying to\n\
612 use the current Emacs frame\n\
613 -e, --eval Evaluate the FILE arguments as ELisp expressions\n\
614 -n, --no-wait Don't wait for the server to return\n"
615 #ifndef WINDOWSNT
616 "-d, --display=DISPLAY Visit the file in the given display\n"
617 #endif
618 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
619 "-s, --socket-name=FILENAME\n\
620 Set filename of the UNIX socket for communication\n"
621 #endif
622 "-f, --server-file=FILENAME\n\
623 Set filename of the TCP authentication file\n\
624 -a, --alternate-editor=EDITOR\n\
625 Editor to fallback to if the server is not running\n\
626 \n\
627 Report bugs to bug-gnu-emacs@gnu.org.\n", progname);
628 exit (EXIT_SUCCESS);
629 }
630
631 /*
632 Try to run a different command, or --if no alternate editor is
633 defined-- exit with an errorcode.
634 Uses argv, but gets it from the global variable main_argv.
635 */
636 void
637 fail (void)
638 {
639 if (alternate_editor)
640 {
641 int i = optind - 1;
642
643 execvp (alternate_editor, main_argv + i);
644 message (TRUE, "%s: error executing alternate editor \"%s\"\n",
645 progname, alternate_editor);
646 }
647 exit (EXIT_FAILURE);
648 }
649
650 \f
651 #if !defined (HAVE_SOCKETS) || !defined (HAVE_INET_SOCKETS)
652
653 int
654 main (argc, argv)
655 int argc;
656 char **argv;
657 {
658 main_argv = argv;
659 progname = argv[0];
660 message (TRUE, "%s: Sorry, the Emacs server is supported only\n"
661 "on systems with Berkeley sockets.\n",
662 argv[0]);
663 fail ();
664 }
665
666 #else /* HAVE_SOCKETS && HAVE_INET_SOCKETS */
667
668 #ifdef WINDOWSNT
669 # include <winsock2.h>
670 #else
671 # include <sys/types.h>
672 # include <sys/socket.h>
673 # include <sys/un.h>
674 #endif
675
676 #define AUTH_KEY_LENGTH 64
677 #define SEND_BUFFER_SIZE 4096
678
679 extern char *strerror ();
680 extern int errno;
681
682 /* Buffer to accumulate data to send in TCP connections. */
683 char send_buffer[SEND_BUFFER_SIZE + 1];
684 int sblen = 0; /* Fill pointer for the send buffer. */
685 /* Socket used to communicate with the Emacs server process. */
686 HSOCKET emacs_socket = 0;
687
688 /* On Windows, the socket library was historically separate from the standard
689 C library, so errors are handled differently. */
690 void
691 sock_err_message (function_name)
692 char *function_name;
693 {
694 #ifdef WINDOWSNT
695 char* msg = NULL;
696
697 FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
698 | FORMAT_MESSAGE_ALLOCATE_BUFFER
699 | FORMAT_MESSAGE_ARGUMENT_ARRAY,
700 NULL, WSAGetLastError (), 0, (LPTSTR)&msg, 0, NULL);
701
702 message (TRUE, "%s: %s: %s\n", progname, function_name, msg);
703
704 LocalFree (msg);
705 #else
706 message (TRUE, "%s: %s: %s\n", progname, function_name, strerror (errno));
707 #endif
708 }
709
710
711 /* Let's send the data to Emacs when either
712 - the data ends in "\n", or
713 - the buffer is full (but this shouldn't happen)
714 Otherwise, we just accumulate it. */
715 void
716 send_to_emacs (s, data)
717 HSOCKET s;
718 char *data;
719 {
720 while (data)
721 {
722 int dlen = strlen (data);
723 if (dlen + sblen >= SEND_BUFFER_SIZE)
724 {
725 int part = SEND_BUFFER_SIZE - sblen;
726 strncpy (&send_buffer[sblen], data, part);
727 data += part;
728 sblen = SEND_BUFFER_SIZE;
729 }
730 else if (dlen)
731 {
732 strcpy (&send_buffer[sblen], data);
733 data = NULL;
734 sblen += dlen;
735 }
736 else
737 break;
738
739 if (sblen == SEND_BUFFER_SIZE
740 || (sblen > 0 && send_buffer[sblen-1] == '\n'))
741 {
742 int sent = send (s, send_buffer, sblen, 0);
743 if (sent != sblen)
744 strcpy (send_buffer, &send_buffer[sent]);
745 sblen -= sent;
746 }
747 }
748 }
749
750 \f
751 /* In STR, insert a & before each &, each space, each newline, and
752 any initial -. Change spaces to underscores, too, so that the
753 return value never contains a space.
754
755 Does not change the string. Outputs the result to STREAM. */
756 void
757 quote_argument (s, str)
758 HSOCKET s;
759 char *str;
760 {
761 char *copy = (char *) xmalloc (strlen (str) * 2 + 1);
762 char *p, *q;
763
764 p = str;
765 q = copy;
766 while (*p)
767 {
768 if (*p == ' ')
769 {
770 *q++ = '&';
771 *q++ = '_';
772 p++;
773 }
774 else if (*p == '\n')
775 {
776 *q++ = '&';
777 *q++ = 'n';
778 p++;
779 }
780 else
781 {
782 if (*p == '&' || (*p == '-' && p == str))
783 *q++ = '&';
784 *q++ = *p++;
785 }
786 }
787 *q++ = 0;
788
789 send_to_emacs (s, copy);
790
791 free (copy);
792 }
793
794
795 /* The inverse of quote_argument. Removes quoting in string STR by
796 modifying the string in place. Returns STR. */
797
798 char *
799 unquote_argument (str)
800 char *str;
801 {
802 char *p, *q;
803
804 if (! str)
805 return str;
806
807 p = str;
808 q = str;
809 while (*p)
810 {
811 if (*p == '&')
812 {
813 p++;
814 if (*p == '&')
815 *p = '&';
816 else if (*p == '_')
817 *p = ' ';
818 else if (*p == 'n')
819 *p = '\n';
820 else if (*p == '-')
821 *p = '-';
822 }
823 *q++ = *p++;
824 }
825 *q = 0;
826 return str;
827 }
828
829 \f
830 int
831 file_name_absolute_p (filename)
832 const unsigned char *filename;
833 {
834 /* Sanity check, it shouldn't happen. */
835 if (! filename) return FALSE;
836
837 /* /xxx is always an absolute path. */
838 if (filename[0] == '/') return TRUE;
839
840 /* Empty filenames (which shouldn't happen) are relative. */
841 if (filename[0] == '\0') return FALSE;
842
843 #ifdef WINDOWSNT
844 /* X:\xxx is always absolute. */
845 if (isalpha (filename[0])
846 && filename[1] == ':' && (filename[2] == '\\' || filename[2] == '/'))
847 return TRUE;
848
849 /* Both \xxx and \\xxx\yyy are absolute. */
850 if (filename[0] == '\\') return TRUE;
851
852 /*
853 FIXME: There's a corner case not dealt with, "x:y", where:
854
855 1) x is a valid drive designation (usually a letter in the A-Z range)
856 and y is a path, relative to the current directory on drive x. This
857 is absolute, *after* fixing the y part to include the current
858 directory in x.
859
860 2) x is a relative file name, and y is an NTFS stream name. This is a
861 correct relative path, but it is very unusual.
862
863 The trouble is that first case items are also valid examples of the
864 second case, i.e., "c:test" can be understood as drive:path or as
865 file:stream.
866
867 The "right" fix would involve checking whether
868 - the current drive/partition is NTFS,
869 - x is a valid (and accesible) drive designator,
870 - x:y already exists as a file:stream in the current directory,
871 - y already exists on the current directory of drive x,
872 - the auspices are favorable,
873 and then taking an "informed decision" based on the above.
874
875 Whatever the result, Emacs currently does a very bad job of dealing
876 with NTFS file:streams: it cannot visit them, and the only way to
877 create one is by setting `buffer-file-name' to point to it (either
878 manually or with emacsclient). So perhaps resorting to 1) and ignoring
879 2) for now is the right thing to do.
880
881 Anyway, something to decide After the Release.
882 */
883 #endif
884
885 return FALSE;
886 }
887
888 #ifdef WINDOWSNT
889 /* Wrapper to make WSACleanup a cdecl, as required by atexit. */
890 void
891 __cdecl close_winsock ()
892 {
893 WSACleanup ();
894 }
895
896 /* Initialize the WinSock2 library. */
897 void
898 initialize_sockets ()
899 {
900 WSADATA wsaData;
901
902 if (WSAStartup (MAKEWORD (2, 0), &wsaData))
903 {
904 message (TRUE, "%s: error initializing WinSock2\n", progname);
905 exit (EXIT_FAILURE);
906 }
907
908 atexit (close_winsock);
909 }
910 #endif /* WINDOWSNT */
911
912 \f
913 /*
914 * Read the information needed to set up a TCP comm channel with
915 * the Emacs server: host, port, pid and authentication string.
916 */
917 int
918 get_server_config (server, authentication)
919 struct sockaddr_in *server;
920 char *authentication;
921 {
922 char dotted[32];
923 char *port;
924 char *pid;
925 FILE *config = NULL;
926
927 if (file_name_absolute_p (server_file))
928 config = fopen (server_file, "rb");
929 else
930 {
931 char *home = egetenv ("HOME");
932
933 if (home)
934 {
935 char *path = alloca (32 + strlen (home) + strlen (server_file));
936 sprintf (path, "%s/.emacs.d/server/%s", home, server_file);
937 config = fopen (path, "rb");
938 }
939 #ifdef WINDOWSNT
940 if (!config && (home = egetenv ("APPDATA")))
941 {
942 char *path = alloca (32 + strlen (home) + strlen (server_file));
943 sprintf (path, "%s/.emacs.d/server/%s", home, server_file);
944 config = fopen (path, "rb");
945 }
946 #endif
947 }
948
949 if (! config)
950 return FALSE;
951
952 if (fgets (dotted, sizeof dotted, config)
953 && (port = strchr (dotted, ':'))
954 && (pid = strchr (port, ' ')))
955 {
956 *port++ = '\0';
957 *pid++ = '\0';
958 }
959 else
960 {
961 message (TRUE, "%s: invalid configuration info\n", progname);
962 exit (EXIT_FAILURE);
963 }
964
965 server->sin_family = AF_INET;
966 server->sin_addr.s_addr = inet_addr (dotted);
967 server->sin_port = htons (atoi (port));
968
969 if (! fread (authentication, AUTH_KEY_LENGTH, 1, config))
970 {
971 message (TRUE, "%s: cannot read authentication info\n", progname);
972 exit (EXIT_FAILURE);
973 }
974
975 fclose (config);
976
977 emacs_pid = atoi (pid);
978
979 return TRUE;
980 }
981
982 HSOCKET
983 set_tcp_socket ()
984 {
985 HSOCKET s;
986 struct sockaddr_in server;
987 struct linger l_arg = {1, 1};
988 char auth_string[AUTH_KEY_LENGTH + 1];
989
990 if (! get_server_config (&server, auth_string))
991 return INVALID_SOCKET;
992
993 if (server.sin_addr.s_addr != inet_addr ("127.0.0.1"))
994 message (FALSE, "%s: connected to remote socket at %s\n",
995 progname, inet_ntoa (server.sin_addr));
996
997 /*
998 * Open up an AF_INET socket
999 */
1000 if ((s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
1001 {
1002 sock_err_message ("socket");
1003 return INVALID_SOCKET;
1004 }
1005
1006 /*
1007 * Set up the socket
1008 */
1009 if (connect (s, (struct sockaddr *) &server, sizeof server) < 0)
1010 {
1011 sock_err_message ("connect");
1012 return INVALID_SOCKET;
1013 }
1014
1015 setsockopt (s, SOL_SOCKET, SO_LINGER, (char *) &l_arg, sizeof l_arg);
1016
1017 /*
1018 * Send the authentication
1019 */
1020 auth_string[AUTH_KEY_LENGTH] = '\0';
1021
1022 send_to_emacs (s, "-auth ");
1023 send_to_emacs (s, auth_string);
1024 send_to_emacs (s, " ");
1025
1026 return s;
1027 }
1028
1029
1030 /* Returns 1 if PREFIX is a prefix of STRING. */
1031 static int
1032 strprefix (char *prefix, char *string)
1033 {
1034 return !strncmp (prefix, string, strlen (prefix));
1035 }
1036
1037
1038 #if !defined (NO_SOCKETS_IN_FILE_SYSTEM)
1039
1040 /* Three possibilities:
1041 2 - can't be `stat'ed (sets errno)
1042 1 - isn't owned by us
1043 0 - success: none of the above */
1044
1045 static int
1046 socket_status (socket_name)
1047 char *socket_name;
1048 {
1049 struct stat statbfr;
1050
1051 if (stat (socket_name, &statbfr) == -1)
1052 return 2;
1053
1054 if (statbfr.st_uid != geteuid ())
1055 return 1;
1056
1057 return 0;
1058 }
1059
1060 \f
1061 /* A signal handler that passes the signal to the Emacs process.
1062 Useful for SIGWINCH. */
1063
1064 SIGTYPE
1065 pass_signal_to_emacs (int signalnum)
1066 {
1067 int old_errno = errno;
1068
1069 if (emacs_pid)
1070 kill (emacs_pid, signalnum);
1071
1072 signal (signalnum, pass_signal_to_emacs);
1073 errno = old_errno;
1074 }
1075
1076 /* Signal handler for SIGCONT; notify the Emacs process that it can
1077 now resume our tty frame. */
1078
1079 SIGTYPE
1080 handle_sigcont (int signalnum)
1081 {
1082 int old_errno = errno;
1083
1084 if (tcgetpgrp (1) == getpgrp ())
1085 {
1086 /* We are in the foreground. */
1087 send_to_emacs (emacs_socket, "-resume \n");
1088 }
1089 else
1090 {
1091 /* We are in the background; cancel the continue. */
1092 kill (getpid (), SIGSTOP);
1093 }
1094
1095 signal (signalnum, handle_sigcont);
1096 errno = old_errno;
1097 }
1098
1099 /* Signal handler for SIGTSTP; notify the Emacs process that we are
1100 going to sleep. Normally the suspend is initiated by Emacs via
1101 server-handle-suspend-tty, but if the server gets out of sync with
1102 reality, we may get a SIGTSTP on C-z. Handling this signal and
1103 notifying Emacs about it should get things under control again. */
1104
1105 SIGTYPE
1106 handle_sigtstp (int signalnum)
1107 {
1108 int old_errno = errno;
1109 sigset_t set;
1110
1111 if (emacs_socket)
1112 send_to_emacs (emacs_socket, "-suspend \n");
1113
1114 /* Unblock this signal and call the default handler by temporarily
1115 changing the handler and resignalling. */
1116 sigprocmask (SIG_BLOCK, NULL, &set);
1117 sigdelset (&set, signalnum);
1118 signal (signalnum, SIG_DFL);
1119 kill (getpid (), signalnum);
1120 sigprocmask (SIG_SETMASK, &set, NULL); /* Let's the above signal through. */
1121 signal (signalnum, handle_sigtstp);
1122
1123 errno = old_errno;
1124 }
1125 /* Set up signal handlers before opening a frame on the current tty. */
1126
1127 void
1128 init_signals (void)
1129 {
1130 /* Set up signal handlers. */
1131 signal (SIGWINCH, pass_signal_to_emacs);
1132
1133 /* Don't pass SIGINT and SIGQUIT to Emacs, because it has no way of
1134 deciding which terminal the signal came from. C-g is now a
1135 normal input event on secondary terminals. */
1136 #if 0
1137 signal (SIGINT, pass_signal_to_emacs);
1138 signal (SIGQUIT, pass_signal_to_emacs);
1139 #endif
1140
1141 signal (SIGCONT, handle_sigcont);
1142 signal (SIGTSTP, handle_sigtstp);
1143 signal (SIGTTOU, handle_sigtstp);
1144 }
1145
1146
1147 HSOCKET
1148 set_local_socket ()
1149 {
1150 HSOCKET s;
1151 struct sockaddr_un server;
1152
1153 /*
1154 * Open up an AF_UNIX socket in this person's home directory
1155 */
1156
1157 if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
1158 {
1159 message (TRUE, "%s: socket: %s\n", progname, strerror (errno));
1160 return INVALID_SOCKET;
1161 }
1162
1163 server.sun_family = AF_UNIX;
1164
1165 {
1166 int sock_status = 0;
1167 int default_sock = !socket_name;
1168 int saved_errno = 0;
1169 char *server_name = "server";
1170
1171 if (socket_name && !index (socket_name, '/') && !index (socket_name, '\\'))
1172 { /* socket_name is a file name component. */
1173 server_name = socket_name;
1174 socket_name = NULL;
1175 default_sock = 1; /* Try both UIDs. */
1176 }
1177
1178 if (default_sock)
1179 {
1180 socket_name = alloca (100 + strlen (server_name));
1181 sprintf (socket_name, "/tmp/emacs%d/%s",
1182 (int) geteuid (), server_name);
1183 }
1184
1185 if (strlen (socket_name) < sizeof (server.sun_path))
1186 strcpy (server.sun_path, socket_name);
1187 else
1188 {
1189 message (TRUE, "%s: socket-name %s too long\n",
1190 progname, socket_name);
1191 fail ();
1192 }
1193
1194 /* See if the socket exists, and if it's owned by us. */
1195 sock_status = socket_status (server.sun_path);
1196 saved_errno = errno;
1197 if (sock_status && default_sock)
1198 {
1199 /* Failing that, see if LOGNAME or USER exist and differ from
1200 our euid. If so, look for a socket based on the UID
1201 associated with the name. This is reminiscent of the logic
1202 that init_editfns uses to set the global Vuser_full_name. */
1203
1204 char *user_name = (char *) egetenv ("LOGNAME");
1205
1206 if (!user_name)
1207 user_name = (char *) egetenv ("USER");
1208
1209 if (user_name)
1210 {
1211 struct passwd *pw = getpwnam (user_name);
1212
1213 if (pw && (pw->pw_uid != geteuid ()))
1214 {
1215 /* We're running under su, apparently. */
1216 socket_name = alloca (100 + strlen (server_name));
1217 sprintf (socket_name, "/tmp/emacs%d/%s",
1218 (int) pw->pw_uid, server_name);
1219
1220 if (strlen (socket_name) < sizeof (server.sun_path))
1221 strcpy (server.sun_path, socket_name);
1222 else
1223 {
1224 message (TRUE, "%s: socket-name %s too long\n",
1225 progname, socket_name);
1226 exit (EXIT_FAILURE);
1227 }
1228
1229 sock_status = socket_status (server.sun_path);
1230 saved_errno = errno;
1231 }
1232 else
1233 errno = saved_errno;
1234 }
1235 }
1236
1237 switch (sock_status)
1238 {
1239 case 1:
1240 /* There's a socket, but it isn't owned by us. This is OK if
1241 we are root. */
1242 if (0 != geteuid ())
1243 {
1244 message (TRUE, "%s: Invalid socket owner\n", progname);
1245 return INVALID_SOCKET;
1246 }
1247 break;
1248
1249 case 2:
1250 /* `stat' failed */
1251 if (saved_errno == ENOENT)
1252 message (TRUE,
1253 "%s: can't find socket; have you started the server?\n\
1254 To start the server in Emacs, type \"M-x server-start\".\n",
1255 progname);
1256 else
1257 message (TRUE, "%s: can't stat %s: %s\n",
1258 progname, server.sun_path, strerror (saved_errno));
1259 return INVALID_SOCKET;
1260 }
1261 }
1262
1263 if (connect (s, (struct sockaddr *) &server, strlen (server.sun_path) + 2)
1264 < 0)
1265 {
1266 message (TRUE, "%s: connect: %s\n", progname, strerror (errno));
1267 return INVALID_SOCKET;
1268 }
1269
1270 return s;
1271 }
1272 #endif /* ! NO_SOCKETS_IN_FILE_SYSTEM */
1273
1274 HSOCKET
1275 set_socket ()
1276 {
1277 HSOCKET s;
1278
1279 INITIALIZE ();
1280
1281 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
1282 /* Explicit --socket-name argument. */
1283 if (socket_name)
1284 {
1285 s = set_local_socket ();
1286 if ((s != INVALID_SOCKET) || alternate_editor)
1287 return s;
1288 message (TRUE, "%s: error accessing socket \"%s\"\n",
1289 progname, socket_name);
1290 exit (EXIT_FAILURE);
1291 }
1292 #endif
1293
1294 /* Explicit --server-file arg or EMACS_SERVER_FILE variable. */
1295 if (!server_file)
1296 server_file = egetenv ("EMACS_SERVER_FILE");
1297
1298 if (server_file)
1299 {
1300 s = set_tcp_socket ();
1301 if ((s != INVALID_SOCKET) || alternate_editor)
1302 return s;
1303
1304 message (TRUE, "%s: error accessing server file \"%s\"\n",
1305 progname, server_file);
1306 exit (EXIT_FAILURE);
1307 }
1308
1309 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
1310 /* Implicit local socket. */
1311 s = set_local_socket ();
1312 if (s != INVALID_SOCKET)
1313 return s;
1314 #endif
1315
1316 /* Implicit server file. */
1317 server_file = "server";
1318 s = set_tcp_socket ();
1319 if ((s != INVALID_SOCKET) || alternate_editor)
1320 return s;
1321
1322 /* No implicit or explicit socket, and no alternate editor. */
1323 message (TRUE, "%s: No socket or alternate editor. Please use:\n\n"
1324 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
1325 "\t--socket-name\n"
1326 #endif
1327 "\t--server-file (or environment variable EMACS_SERVER_FILE)\n\
1328 \t--alternate-editor (or environment variable ALTERNATE_EDITOR)\n",
1329 progname);
1330 exit (EXIT_FAILURE);
1331 }
1332
1333 #ifdef WINDOWSNT
1334 FARPROC set_fg; /* Pointer to AllowSetForegroundWindow. */
1335 FARPROC get_wc; /* Pointer to RealGetWindowClassA. */
1336
1337 BOOL CALLBACK
1338 w32_find_emacs_process (hWnd, lParam)
1339 HWND hWnd;
1340 LPARAM lParam;
1341 {
1342 DWORD pid;
1343 char class[6];
1344
1345 /* Reject any window not of class "Emacs". */
1346 if (! get_wc (hWnd, class, sizeof (class))
1347 || strcmp (class, "Emacs"))
1348 return TRUE;
1349
1350 /* We only need the process id, not the thread id. */
1351 (void) GetWindowThreadProcessId (hWnd, &pid);
1352
1353 /* Not the one we're looking for. */
1354 if (pid != (DWORD) emacs_pid) return TRUE;
1355
1356 /* OK, let's raise it. */
1357 set_fg (emacs_pid);
1358
1359 /* Stop enumeration. */
1360 return FALSE;
1361 }
1362
1363 /*
1364 * Search for a window of class "Emacs" and owned by a process with
1365 * process id = emacs_pid. If found, allow it to grab the focus.
1366 */
1367 void
1368 w32_give_focus ()
1369 {
1370 HMODULE hUser32;
1371
1372 /* It shouldn't happen when dealing with TCP sockets. */
1373 if (!emacs_pid) return;
1374
1375 if (!(hUser32 = LoadLibrary ("user32.dll"))) return;
1376
1377 /* Modern Windows restrict which processes can set the foreground window.
1378 emacsclient can allow Emacs to grab the focus by calling the function
1379 AllowSetForegroundWindow. Unfortunately, older Windows (W95, W98 and
1380 NT) lack this function, so we have to check its availability. */
1381 if ((set_fg = GetProcAddress (hUser32, "AllowSetForegroundWindow"))
1382 && (get_wc = GetProcAddress (hUser32, "RealGetWindowClassA")))
1383 EnumWindows (w32_find_emacs_process, (LPARAM) 0);
1384
1385 FreeLibrary (hUser32);
1386 }
1387 #endif
1388
1389 int
1390 main (argc, argv)
1391 int argc;
1392 char **argv;
1393 {
1394 int i, rl, needlf = 0;
1395 char *cwd, *str;
1396 char string[BUFSIZ+1];
1397
1398 main_argv = argv;
1399 progname = argv[0];
1400
1401 /* Process options. */
1402 decode_options (argc, argv);
1403
1404 if ((argc - optind < 1) && !eval && !tty && !window_system)
1405 {
1406 message (TRUE, "%s: file name or argument required\n"
1407 "Try `%s --help' for more information\n",
1408 progname, progname);
1409 exit (EXIT_FAILURE);
1410 }
1411
1412 if ((emacs_socket = set_socket ()) == INVALID_SOCKET)
1413 fail ();
1414
1415
1416 cwd = get_current_dir_name ();
1417 if (cwd == 0)
1418 {
1419 /* getwd puts message in STRING if it fails. */
1420 message (TRUE, "%s: %s\n", progname,
1421 "Cannot get current working directory");
1422 fail ();
1423 }
1424
1425 #ifdef WINDOWSNT
1426 w32_give_focus ();
1427 #endif
1428
1429 /* Send over our environment. */
1430 if (!current_frame)
1431 {
1432 extern char **environ;
1433 int i;
1434 for (i = 0; environ[i]; i++)
1435 {
1436 char *name = xstrdup (environ[i]);
1437 char *value = strchr (name, '=');
1438 send_to_emacs (emacs_socket, "-env ");
1439 quote_argument (emacs_socket, environ[i]);
1440 send_to_emacs (emacs_socket, " ");
1441 }
1442 }
1443
1444 /* Send over our current directory. */
1445 if (!current_frame)
1446 {
1447 send_to_emacs (emacs_socket, "-dir ");
1448 quote_argument (emacs_socket, cwd);
1449 send_to_emacs (emacs_socket, "/");
1450 send_to_emacs (emacs_socket, " ");
1451 }
1452
1453 retry:
1454 if (nowait)
1455 send_to_emacs (emacs_socket, "-nowait ");
1456
1457 if (current_frame)
1458 send_to_emacs (emacs_socket, "-current-frame ");
1459
1460 if (display)
1461 {
1462 send_to_emacs (emacs_socket, "-display ");
1463 quote_argument (emacs_socket, display);
1464 send_to_emacs (emacs_socket, " ");
1465 }
1466
1467 if (tty)
1468 {
1469 char *type = egetenv ("TERM");
1470 char *tty_name = NULL;
1471 #ifndef WINDOWSNT
1472 tty_name = ttyname (fileno (stdin));
1473 #endif
1474
1475 if (! tty_name)
1476 {
1477 message (TRUE, "%s: could not get terminal name\n", progname);
1478 fail ();
1479 }
1480
1481 if (! type)
1482 {
1483 message (TRUE, "%s: please set the TERM variable to your terminal type\n",
1484 progname);
1485 fail ();
1486 }
1487
1488 if (! strcmp (type, "eterm"))
1489 {
1490 /* This causes nasty, MULTI_KBOARD-related input lockouts. */
1491 message (TRUE, "%s: opening a frame in an Emacs term buffer"
1492 " is not supported\n", progname);
1493 fail ();
1494 }
1495 #if !defined (NO_SOCKETS_IN_FILE_SYSTEM)
1496 init_signals ();
1497 #endif
1498
1499 send_to_emacs (emacs_socket, "-tty ");
1500 quote_argument (emacs_socket, tty_name);
1501 send_to_emacs (emacs_socket, " ");
1502 quote_argument (emacs_socket, type);
1503 send_to_emacs (emacs_socket, " ");
1504 }
1505
1506 if (window_system)
1507 send_to_emacs (emacs_socket, "-window-system ");
1508
1509 if ((argc - optind > 0))
1510 {
1511 for (i = optind; i < argc; i++)
1512 {
1513 int relative = 0;
1514
1515 if (eval)
1516 {
1517 /* Don't prepend cwd or anything like that. */
1518 send_to_emacs (emacs_socket, "-eval ");
1519 quote_argument (emacs_socket, argv[i]);
1520 send_to_emacs (emacs_socket, " ");
1521 continue;
1522 }
1523
1524 if (*argv[i] == '+')
1525 {
1526 char *p = argv[i] + 1;
1527 while (isdigit ((unsigned char) *p) || *p == ':') p++;
1528 if (*p == 0)
1529 {
1530 send_to_emacs (emacs_socket, "-position ");
1531 quote_argument (emacs_socket, argv[i]);
1532 send_to_emacs (emacs_socket, " ");
1533 continue;
1534 }
1535 else
1536 relative = 1;
1537 }
1538 else if (! file_name_absolute_p (argv[i]))
1539 relative = 1;
1540
1541 send_to_emacs (emacs_socket, "-file ");
1542 if (relative)
1543 {
1544 quote_argument (emacs_socket, cwd);
1545 send_to_emacs (emacs_socket, "/");
1546 }
1547 quote_argument (emacs_socket, argv[i]);
1548 send_to_emacs (emacs_socket, " ");
1549 }
1550 }
1551 else
1552 {
1553 if (!tty && !window_system)
1554 {
1555 while ((str = fgets (string, BUFSIZ, stdin)))
1556 {
1557 if (eval)
1558 send_to_emacs (emacs_socket, "-eval ");
1559 else
1560 send_to_emacs (emacs_socket, "-file ");
1561 quote_argument (emacs_socket, str);
1562 }
1563 send_to_emacs (emacs_socket, " ");
1564 }
1565 }
1566
1567 send_to_emacs (emacs_socket, "\n");
1568
1569 /* Wait for an answer. */
1570 if (!eval && !tty && !nowait)
1571 {
1572 printf ("Waiting for Emacs...");
1573 needlf = 2;
1574 }
1575 fflush (stdout);
1576 fsync (1);
1577
1578 /* Now, wait for an answer and print any messages. */
1579 while ((rl = recv (emacs_socket, string, BUFSIZ, 0)) > 0)
1580 {
1581 char *p;
1582 string[rl] = '\0';
1583
1584 p = string + strlen (string) - 1;
1585 while (p > string && *p == '\n')
1586 *p-- = 0;
1587
1588 if (strprefix ("-emacs-pid ", string))
1589 {
1590 /* -emacs-pid PID: The process id of the Emacs process. */
1591 emacs_pid = strtol (string + strlen ("-emacs-pid"), NULL, 10);
1592 }
1593 else if (strprefix ("-window-system-unsupported ", string))
1594 {
1595 /* -window-system-unsupported: Emacs was compiled without X
1596 support. Try again on the terminal. */
1597 window_system = 0;
1598 nowait = 0;
1599 tty = 1;
1600 goto retry;
1601 }
1602 else if (strprefix ("-print ", string))
1603 {
1604 /* -print STRING: Print STRING on the terminal. */
1605 str = unquote_argument (string + strlen ("-print "));
1606 if (needlf)
1607 printf ("\n");
1608 printf ("%s", str);
1609 needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n';
1610 }
1611 else if (strprefix ("-error ", string))
1612 {
1613 /* -error DESCRIPTION: Signal an error on the terminal. */
1614 str = unquote_argument (string + strlen ("-error "));
1615 if (needlf)
1616 printf ("\n");
1617 fprintf (stderr, "*ERROR*: %s", str);
1618 needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n';
1619 }
1620 #ifdef SIGSTOP
1621 else if (strprefix ("-suspend ", string))
1622 {
1623 /* -suspend: Suspend this terminal, i.e., stop the process. */
1624 if (needlf)
1625 printf ("\n");
1626 needlf = 0;
1627 kill (0, SIGSTOP);
1628 }
1629 #endif
1630 else
1631 {
1632 /* Unknown command. */
1633 if (needlf)
1634 printf ("\n");
1635 printf ("*ERROR*: Unknown message: %s", string);
1636 needlf = string[0] == '\0' ? needlf : string[strlen (string) - 1] != '\n';
1637 }
1638 }
1639
1640 if (needlf)
1641 printf ("\n");
1642 fflush (stdout);
1643 fsync (1);
1644
1645 CLOSE_SOCKET (emacs_socket);
1646 return EXIT_SUCCESS;
1647 }
1648
1649 #endif /* HAVE_SOCKETS && HAVE_INET_SOCKETS */
1650
1651 \f
1652 #ifndef HAVE_STRERROR
1653 char *
1654 strerror (errnum)
1655 int errnum;
1656 {
1657 extern char *sys_errlist[];
1658 extern int sys_nerr;
1659
1660 if (errnum >= 0 && errnum < sys_nerr)
1661 return sys_errlist[errnum];
1662 return (char *) "Unknown error";
1663 }
1664
1665 #endif /* ! HAVE_STRERROR */
1666
1667 /* arch-tag: f39bb9c4-73eb-477e-896d-50832e2ca9a7
1668 (do not change this comment) */
1669
1670 /* emacsclient.c ends here */