]> code.delx.au - gnu-emacs/blob - lib-src/emacsclient.c
(longopts) [! NO_SOCKETS_IN_FILE_SYSTEM]: Don't show option --socket-name.
[gnu-emacs] / lib-src / emacsclient.c
1 /* Client process that communicates with GNU Emacs acting as server.
2 Copyright (C) 1986, 1987, 1994, 1999, 2000, 2001, 2002, 2003, 2004,
3 2005, 2006 Free Software Foundation, Inc.
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 2, 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 # include <malloc.h>
32 # include <stdlib.h>
33
34 # define HAVE_SOCKETS
35 # define HAVE_INET_SOCKETS
36 # define NO_SOCKETS_IN_FILE_SYSTEM
37
38 # define HSOCKET SOCKET
39 # define CLOSE_SOCKET closesocket
40 # define INITIALIZE() (initialize_sockets ())
41
42 #else /* !WINDOWSNT */
43
44 # ifdef HAVE_INET_SOCKETS
45 # include <netinet/in.h>
46 # endif
47
48 # define INVALID_SOCKET -1
49 # define HSOCKET int
50 # define CLOSE_SOCKET close
51 # define INITIALIZE()
52
53 #endif /* !WINDOWSNT */
54
55 #undef signal
56
57 #include <ctype.h>
58 #include <stdio.h>
59 #include "getopt.h"
60 #ifdef HAVE_UNISTD_H
61 #include <unistd.h>
62 #endif
63
64 #ifdef VMS
65 # include "vms-pwd.h"
66 #else /* not VMS */
67 #ifdef WINDOWSNT
68 # include <io.h>
69 #else /* not WINDOWSNT */
70 # include <pwd.h>
71 #endif /* not WINDOWSNT */
72 #endif /* not VMS */
73
74 char *getenv (), *getwd ();
75 char *(getcwd) ();
76
77 #ifndef VERSION
78 #define VERSION "unspecified"
79 #endif
80 \f
81 #define SEND_STRING(data) (send_to_emacs (s, (data)))
82 #define SEND_QUOTED(data) (quote_file_name (s, (data)))
83
84 #ifndef EXIT_SUCCESS
85 #define EXIT_SUCCESS 0
86 #endif
87
88 #ifndef EXIT_FAILURE
89 #define EXIT_FAILURE 1
90 #endif
91
92 #ifndef FALSE
93 #define FALSE 0
94 #endif
95
96 #ifndef TRUE
97 #define TRUE 1
98 #endif
99
100 #ifndef NO_RETURN
101 #define NO_RETURN
102 #endif
103 \f
104 /* Name used to invoke this program. */
105 char *progname;
106
107 /* Nonzero means don't wait for a response from Emacs. --no-wait. */
108 int nowait = 0;
109
110 /* Nonzero means args are expressions to be evaluated. --eval. */
111 int eval = 0;
112
113 /* The display on which Emacs should work. --display. */
114 char *display = NULL;
115
116 /* If non-NULL, the name of an editor to fallback to if the server
117 is not running. --alternate-editor. */
118 const char *alternate_editor = NULL;
119
120 /* If non-NULL, the filename of the UNIX socket. */
121 char *socket_name = NULL;
122
123 /* If non-NULL, the filename of the authentication file. */
124 char *server_file = NULL;
125
126 void print_help_and_exit () NO_RETURN;
127
128 struct option longopts[] =
129 {
130 { "no-wait", no_argument, NULL, 'n' },
131 { "eval", no_argument, NULL, 'e' },
132 { "help", no_argument, NULL, 'H' },
133 { "version", no_argument, NULL, 'V' },
134 { "alternate-editor", required_argument, NULL, 'a' },
135 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
136 { "socket-name", required_argument, NULL, 's' },
137 #endif
138 { "server-file", required_argument, NULL, 'f' },
139 { "display", required_argument, NULL, 'd' },
140 { 0, 0, 0, 0 }
141 };
142
143 /* Decode the options from argv and argc.
144 The global variable `optind' will say how many arguments we used up. */
145
146 void
147 decode_options (argc, argv)
148 int argc;
149 char **argv;
150 {
151 alternate_editor = getenv ("ALTERNATE_EDITOR");
152
153 while (1)
154 {
155 int opt = getopt_long (argc, argv,
156 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
157 "VHnea:s:f:d:",
158 #else
159 "VHnea:f:d:",
160 #endif
161 longopts, 0);
162
163 if (opt == EOF)
164 break;
165
166 switch (opt)
167 {
168 case 0:
169 /* If getopt returns 0, then it has already processed a
170 long-named option. We should do nothing. */
171 break;
172
173 case 'a':
174 alternate_editor = optarg;
175 break;
176
177 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
178 case 's':
179 socket_name = optarg;
180 break;
181 #endif
182
183 case 'f':
184 server_file = optarg;
185 break;
186
187 case 'd':
188 display = optarg;
189 break;
190
191 case 'n':
192 nowait = 1;
193 break;
194
195 case 'e':
196 eval = 1;
197 break;
198
199 case 'V':
200 printf ("emacsclient %s\n", VERSION);
201 exit (EXIT_SUCCESS);
202 break;
203
204 case 'H':
205 print_help_and_exit ();
206 break;
207
208 default:
209 fprintf (stderr, "Try `%s --help' for more information\n", progname);
210 exit (EXIT_FAILURE);
211 break;
212 }
213 }
214 }
215
216 void
217 print_help_and_exit ()
218 {
219 printf (
220 "Usage: %s [OPTIONS] FILE...\n\
221 Tell the Emacs server to visit the specified files.\n\
222 Every FILE can be either just a FILENAME or [+LINE[:COLUMN]] FILENAME.\n\
223 \n\
224 The following OPTIONS are accepted:\n\
225 -V, --version Just print a version info and return\n\
226 -H, --help Print this usage information message\n\
227 -n, --no-wait Don't wait for the server to return\n\
228 -e, --eval Evaluate the FILE arguments as ELisp expressions\n\
229 -d, --display=DISPLAY Visit the file in the given display\n"
230 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
231 "-s, --socket-name=FILENAME\n\
232 Set the filename of the UNIX socket for communication\n"
233 #endif
234 "-f, --server-file=FILENAME\n\
235 Set the filename of the TCP configuration file\n\
236 -a, --alternate-editor=EDITOR\n\
237 Editor to fallback to if the server is not running\n\
238 \n\
239 Report bugs to bug-gnu-emacs@gnu.org.\n", progname);
240 exit (EXIT_SUCCESS);
241 }
242
243 \f
244 /*
245 Try to run a different command, or --if no alternate editor is
246 defined-- exit with an errorcode.
247 */
248 void
249 fail (argc, argv)
250 int argc;
251 char **argv;
252 {
253 if (alternate_editor)
254 {
255 int i = optind - 1;
256 #ifdef WINDOWSNT
257 argv[i] = (char *)alternate_editor;
258 #endif
259 execvp (alternate_editor, argv + i);
260 fprintf (stderr, "%s: error executing alternate editor \"%s\"\n",
261 progname, alternate_editor);
262 }
263 exit (EXIT_FAILURE);
264 }
265
266 \f
267 #if !defined (HAVE_SOCKETS) || !defined (HAVE_INET_SOCKETS)
268
269 int
270 main (argc, argv)
271 int argc;
272 char **argv;
273 {
274 fprintf (stderr, "%s: Sorry, the Emacs server is supported only\n",
275 argv[0]);
276 fprintf (stderr, "on systems with Berkeley sockets.\n");
277
278 fail (argc, argv);
279 }
280
281 #else /* HAVE_SOCKETS && HAVE_INET_SOCKETS */
282
283 #ifdef WINDOWSNT
284 # include <winsock2.h>
285 #else
286 # include <sys/types.h>
287 # include <sys/socket.h>
288 # include <sys/un.h>
289 # include <sys/stat.h>
290 # include <errno.h>
291 #endif
292
293 #define AUTH_KEY_LENGTH 64
294 #define SEND_BUFFER_SIZE 4096
295
296 extern char *strerror ();
297 extern int errno;
298
299 /* Buffer to accumulate data to send in TCP connections. */
300 char send_buffer[SEND_BUFFER_SIZE + 1];
301 int sblen = 0; /* Fill pointer for the send buffer. */
302
303 /* Let's send the data to Emacs when either
304 - the data ends in "\n", or
305 - the buffer is full (but this shouldn't happen)
306 Otherwise, we just accumulate it. */
307 void
308 send_to_emacs (s, data)
309 HSOCKET s;
310 char *data;
311 {
312 while (data)
313 {
314 int dlen = strlen (data);
315 if (dlen + sblen >= SEND_BUFFER_SIZE)
316 {
317 int part = SEND_BUFFER_SIZE - sblen;
318 strncpy (&send_buffer[sblen], data, part);
319 data += part;
320 sblen = SEND_BUFFER_SIZE;
321 }
322 else if (dlen)
323 {
324 strcpy (&send_buffer[sblen], data);
325 data = NULL;
326 sblen += dlen;
327 }
328 else
329 break;
330
331 if (sblen == SEND_BUFFER_SIZE
332 || (sblen > 0 && send_buffer[sblen-1] == '\n'))
333 {
334 int sent = send (s, send_buffer, sblen, 0);
335 if (sent != sblen)
336 strcpy (send_buffer, &send_buffer[sent]);
337 sblen -= sent;
338 }
339 }
340 }
341
342 /* In NAME, insert a & before each &, each space, each newline, and
343 any initial -. Change spaces to underscores, too, so that the
344 return value never contains a space. */
345 void
346 quote_file_name (s, name)
347 HSOCKET s;
348 char *name;
349 {
350 char *copy = (char *) malloc (strlen (name) * 2 + 1);
351 char *p, *q;
352
353 p = name;
354 q = copy;
355 while (*p)
356 {
357 if (*p == ' ')
358 {
359 *q++ = '&';
360 *q++ = '_';
361 p++;
362 }
363 else if (*p == '\n')
364 {
365 *q++ = '&';
366 *q++ = 'n';
367 p++;
368 }
369 else
370 {
371 if (*p == '&' || (*p == '-' && p == name))
372 *q++ = '&';
373 *q++ = *p++;
374 }
375 }
376 *q++ = 0;
377
378 SEND_STRING (copy);
379
380 free (copy);
381 }
382
383 int
384 file_name_absolute_p (filename)
385 const unsigned char *filename;
386 {
387 /* Sanity check, it shouldn't happen. */
388 if (! filename) return FALSE;
389
390 /* /xxx is always an absolute path. */
391 if (filename[0] == '/') return TRUE;
392
393 /* Empty filenames (which shouldn't happen) are relative. */
394 if (filename[0] == '\0') return FALSE;
395
396 #ifdef WINDOWSNT
397 /* X:\xxx is always absolute; X:xxx is an error and will fail. */
398 if (islower (tolower (filename[0]))
399 && filename[1] == ':' && filename[2] == '\\')
400 return TRUE;
401
402 /* Both \xxx and \\xxx\yyy are absolute. */
403 if (filename[0] == '\\') return TRUE;
404 #endif
405
406 return FALSE;
407 }
408
409 #ifdef WINDOWSNT
410 /* Wrapper to make WSACleanup a cdecl, as required by atexit(). */
411 void
412 __cdecl close_winsock ()
413 {
414 WSACleanup ();
415 }
416
417 /* Initialize the WinSock2 library. */
418 void
419 initialize_sockets ()
420 {
421 WSADATA wsaData;
422
423 if (WSAStartup (MAKEWORD (2, 0), &wsaData))
424 {
425 fprintf (stderr, "%s: error initializing WinSock2", progname);
426 exit (EXIT_FAILURE);
427 }
428
429 atexit (close_winsock);
430 }
431 #endif /* WINDOWSNT */
432 \f
433 /*
434 * Read the information needed to set up a TCP comm channel with
435 * the Emacs server: host, port and authentication string.
436 */
437 int
438 get_server_config (server, authentication)
439 struct sockaddr_in *server;
440 char *authentication;
441 {
442 char dotted[32];
443 char *port;
444 FILE *config = NULL;
445
446 if (file_name_absolute_p (server_file))
447 config = fopen (server_file, "rb");
448 else
449 {
450 char *home = getenv ("HOME");
451 #ifdef WINDOWSNT
452 if (! home)
453 home = getenv ("APPDATA");
454 #endif
455 if (home)
456 {
457 char *path = alloca (32 + strlen (home) + strlen (server_file));
458 sprintf (path, "%s/.emacs.d/server/%s", home, server_file);
459 config = fopen (path, "rb");
460 }
461 }
462
463 if (! config)
464 return FALSE;
465
466 if (fgets (dotted, sizeof dotted, config)
467 && (port = strchr (dotted, ':')))
468 {
469 *port++ = '\0';
470 }
471 else
472 {
473 fprintf (stderr, "%s: invalid configuration info", progname);
474 exit (EXIT_FAILURE);
475 }
476
477 server->sin_family = AF_INET;
478 server->sin_addr.s_addr = inet_addr (dotted);
479 server->sin_port = htons (atoi (port));
480
481 if (! fread (authentication, AUTH_KEY_LENGTH, 1, config))
482 {
483 fprintf (stderr, "%s: cannot read authentication info", progname);
484 exit (EXIT_FAILURE);
485 }
486
487 fclose (config);
488
489 return TRUE;
490 }
491
492 HSOCKET
493 set_tcp_socket ()
494 {
495 HSOCKET s;
496 struct sockaddr_in server;
497 struct linger l_arg = {1, 1};
498 char auth_string[AUTH_KEY_LENGTH + 1];
499
500 if (! get_server_config (&server, auth_string))
501 return INVALID_SOCKET;
502
503 if (server.sin_addr.s_addr != inet_addr ("127.0.0.1"))
504 fprintf (stderr, "%s: connected to remote socket at %s\n",
505 progname, inet_ntoa (server.sin_addr));
506
507 /*
508 * Open up an AF_INET socket
509 */
510 if ((s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
511 {
512 fprintf (stderr, "%s: ", progname);
513 perror ("socket");
514 return INVALID_SOCKET;
515 }
516
517 /*
518 * Set up the socket
519 */
520 if (connect (s, (struct sockaddr *) &server, sizeof server) < 0)
521 {
522 fprintf (stderr, "%s: ", progname);
523 perror ("connect");
524 return INVALID_SOCKET;
525 }
526
527 setsockopt (s, SOL_SOCKET, SO_LINGER, (char *) &l_arg, sizeof l_arg);
528
529 /*
530 * Send the authentication
531 */
532 auth_string[AUTH_KEY_LENGTH] = '\0';
533
534 SEND_STRING ("-auth ");
535 SEND_STRING (auth_string);
536 SEND_STRING ("\n");
537
538 return s;
539 }
540
541 #if !defined (NO_SOCKETS_IN_FILE_SYSTEM)
542
543 /* Three possibilities:
544 2 - can't be `stat'ed (sets errno)
545 1 - isn't owned by us
546 0 - success: none of the above */
547
548 static int
549 socket_status (socket_name)
550 char *socket_name;
551 {
552 struct stat statbfr;
553
554 if (stat (socket_name, &statbfr) == -1)
555 return 2;
556
557 if (statbfr.st_uid != geteuid ())
558 return 1;
559
560 return 0;
561 }
562
563 HSOCKET
564 set_local_socket ()
565 {
566 HSOCKET s;
567 struct sockaddr_un server;
568
569 /*
570 * Open up an AF_UNIX socket in this person's home directory
571 */
572
573 if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
574 {
575 fprintf (stderr, "%s: ", progname);
576 perror ("socket");
577 return INVALID_SOCKET;
578 }
579
580 server.sun_family = AF_UNIX;
581
582 {
583 int sock_status = 0;
584 int default_sock = !socket_name;
585 int saved_errno;
586 char *server_name = "server";
587
588 if (socket_name && !index (socket_name, '/') && !index (socket_name, '\\'))
589 { /* socket_name is a file name component. */
590 server_name = socket_name;
591 socket_name = NULL;
592 default_sock = 1; /* Try both UIDs. */
593 }
594
595 if (default_sock)
596 {
597 socket_name = alloca (100 + strlen (server_name));
598 sprintf (socket_name, "/tmp/emacs%d/%s",
599 (int) geteuid (), server_name);
600 }
601
602 if (strlen (socket_name) < sizeof (server.sun_path))
603 strcpy (server.sun_path, socket_name);
604 else
605 {
606 fprintf (stderr, "%s: socket-name %s too long",
607 progname, socket_name);
608 exit (EXIT_FAILURE);
609 }
610
611 /* See if the socket exists, and if it's owned by us. */
612 sock_status = socket_status (server.sun_path);
613 saved_errno = errno;
614 if (sock_status && default_sock)
615 {
616 /* Failing that, see if LOGNAME or USER exist and differ from
617 our euid. If so, look for a socket based on the UID
618 associated with the name. This is reminiscent of the logic
619 that init_editfns uses to set the global Vuser_full_name. */
620
621 char *user_name = (char *) getenv ("LOGNAME");
622
623 if (!user_name)
624 user_name = (char *) getenv ("USER");
625
626 if (user_name)
627 {
628 struct passwd *pw = getpwnam (user_name);
629
630 if (pw && (pw->pw_uid != geteuid ()))
631 {
632 /* We're running under su, apparently. */
633 socket_name = alloca (100 + strlen (server_name));
634 sprintf (socket_name, "/tmp/emacs%d/%s",
635 (int) pw->pw_uid, server_name);
636
637 if (strlen (socket_name) < sizeof (server.sun_path))
638 strcpy (server.sun_path, socket_name);
639 else
640 {
641 fprintf (stderr, "%s: socket-name %s too long",
642 progname, socket_name);
643 exit (EXIT_FAILURE);
644 }
645
646 sock_status = socket_status (server.sun_path);
647 saved_errno = errno;
648 }
649 else
650 errno = saved_errno;
651 }
652 }
653
654 switch (sock_status)
655 {
656 case 1:
657 /* There's a socket, but it isn't owned by us. This is OK if
658 we are root. */
659 if (0 != geteuid ())
660 {
661 fprintf (stderr, "%s: Invalid socket owner\n", progname);
662 return INVALID_SOCKET;
663 }
664 break;
665
666 case 2:
667 /* `stat' failed */
668 if (saved_errno == ENOENT)
669 fprintf (stderr,
670 "%s: can't find socket; have you started the server?\n\
671 To start the server in Emacs, type \"M-x server-start\".\n",
672 progname);
673 else
674 fprintf (stderr, "%s: can't stat %s: %s\n",
675 progname, server.sun_path, strerror (saved_errno));
676 return INVALID_SOCKET;
677 }
678 }
679
680 if (connect (s, (struct sockaddr *) &server, strlen (server.sun_path) + 2)
681 < 0)
682 {
683 fprintf (stderr, "%s: ", progname);
684 perror ("connect");
685 return INVALID_SOCKET;
686 }
687
688 return s;
689 }
690 #endif /* ! NO_SOCKETS_IN_FILE_SYSTEM */
691
692 HSOCKET
693 set_socket ()
694 {
695 HSOCKET s;
696
697 INITIALIZE ();
698
699 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
700 /* Explicit --socket-name argument. */
701 if (socket_name)
702 {
703 s = set_local_socket ();
704 if ((s != INVALID_SOCKET) || alternate_editor)
705 return s;
706
707 fprintf (stderr, "%s: error accessing socket \"%s\"",
708 progname, socket_name);
709 exit (EXIT_FAILURE);
710 }
711 #endif
712
713 /* Explicit --server-file arg or EMACS_SERVER_FILE variable. */
714 if (!server_file)
715 server_file = getenv ("EMACS_SERVER_FILE");
716
717 if (server_file)
718 {
719 s = set_tcp_socket ();
720 if ((s != INVALID_SOCKET) || alternate_editor)
721 return s;
722
723 fprintf (stderr, "%s: error accessing server file \"%s\"",
724 progname, server_file);
725 exit (EXIT_FAILURE);
726 }
727
728 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
729 /* Implicit local socket. */
730 s = set_local_socket ();
731 if (s != INVALID_SOCKET)
732 return s;
733 #endif
734
735 /* Implicit server file. */
736 server_file = "server";
737 s = set_tcp_socket ();
738 if ((s != INVALID_SOCKET) || alternate_editor)
739 return s;
740
741 /* No implicit or explicit socket, and no alternate editor. */
742 fprintf (stderr, "%s: No socket or alternate editor. Please use:\n\n"
743 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
744 "\t--socket-name\n"
745 #endif
746 "\t--server-file (or environment variable EMACS_SERVER_FILE)\n\
747 \t--alternate-editor (or environment variable ALTERNATE_EDITOR)\n",
748 progname);
749 exit (EXIT_FAILURE);
750 }
751
752 int
753 main (argc, argv)
754 int argc;
755 char **argv;
756 {
757 HSOCKET s;
758 int i, rl, needlf = 0;
759 char *cwd;
760 char string[BUFSIZ+1];
761
762 progname = argv[0];
763
764 /* Process options. */
765 decode_options (argc, argv);
766
767 if ((argc - optind < 1) && !eval)
768 {
769 fprintf (stderr, "%s: file name or argument required\n", progname);
770 fprintf (stderr, "Try `%s --help' for more information\n", progname);
771 exit (EXIT_FAILURE);
772 }
773
774 if ((s = set_socket ()) == INVALID_SOCKET)
775 fail (argc, argv);
776
777 #ifdef HAVE_GETCWD
778 cwd = getcwd (string, sizeof string);
779 #else
780 cwd = getwd (string);
781 #endif
782 if (cwd == 0)
783 {
784 /* getwd puts message in STRING if it fails. */
785 #ifdef HAVE_GETCWD
786 fprintf (stderr, "%s: %s (%s)\n", progname,
787 "Cannot get current working directory", strerror (errno));
788 #else
789 fprintf (stderr, "%s: %s (%s)\n", progname, string, strerror (errno));
790 #endif
791 fail (argc, argv);
792 }
793
794 if (nowait)
795 SEND_STRING ("-nowait ");
796
797 if (eval)
798 SEND_STRING ("-eval ");
799
800 if (display)
801 {
802 SEND_STRING ("-display ");
803 SEND_QUOTED (display);
804 SEND_STRING (" ");
805 }
806
807 if ((argc - optind > 0))
808 {
809 for (i = optind; i < argc; i++)
810 {
811 if (eval)
812 ; /* Don't prepend any cwd or anything like that. */
813 else if (*argv[i] == '+')
814 {
815 char *p = argv[i] + 1;
816 while (isdigit ((unsigned char) *p) || *p == ':') p++;
817 if (*p != 0)
818 {
819 SEND_QUOTED (cwd);
820 SEND_STRING ("/");
821 }
822 }
823 else if (! file_name_absolute_p (argv[i]))
824 {
825 SEND_QUOTED (cwd);
826 SEND_STRING ("/");
827 }
828
829 SEND_QUOTED (argv[i]);
830 SEND_STRING (" ");
831 }
832 }
833 else
834 {
835 while (fgets (string, BUFSIZ, stdin))
836 {
837 SEND_QUOTED (string);
838 }
839 SEND_STRING (" ");
840 }
841
842 SEND_STRING ("\n");
843
844 /* Maybe wait for an answer. */
845 if (!nowait)
846 {
847 if (!eval)
848 {
849 printf ("Waiting for Emacs...");
850 needlf = 2;
851 }
852 fflush (stdout);
853
854 /* Now, wait for an answer and print any messages. */
855 while ((rl = recv (s, string, BUFSIZ, 0)) > 0)
856 {
857 string[rl] = '\0';
858 if (needlf == 2)
859 printf ("\n");
860 printf ("%s", string);
861 needlf = string[0] == '\0' ? needlf : string[strlen (string) - 1] != '\n';
862 }
863
864 if (needlf)
865 printf ("\n");
866 fflush (stdout);
867 }
868
869 CLOSE_SOCKET (s);
870 return EXIT_SUCCESS;
871 }
872
873 #endif /* HAVE_SOCKETS && HAVE_INET_SOCKETS */
874
875 #ifndef HAVE_STRERROR
876 char *
877 strerror (errnum)
878 int errnum;
879 {
880 extern char *sys_errlist[];
881 extern int sys_nerr;
882
883 if (errnum >= 0 && errnum < sys_nerr)
884 return sys_errlist[errnum];
885 return (char *) "Unknown error";
886 }
887
888 #endif /* ! HAVE_STRERROR */
889
890 /* arch-tag: f39bb9c4-73eb-477e-896d-50832e2ca9a7
891 (do not change this comment) */
892
893 /* emacsclient.c ends here */