comparison lib-src/emacsclient.c @ 83548:c71725faff1a

Merged from emacs@sv.gnu.org. Last-minute emacsclient rewrites be damned! Patches applied: * emacs@sv.gnu.org/emacs--devo--0--patch-490 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-491 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-492 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-493 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-494 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-495 Merge from gnus--rel--5.10 * emacs@sv.gnu.org/emacs--devo--0--patch-496 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-497 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-498 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-499 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-500 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-501 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-502 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-503 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-504 Merge from gnus--rel--5.10 * emacs@sv.gnu.org/emacs--devo--0--patch-505 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-506 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-507 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-508 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-509 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-510 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-511 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-512 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-513 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-514 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-515 Merge from gnus--rel--5.10 * emacs@sv.gnu.org/emacs--devo--0--patch-516 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-517 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-518 Merge from gnus--rel--5.10 * emacs@sv.gnu.org/emacs--devo--0--patch-519 Update from CVS: etc/TUTORIAL.cn: Updated. * emacs@sv.gnu.org/emacs--devo--0--patch-520 Merge from erc--emacs--22 * emacs@sv.gnu.org/emacs--devo--0--patch-521 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-522 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-523 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-524 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-525 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-526 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-527 Merge from gnus--rel--5.10 * emacs@sv.gnu.org/emacs--devo--0--patch-528 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-529 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-530 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-531 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-532 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-533 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-534 Merge from gnus--rel--5.10 * emacs@sv.gnu.org/emacs--devo--0--patch-535 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-161 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-162 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-163 Merge from emacs--devo--0 * emacs@sv.gnu.org/gnus--rel--5.10--patch-164 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-165 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-166 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-167 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-168 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-169 Merge from emacs--devo--0 * emacs@sv.gnu.org/gnus--rel--5.10--patch-170 Update from CVS git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-588
author Karoly Lorentey <lorentey@elte.hu>
date Sun, 03 Dec 2006 15:03:30 +0000
parents 02e39decdc84 c6cb776ffbb7
children 17e0dd217877
comparison
equal deleted inserted replaced
83547:0912b745fc75 83548:c71725faff1a
24 24
25 #ifdef HAVE_CONFIG_H 25 #ifdef HAVE_CONFIG_H
26 #include <config.h> 26 #include <config.h>
27 #endif 27 #endif
28 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
39 # define NO_SOCKETS_IN_FILE_SYSTEM
40
41 # define HSOCKET SOCKET
42 # define CLOSE_SOCKET closesocket
43 # define INITIALIZE() (initialize_sockets ())
44
45 #else /* !WINDOWSNT */
46
47 # include <sys/types.h>
48
49 # ifdef HAVE_INET_SOCKETS
50 # include <netinet/in.h>
51 # endif
52
53 # define INVALID_SOCKET -1
54 # define HSOCKET int
55 # define CLOSE_SOCKET close
56 # define INITIALIZE()
57
58 #endif /* !WINDOWSNT */
59
29 #undef signal 60 #undef signal
30 61
62 #include <stdarg.h>
31 #include <ctype.h> 63 #include <ctype.h>
32 #include <stdio.h> 64 #include <stdio.h>
33 #include <getopt.h> 65 #include "getopt.h"
34 #ifdef HAVE_UNISTD_H 66 #ifdef HAVE_UNISTD_H
35 #include <unistd.h> 67 #include <unistd.h>
36 #endif 68 #endif
37 69
38 #ifdef VMS 70 #ifdef VMS
39 # include "vms-pwd.h" 71 # include "vms-pwd.h"
40 #else 72 #else /* not VMS */
73 #ifdef WINDOWSNT
74 # include <io.h>
75 #else /* not WINDOWSNT */
41 # include <pwd.h> 76 # include <pwd.h>
77 #endif /* not WINDOWSNT */
42 #endif /* not VMS */ 78 #endif /* not VMS */
43 #include <sys/stat.h> 79 #include <sys/stat.h>
44 80
45 #include <signal.h> 81 #include <signal.h>
46 #include <errno.h> 82 #include <errno.h>
70 106
71 #ifndef VERSION 107 #ifndef VERSION
72 #define VERSION "unspecified" 108 #define VERSION "unspecified"
73 #endif 109 #endif
74 110
111 #define SEND_STRING(data) (send_to_emacs (s, (data)))
112 #define SEND_QUOTED(data) (quote_argument (s, (data)))
113
114 #ifndef EXIT_SUCCESS
115 #define EXIT_SUCCESS 0
116 #endif
117
118 #ifndef EXIT_FAILURE
119 #define EXIT_FAILURE 1
120 #endif
121
122 #ifndef FALSE
123 #define FALSE 0
124 #endif
125
126 #ifndef TRUE
127 #define TRUE 1
128 #endif
129
130 #ifndef NO_RETURN
131 #define NO_RETURN
132 #endif
133
75 /* Name used to invoke this program. */ 134 /* Name used to invoke this program. */
76 char *progname; 135 char *progname;
77 136
78 /* The first argument to main. */ 137 /* The first argument to main. */
79 int main_argc; 138 int main_argc;
99 /* Nonzero means open a new Emacs frame on the current terminal. */ 158 /* Nonzero means open a new Emacs frame on the current terminal. */
100 int tty = 0; 159 int tty = 0;
101 160
102 /* If non-NULL, the name of an editor to fallback to if the server 161 /* If non-NULL, the name of an editor to fallback to if the server
103 is not running. --alternate-editor. */ 162 is not running. --alternate-editor. */
104 const char * alternate_editor = NULL; 163 const char *alternate_editor = NULL;
105 164
106 /* If non-NULL, the filename of the UNIX socket. */ 165 /* If non-NULL, the filename of the UNIX socket. */
107 char *socket_name = NULL; 166 char *socket_name = NULL;
167
168 /* If non-NULL, the filename of the authentication file. */
169 char *server_file = NULL;
170
171 /* PID of the Emacs server process. */
172 int emacs_pid = 0;
173
174 /* File handles for communicating with Emacs. */
175 FILE *out, *in;
108 176
109 void print_help_and_exit () NO_RETURN; 177 void print_help_and_exit () NO_RETURN;
110 178
111 struct option longopts[] = 179 struct option longopts[] =
112 { 180 {
115 { "help", no_argument, NULL, 'H' }, 183 { "help", no_argument, NULL, 'H' },
116 { "version", no_argument, NULL, 'V' }, 184 { "version", no_argument, NULL, 'V' },
117 { "tty", no_argument, NULL, 't' }, 185 { "tty", no_argument, NULL, 't' },
118 { "current-frame", no_argument, NULL, 'c' }, 186 { "current-frame", no_argument, NULL, 'c' },
119 { "alternate-editor", required_argument, NULL, 'a' }, 187 { "alternate-editor", required_argument, NULL, 'a' },
188 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
120 { "socket-name", required_argument, NULL, 's' }, 189 { "socket-name", required_argument, NULL, 's' },
190 #endif
191 { "server-file", required_argument, NULL, 'f' },
121 { "display", required_argument, NULL, 'd' }, 192 { "display", required_argument, NULL, 'd' },
122 { 0, 0, 0, 0 } 193 { 0, 0, 0, 0 }
123 }; 194 };
124 195
125 /* Decode the options from argv and argc. 196
126 The global variable `optind' will say how many arguments we used up. */
127
128 void
129 decode_options (argc, argv)
130 int argc;
131 char **argv;
132 {
133 alternate_editor = getenv ("ALTERNATE_EDITOR");
134 display = getenv ("DISPLAY");
135 if (display && strlen (display) == 0)
136 display = NULL;
137
138 while (1)
139 {
140 int opt = getopt_long (argc, argv,
141 "VHnea:s:d:tc", longopts, 0);
142
143 if (opt == EOF)
144 break;
145
146 switch (opt)
147 {
148 case 0:
149 /* If getopt returns 0, then it has already processed a
150 long-named option. We should do nothing. */
151 break;
152
153 case 'a':
154 alternate_editor = optarg;
155 break;
156
157 case 's':
158 socket_name = optarg;
159 break;
160
161 case 'd':
162 display = optarg;
163 break;
164
165 case 'n':
166 nowait = 1;
167 break;
168
169 case 'e':
170 eval = 1;
171 break;
172
173 case 'V':
174 printf ("emacsclient %s\n", VERSION);
175 exit (EXIT_SUCCESS);
176 break;
177
178 case 't':
179 tty = 1;
180 break;
181
182 case 'c':
183 current_frame = 1;
184 break;
185
186 case 'H':
187 print_help_and_exit ();
188 break;
189
190 default:
191 fprintf (stderr, "Try `%s --help' for more information\n", progname);
192 exit (EXIT_FAILURE);
193 break;
194 }
195 }
196
197 if (!tty && display)
198 window_system = 1;
199 else
200 tty = 1;
201
202 /* --no-wait implies --current-frame on ttys when there are file
203 arguments or expressions given. */
204 if (nowait && tty && argc - optind > 0)
205 current_frame = 1;
206
207 if (current_frame)
208 {
209 tty = 0;
210 window_system = 0;
211 }
212
213 if (tty)
214 window_system = 0;
215 }
216
217 void
218 print_help_and_exit ()
219 {
220 printf (
221 "Usage: %s [OPTIONS] FILE...\n\
222 Tell the Emacs server to visit the specified files.\n\
223 Every FILE can be either just a FILENAME or [+LINE[:COLUMN]] FILENAME.\n\
224 \n\
225 The following OPTIONS are accepted:\n\
226 -V, --version Just print a version info and return\n\
227 -H, --help Print this usage information message\n\
228 -t, --tty Open a new Emacs frame on the current terminal\n\
229 -c, --current-frame Do not create a new frame; use the current Emacs frame\n\
230 -n, --no-wait Don't wait for the server to return\n\
231 -e, --eval Evaluate the FILE arguments as ELisp expressions\n\
232 -d, --display=DISPLAY Visit the file in the given display\n\
233 -s, --socket-name=FILENAME\n\
234 Set the filename of the UNIX socket for communication\n\
235 -a, --alternate-editor=EDITOR\n\
236 Editor to fallback to if the server is not running\n\
237 \n\
238 Report bugs to bug-gnu-emacs@gnu.org.\n", progname);
239 exit (EXIT_SUCCESS);
240 }
241
242 /* Like malloc but get fatal error if memory is exhausted. */ 197 /* Like malloc but get fatal error if memory is exhausted. */
243 198
244 long * 199 long *
245 xmalloc (size) 200 xmalloc (size)
246 unsigned int size; 201 unsigned int size;
292 #ifdef MAXPATHLEN 247 #ifdef MAXPATHLEN
293 && strlen (pwd) < MAXPATHLEN 248 && strlen (pwd) < MAXPATHLEN
294 #endif 249 #endif
295 ) 250 )
296 { 251 {
297 buf = (char *) malloc (strlen (pwd) + 1); 252 buf = (char *) xmalloc (strlen (pwd) + 1);
298 if (!buf) 253 if (!buf)
299 return NULL; 254 return NULL;
300 strcpy (buf, pwd); 255 strcpy (buf, pwd);
301 } 256 }
302 #ifdef HAVE_GETCWD 257 #ifdef HAVE_GETCWD
303 else 258 else
304 { 259 {
305 size_t buf_size = 1024; 260 size_t buf_size = 1024;
306 buf = (char *) malloc (buf_size); 261 buf = (char *) xmalloc (buf_size);
307 if (!buf) 262 if (!buf)
308 return NULL; 263 return NULL;
309 for (;;) 264 for (;;)
310 { 265 {
311 if (getcwd (buf, buf_size) == buf) 266 if (getcwd (buf, buf_size) == buf)
325 } 280 }
326 #else 281 #else
327 else 282 else
328 { 283 {
329 /* We need MAXPATHLEN here. */ 284 /* We need MAXPATHLEN here. */
330 buf = (char *) malloc (MAXPATHLEN + 1); 285 buf = (char *) xmalloc (MAXPATHLEN + 1);
331 if (!buf) 286 if (!buf)
332 return NULL; 287 return NULL;
333 if (getwd (buf) == NULL) 288 if (getwd (buf) == NULL)
334 { 289 {
335 int tmp_errno = errno; 290 int tmp_errno = errno;
341 #endif 296 #endif
342 return buf; 297 return buf;
343 } 298 }
344 #endif 299 #endif
345 300
301 /* Message functions. */
302
303 #ifdef WINDOWSNT
304 /* I first tried to check for STDOUT. The check did not work,
305 I get a valid handle also in nonconsole apps.
306 Instead I test for console title, which seems to work. */
307 int
308 w32_window_app()
309 {
310 static int window_app = -1;
311 char szTitle[MAX_PATH];
312
313 if (window_app < 0)
314 window_app = (GetConsoleTitleA (szTitle, MAX_PATH) == 0);
315
316 return window_app;
317 }
318 #endif
319
320 void
321 message (int is_error, char *message, ...)
322 {
323 char msg [2048];
324 va_list args;
325
326 va_start (args, message);
327 vsprintf (msg, message, args);
328 va_end (args);
329
330 #ifdef WINDOWSNT
331 if (w32_window_app ())
332 {
333 if (is_error)
334 MessageBox (NULL, msg, "Emacsclient ERROR", MB_ICONERROR);
335 else
336 MessageBox (NULL, msg, "Emacsclient", MB_ICONINFORMATION);
337 }
338 else
339 #endif
340 {
341 FILE *f = is_error ? stderr : stdout;
342
343 fputs (msg, f);
344 fflush (f);
345 }
346 }
347
348 /* Decode the options from argv and argc.
349 The global variable `optind' will say how many arguments we used up. */
350
351 void
352 decode_options (argc, argv)
353 int argc;
354 char **argv;
355 {
356 alternate_editor = getenv ("ALTERNATE_EDITOR");
357 display = getenv ("DISPLAY");
358 if (display && strlen (display) == 0)
359 display = NULL;
360
361 while (1)
362 {
363 int opt = getopt_long (argc, argv,
364 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
365 "VHnea:s:f:d:tc",
366 #else
367 "VHnea:f:d:tc",
368 #endif
369 longopts, 0);
370
371 if (opt == EOF)
372 break;
373
374 switch (opt)
375 {
376 case 0:
377 /* If getopt returns 0, then it has already processed a
378 long-named option. We should do nothing. */
379 break;
380
381 case 'a':
382 alternate_editor = optarg;
383 break;
384
385 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
386 case 's':
387 socket_name = optarg;
388 break;
389 #endif
390
391 case 'f':
392 server_file = optarg;
393 break;
394
395 case 'd':
396 display = optarg;
397 break;
398
399 case 'n':
400 nowait = 1;
401 break;
402
403 case 'e':
404 eval = 1;
405 break;
406
407 case 'V':
408 message (FALSE, "emacsclient %s\n", VERSION);
409 exit (EXIT_SUCCESS);
410 break;
411
412 case 't':
413 tty = 1;
414 break;
415
416 case 'c':
417 current_frame = 1;
418 break;
419
420 case 'H':
421 print_help_and_exit ();
422 break;
423
424 default:
425 message (TRUE, "Try `%s --help' for more information\n", progname);
426 exit (EXIT_FAILURE);
427 break;
428 }
429 }
430
431 if (!tty && display)
432 window_system = 1;
433 else
434 tty = 1;
435
436 /* --no-wait implies --current-frame on ttys when there are file
437 arguments or expressions given. */
438 if (nowait && tty && argc - optind > 0)
439 current_frame = 1;
440
441 if (current_frame)
442 {
443 tty = 0;
444 window_system = 0;
445 }
446
447 if (tty)
448 window_system = 0;
449 }
450
451
452 void
453 print_help_and_exit ()
454 {
455 message (FALSE,
456 "Usage: %s [OPTIONS] FILE...\n\
457 Tell the Emacs server to visit the specified files.\n\
458 Every FILE can be either just a FILENAME or [+LINE[:COLUMN]] FILENAME.\n\
459 \n\
460 The following OPTIONS are accepted:\n\
461 -V, --version Just print version info and return\n\
462 -H, --help Print this usage information message\n\
463 -t, --tty Open a new Emacs frame on the current terminal\n\
464 -c, --current-frame Do not create a new frame; use the current Emacs frame\n\
465 -e, --eval Evaluate the FILE arguments as ELisp expressions\n\
466 -n, --no-wait Don't wait for the server to return\n\
467 -d, --display=DISPLAY Visit the file in the given display\n"
468 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
469 "-s, --socket-name=FILENAME\n\
470 Set filename of the UNIX socket for communication\n"
471 #endif
472 "-f, --server-file=FILENAME\n\
473 Set filename of the TCP authentication file\n\
474 -a, --alternate-editor=EDITOR\n\
475 Editor to fallback to if the server is not running\n\
476 \n\
477 Report bugs to bug-gnu-emacs@gnu.org.\n", progname);
478 exit (EXIT_SUCCESS);
479 }
480
481 /*
482 Try to run a different command, or --if no alternate editor is
483 defined-- exit with an errorcode.
484 */
485 void
486 fail (void)
487 {
488 if (alternate_editor)
489 {
490 int i = optind - 1;
491 #ifdef WINDOWSNT
492 main_argv[i] = (char *)alternate_editor;
493 #endif
494 execvp (alternate_editor, main_argv + i);
495 message (TRUE, "%s: error executing alternate editor \"%s\"\n",
496 progname, alternate_editor);
497 }
498 exit (EXIT_FAILURE);
499 }
500
501
502 #if !defined (HAVE_SOCKETS) || !defined (HAVE_INET_SOCKETS)
503
504 int
505 main (argc, argv)
506 int argc;
507 char **argv;
508 {
509 main_argc = argc;
510 main_argv = argv;
511 progname = argv[0];
512 message (TRUE, "%s: Sorry, the Emacs server is supported only\n"
513 "on systems with Berkeley sockets.\n",
514 argv[0]);
515 fail ();
516 }
517
518 #else /* HAVE_SOCKETS && HAVE_INET_SOCKETS */
519
520 #ifdef WINDOWSNT
521 # include <winsock2.h>
522 #else
523 # include <sys/types.h>
524 # include <sys/socket.h>
525 # include <sys/un.h>
526 # include <sys/stat.h>
527 # include <errno.h>
528 #endif
529
530 #define AUTH_KEY_LENGTH 64
531 #define SEND_BUFFER_SIZE 4096
532
533 extern char *strerror ();
534 extern int errno;
535
536 /* Buffer to accumulate data to send in TCP connections. */
537 char send_buffer[SEND_BUFFER_SIZE + 1];
538 int sblen = 0; /* Fill pointer for the send buffer. */
539
540 /* Let's send the data to Emacs when either
541 - the data ends in "\n", or
542 - the buffer is full (but this shouldn't happen)
543 Otherwise, we just accumulate it. */
544 void
545 send_to_emacs (s, data)
546 HSOCKET s;
547 char *data;
548 {
549 while (data)
550 {
551 int dlen = strlen (data);
552 if (dlen + sblen >= SEND_BUFFER_SIZE)
553 {
554 int part = SEND_BUFFER_SIZE - sblen;
555 strncpy (&send_buffer[sblen], data, part);
556 data += part;
557 sblen = SEND_BUFFER_SIZE;
558 }
559 else if (dlen)
560 {
561 strcpy (&send_buffer[sblen], data);
562 data = NULL;
563 sblen += dlen;
564 }
565 else
566 break;
567
568 if (sblen == SEND_BUFFER_SIZE
569 || (sblen > 0 && send_buffer[sblen-1] == '\n'))
570 {
571 int sent = send (s, send_buffer, sblen, 0);
572 if (sent != sblen)
573 strcpy (send_buffer, &send_buffer[sent]);
574 sblen -= sent;
575 }
576 }
577 }
346 578
347 579
348 /* In STR, insert a & before each &, each space, each newline, and 580 /* In STR, insert a & before each &, each space, each newline, and
349 any initial -. Change spaces to underscores, too, so that the 581 any initial -. Change spaces to underscores, too, so that the
350 return value never contains a space. 582 return value never contains a space.
351 583
352 Does not change the string. Outputs the result to STREAM. */ 584 Does not change the string. Outputs the result to STREAM. */
353
354 void 585 void
355 quote_argument (str, stream) 586 quote_argument (s, str)
587 HSOCKET s;
356 char *str; 588 char *str;
357 FILE *stream;
358 { 589 {
359 char *copy = (char *) xmalloc (strlen (str) * 2 + 1); 590 char *copy = (char *) xmalloc (strlen (str) * 2 + 1);
360 char *p, *q; 591 char *p, *q;
361 592
362 p = str; 593 p = str;
382 *q++ = *p++; 613 *q++ = *p++;
383 } 614 }
384 } 615 }
385 *q++ = 0; 616 *q++ = 0;
386 617
387 fprintf (stream, "%s", copy); 618 SEND_STRING (copy);
388 619
389 free (copy); 620 free (copy);
390 } 621 }
391 622
392 623
423 *q = 0; 654 *q = 0;
424 return str; 655 return str;
425 } 656 }
426 657
427 658
659 int
660 file_name_absolute_p (filename)
661 const unsigned char *filename;
662 {
663 /* Sanity check, it shouldn't happen. */
664 if (! filename) return FALSE;
665
666 /* /xxx is always an absolute path. */
667 if (filename[0] == '/') return TRUE;
668
669 /* Empty filenames (which shouldn't happen) are relative. */
670 if (filename[0] == '\0') return FALSE;
671
672 #ifdef WINDOWSNT
673 /* X:\xxx is always absolute; X:xxx is an error and will fail. */
674 if (isalpha (filename[0])
675 && filename[1] == ':' && (filename[2] == '\\' || filename[2] == '/'))
676 return TRUE;
677
678 /* Both \xxx and \\xxx\yyy are absolute. */
679 if (filename[0] == '\\') return TRUE;
680 #endif
681
682 return FALSE;
683 }
684
685 #ifdef WINDOWSNT
686 /* Wrapper to make WSACleanup a cdecl, as required by atexit(). */
687 void
688 __cdecl close_winsock ()
689 {
690 WSACleanup ();
691 }
692
693 /* Initialize the WinSock2 library. */
694 void
695 initialize_sockets ()
696 {
697 WSADATA wsaData;
698
699 if (WSAStartup (MAKEWORD (2, 0), &wsaData))
700 {
701 message (TRUE, "%s: error initializing WinSock2", progname);
702 exit (EXIT_FAILURE);
703 }
704
705 atexit (close_winsock);
706 }
707 #endif /* WINDOWSNT */
708
709
428 /* 710 /*
429 Try to run a different command, or --if no alternate editor is 711 * Read the information needed to set up a TCP comm channel with
430 defined-- exit with an errorcode. 712 * the Emacs server: host, port, pid and authentication string.
431 */ 713 */
432 void 714 int
433 fail (void) 715 get_server_config (server, authentication)
434 { 716 struct sockaddr_in *server;
435 if (alternate_editor) 717 char *authentication;
436 { 718 {
437 int i = optind - 1; 719 char dotted[32];
438 execvp (alternate_editor, main_argv + i); 720 char *port;
439 return; 721 char *pid;
440 } 722 FILE *config = NULL;
723
724 if (file_name_absolute_p (server_file))
725 config = fopen (server_file, "rb");
441 else 726 else
442 { 727 {
728 char *home = getenv ("HOME");
729
730 if (home)
731 {
732 char *path = alloca (32 + strlen (home) + strlen (server_file));
733 sprintf (path, "%s/.emacs.d/server/%s", home, server_file);
734 config = fopen (path, "rb");
735 }
736 #ifdef WINDOWSNT
737 if (!config && (home = getenv ("APPDATA")))
738 {
739 char *path = alloca (32 + strlen (home) + strlen (server_file));
740 sprintf (path, "%s/.emacs.d/server/%s", home, server_file);
741 config = fopen (path, "rb");
742 }
743 #endif
744 }
745
746 if (! config)
747 return FALSE;
748
749 if (fgets (dotted, sizeof dotted, config)
750 && (port = strchr (dotted, ':'))
751 && (pid = strchr (port, ' ')))
752 {
753 *port++ = '\0';
754 *pid++ = '\0';
755 }
756 else
757 {
758 message (TRUE, "%s: invalid configuration info", progname);
443 exit (EXIT_FAILURE); 759 exit (EXIT_FAILURE);
444 } 760 }
445 } 761
446 762 server->sin_family = AF_INET;
447 /* The process id of Emacs. */ 763 server->sin_addr.s_addr = inet_addr (dotted);
448 int emacs_pid; 764 server->sin_port = htons (atoi (port));
449 765
450 /* File handles for communicating with Emacs. */ 766 if (! fread (authentication, AUTH_KEY_LENGTH, 1, config))
451 FILE *out, *in; 767 {
452 768 message (TRUE, "%s: cannot read authentication info", progname);
769 exit (EXIT_FAILURE);
770 }
771
772 fclose (config);
773
774 emacs_pid = atoi (pid);
775
776 return TRUE;
777 }
778
779 HSOCKET
780 set_tcp_socket ()
781 {
782 HSOCKET s;
783 struct sockaddr_in server;
784 struct linger l_arg = {1, 1};
785 char auth_string[AUTH_KEY_LENGTH + 1];
786
787 if (! get_server_config (&server, auth_string))
788 return INVALID_SOCKET;
789
790 if (server.sin_addr.s_addr != inet_addr ("127.0.0.1"))
791 message (FALSE, "%s: connected to remote socket at %s\n",
792 progname, inet_ntoa (server.sin_addr));
793
794 /*
795 * Open up an AF_INET socket
796 */
797 if ((s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
798 {
799 message (TRUE, "%s: socket: %s\n", progname, strerror (errno));
800 return INVALID_SOCKET;
801 }
802
803 /*
804 * Set up the socket
805 */
806 if (connect (s, (struct sockaddr *) &server, sizeof server) < 0)
807 {
808 message (TRUE, "%s: connect: %s\n", progname, strerror (errno));
809 return INVALID_SOCKET;
810 }
811
812 setsockopt (s, SOL_SOCKET, SO_LINGER, (char *) &l_arg, sizeof l_arg);
813
814 /*
815 * Send the authentication
816 */
817 auth_string[AUTH_KEY_LENGTH] = '\0';
818
819 SEND_STRING ("-auth ");
820 SEND_STRING (auth_string);
821 SEND_STRING ("\n");
822
823 return s;
824 }
825
826 #if !defined (NO_SOCKETS_IN_FILE_SYSTEM)
827
828 /* Three possibilities:
829 2 - can't be `stat'ed (sets errno)
830 1 - isn't owned by us
831 0 - success: none of the above */
832
833 static int
834 socket_status (socket_name)
835 char *socket_name;
836 {
837 struct stat statbfr;
838
839 if (stat (socket_name, &statbfr) == -1)
840 return 2;
841
842 if (statbfr.st_uid != geteuid ())
843 return 1;
844
845 return 0;
846 }
847
848
453 /* A signal handler that passes the signal to the Emacs process. 849 /* A signal handler that passes the signal to the Emacs process.
454 Useful for SIGWINCH. */ 850 Useful for SIGWINCH. */
455 851
456 SIGTYPE 852 SIGTYPE
457 pass_signal_to_emacs (int signalnum) 853 pass_signal_to_emacs (int signalnum)
540 signal (SIGCONT, handle_sigcont); 936 signal (SIGCONT, handle_sigcont);
541 signal (SIGTSTP, handle_sigtstp); 937 signal (SIGTSTP, handle_sigtstp);
542 signal (SIGTTOU, handle_sigtstp); 938 signal (SIGTTOU, handle_sigtstp);
543 } 939 }
544 940
545 941
546 #if !defined (HAVE_SOCKETS) || defined (NO_SOCKETS_IN_FILE_SYSTEM)
547
548 int
549 main (argc, argv)
550 int argc;
551 char **argv;
552 {
553 fprintf (stderr, "%s: Sorry, the Emacs server is supported only\n",
554 argv[0]);
555 fprintf (stderr, "on systems with Berkeley sockets.\n");
556
557 fail ();
558 }
559
560 #else /* HAVE_SOCKETS */
561
562 #include <sys/types.h>
563 #include <sys/socket.h>
564 #include <sys/un.h>
565 #include <sys/stat.h>
566 #include <errno.h>
567
568 extern char *strerror ();
569 extern int errno;
570
571 /* Three possibilities:
572 2 - can't be `stat'ed (sets errno)
573 1 - isn't owned by us
574 0 - success: none of the above */
575
576 static int
577 socket_status (socket_name)
578 char *socket_name;
579 {
580 struct stat statbfr;
581
582 if (stat (socket_name, &statbfr) == -1)
583 return 2;
584
585 if (statbfr.st_uid != geteuid ())
586 return 1;
587
588 return 0;
589 }
590 942
591 /* Returns 1 if PREFIX is a prefix of STRING. */ 943 /* Returns 1 if PREFIX is a prefix of STRING. */
592 static int 944 static int
593 strprefix (char *prefix, char *string) 945 strprefix (char *prefix, char *string)
594 { 946 {
603 if (!string[i] || string[i] != prefix[i]) 955 if (!string[i] || string[i] != prefix[i])
604 return 0; 956 return 0;
605 return 1; 957 return 1;
606 } 958 }
607 959
608 int 960
609 main (argc, argv) 961 HSOCKET
610 int argc; 962 set_local_socket ()
611 char **argv; 963 {
612 { 964 HSOCKET s;
613 int s, i, needlf = 0;
614 struct sockaddr_un server; 965 struct sockaddr_un server;
615 char *cwd, *str;
616 char string[BUFSIZ];
617
618 main_argc = argc;
619 main_argv = argv;
620 progname = argv[0];
621
622 /* Process options. */
623 decode_options (argc, argv);
624
625 if ((argc - optind < 1) && !eval && !tty && !window_system)
626 {
627 fprintf (stderr, "%s: file name or argument required\n", progname);
628 fprintf (stderr, "Try `%s --help' for more information\n", progname);
629 exit (EXIT_FAILURE);
630 }
631 966
632 /* 967 /*
633 * Open up an AF_UNIX socket in this person's home directory 968 * Open up an AF_UNIX socket in this person's home directory
634 */ 969 */
635 970
636 if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) 971 if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
637 { 972 {
638 fprintf (stderr, "%s: ", argv[0]); 973 message (TRUE, "%s: socket: %s\n", progname, strerror (errno));
639 perror ("socket"); 974 return INVALID_SOCKET;
640 fail ();
641 } 975 }
642 976
643 server.sun_family = AF_UNIX; 977 server.sun_family = AF_UNIX;
644 978
645 { 979 {
646 int sock_status = 0; 980 int sock_status = 0;
647 int default_sock = !socket_name; 981 int default_sock = !socket_name;
648 int saved_errno = 0; 982 int saved_errno = 0;
649 983
650 char *server_name = "server"; 984 char *server_name = "server";
651 985
652 if (socket_name && !index (socket_name, '/') && !index (socket_name, '\\')) 986 if (socket_name && !index (socket_name, '/') && !index (socket_name, '\\'))
653 { /* socket_name is a file name component. */ 987 { /* socket_name is a file name component. */
654 server_name = socket_name; 988 server_name = socket_name;
655 socket_name = NULL; 989 socket_name = NULL;
656 default_sock = 1; /* Try both UIDs. */ 990 default_sock = 1; /* Try both UIDs. */
657 } 991 }
658 992
659 if (default_sock) 993 if (default_sock)
660 { 994 {
661 socket_name = alloca (100 + strlen (server_name)); 995 socket_name = alloca (100 + strlen (server_name));
662 sprintf (socket_name, "/tmp/emacs%d/%s", 996 sprintf (socket_name, "/tmp/emacs%d/%s",
663 (int) geteuid (), server_name); 997 (int) geteuid (), server_name);
664 } 998 }
665 999
666 if (strlen (socket_name) < sizeof (server.sun_path)) 1000 if (strlen (socket_name) < sizeof (server.sun_path))
667 strcpy (server.sun_path, socket_name); 1001 strcpy (server.sun_path, socket_name);
668 else 1002 else
669 { 1003 {
670 fprintf (stderr, "%s: socket-name %s too long", 1004 message (TRUE, "%s: socket-name %s too long",
671 argv[0], socket_name); 1005 progname, socket_name);
672 fail (); 1006 fail ();
673 } 1007 }
674 1008
675 /* See if the socket exists, and if it's owned by us. */ 1009 /* See if the socket exists, and if it's owned by us. */
676 sock_status = socket_status (server.sun_path); 1010 sock_status = socket_status (server.sun_path);
700 1034
701 if (strlen (socket_name) < sizeof (server.sun_path)) 1035 if (strlen (socket_name) < sizeof (server.sun_path))
702 strcpy (server.sun_path, socket_name); 1036 strcpy (server.sun_path, socket_name);
703 else 1037 else
704 { 1038 {
705 fprintf (stderr, "%s: socket-name %s too long", 1039 message (TRUE, "%s: socket-name %s too long",
706 argv[0], socket_name); 1040 progname, socket_name);
707 exit (EXIT_FAILURE); 1041 exit (EXIT_FAILURE);
708 } 1042 }
709 1043
710 sock_status = socket_status (server.sun_path); 1044 sock_status = socket_status (server.sun_path);
711 saved_errno = errno; 1045 saved_errno = errno;
713 else 1047 else
714 errno = saved_errno; 1048 errno = saved_errno;
715 } 1049 }
716 } 1050 }
717 1051
718 switch (sock_status) 1052 switch (sock_status)
719 { 1053 {
720 case 1: 1054 case 1:
721 /* There's a socket, but it isn't owned by us. This is OK if 1055 /* There's a socket, but it isn't owned by us. This is OK if
722 we are root. */ 1056 we are root. */
723 if (0 != geteuid ()) 1057 if (0 != geteuid ())
724 { 1058 {
725 fprintf (stderr, "%s: Invalid socket owner\n", argv[0]); 1059 message (TRUE, "%s: Invalid socket owner\n", progname);
726 fail (); 1060 return INVALID_SOCKET;
727 } 1061 }
728 break; 1062 break;
729 1063
730 case 2: 1064 case 2:
731 /* `stat' failed */ 1065 /* `stat' failed */
732 if (saved_errno == ENOENT) 1066 if (saved_errno == ENOENT)
733 fprintf (stderr, 1067 message (TRUE,
734 "%s: can't find socket; have you started the server?\n\ 1068 "%s: can't find socket; have you started the server?\n\
735 To start the server in Emacs, type \"M-x server-start\".\n", 1069 To start the server in Emacs, type \"M-x server-start\".\n",
736 argv[0]); 1070 progname);
737 else 1071 else
738 fprintf (stderr, "%s: can't stat %s: %s\n", 1072 message (TRUE, "%s: can't stat %s: %s\n",
739 argv[0], server.sun_path, strerror (saved_errno)); 1073 progname, server.sun_path, strerror (saved_errno));
740 fail (); 1074 return INVALID_SOCKET;
741 break; 1075 }
742 }
743 } 1076 }
744 1077
745 if (connect (s, (struct sockaddr *) &server, strlen (server.sun_path) + 2) 1078 if (connect (s, (struct sockaddr *) &server, strlen (server.sun_path) + 2)
746 < 0) 1079 < 0)
747 { 1080 {
748 fprintf (stderr, "%s: ", argv[0]); 1081 message (TRUE, "%s: connect: %s\n", progname, strerror (errno));
749 perror ("connect"); 1082 return INVALID_SOCKET;
1083 }
1084
1085 return s;
1086 }
1087 #endif /* ! NO_SOCKETS_IN_FILE_SYSTEM */
1088
1089 HSOCKET
1090 set_socket ()
1091 {
1092 HSOCKET s;
1093
1094 INITIALIZE ();
1095
1096 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
1097 /* Explicit --socket-name argument. */
1098 if (socket_name)
1099 {
1100 s = set_local_socket ();
1101 if ((s != INVALID_SOCKET) || alternate_editor)
1102 return s;
1103 message (TRUE, "%s: error accessing socket \"%s\"",
1104 progname, socket_name);
1105 exit (EXIT_FAILURE);
1106 }
1107 #endif
1108
1109 /* Explicit --server-file arg or EMACS_SERVER_FILE variable. */
1110 if (!server_file)
1111 server_file = getenv ("EMACS_SERVER_FILE");
1112
1113 if (server_file)
1114 {
1115 s = set_tcp_socket ();
1116 if ((s != INVALID_SOCKET) || alternate_editor)
1117 return s;
1118
1119 message (TRUE, "%s: error accessing server file \"%s\"",
1120 progname, server_file);
1121 exit (EXIT_FAILURE);
1122 }
1123
1124 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
1125 /* Implicit local socket. */
1126 s = set_local_socket ();
1127 if (s != INVALID_SOCKET)
1128 return s;
1129 #endif
1130
1131 /* Implicit server file. */
1132 server_file = "server";
1133 s = set_tcp_socket ();
1134 if ((s != INVALID_SOCKET) || alternate_editor)
1135 return s;
1136
1137 /* No implicit or explicit socket, and no alternate editor. */
1138 message (TRUE, "%s: No socket or alternate editor. Please use:\n\n"
1139 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
1140 "\t--socket-name\n"
1141 #endif
1142 "\t--server-file (or environment variable EMACS_SERVER_FILE)\n\
1143 \t--alternate-editor (or environment variable ALTERNATE_EDITOR)\n",
1144 progname);
1145 exit (EXIT_FAILURE);
1146 }
1147
1148 int
1149 main (argc, argv)
1150 int argc;
1151 char **argv;
1152 {
1153 HSOCKET s;
1154 int i, rl, needlf = 0;
1155 char *cwd, *str;
1156 char string[BUFSIZ+1];
1157
1158 main_argc = argc;
1159 main_argv = argv;
1160 progname = argv[0];
1161
1162 /* Process options. */
1163 decode_options (argc, argv);
1164
1165 if ((argc - optind < 1) && !eval && !tty && !window_system)
1166 {
1167 message (TRUE, "%s: file name or argument required\n"
1168 "Try `%s --help' for more information\n",
1169 progname, progname);
1170 exit (EXIT_FAILURE);
1171 }
1172
1173 if ((s = set_socket ()) == INVALID_SOCKET)
1174 fail ();
1175
1176
1177 cwd = get_current_dir_name ();
1178 if (cwd == 0)
1179 {
1180 /* getwd puts message in STRING if it fails. */
1181 message (TRUE, "%s: %s\n", progname,
1182 "Cannot get current working directory");
750 fail (); 1183 fail ();
751 } 1184 }
752 1185
753 /* We use the stream OUT to send our commands to the server. */ 1186 #ifdef WINDOWSNT
754 if ((out = fdopen (s, "r+")) == NULL) 1187 /*
755 { 1188 Modern Windows restrict which processes can set the foreground window.
756 fprintf (stderr, "%s: ", argv[0]); 1189 emacsclient can allow Emacs to grab the focus by calling the function
757 perror ("fdopen"); 1190 AllowSetForegroundWindow(). Unfortunately, older Windows (W95, W98
758 fail (); 1191 and NT) lack this function, so we have to check its availability.
759 } 1192 */
760 1193 if (emacs_pid)
761 /* We use the stream IN to read the responses. 1194 {
762 We used to use just one stream for both output and input 1195 HMODULE hUser32;
763 on the socket, but reversing direction works nonportably: 1196
764 on some systems, the output appears as the first input; 1197 if (hUser32 = LoadLibrary ("user32.dll"))
765 on other systems it does not. */ 1198 {
766 if ((in = fdopen (s, "r+")) == NULL) 1199 FARPROC set_fg;
767 { 1200 if (set_fg = GetProcAddress (hUser32, "AllowSetForegroundWindow"))
768 fprintf (stderr, "%s: ", argv[0]); 1201 set_fg (emacs_pid);
769 perror ("fdopen"); 1202 FreeLibrary (hUser32);
770 fail (); 1203 }
771 } 1204 }
772 1205 #endif
773 #ifdef HAVE_GETCWD
774 cwd = getcwd (string, sizeof string);
775 #else
776 cwd = getwd (string);
777 #endif
778 if (cwd == 0)
779 {
780 /* getwd puts message in STRING if it fails. */
781
782 #ifdef HAVE_GETCWD
783 fprintf (stderr, "%s: %s (%s)\n", argv[0],
784 "cannot get current working directory", strerror (errno));
785 #else
786 fprintf (stderr, "%s: %s (%s)\n", argv[0], string, strerror (errno));
787 #endif
788 fail ();
789 }
790 1206
791 /* First of all, send our version number for verification. */ 1207 /* First of all, send our version number for verification. */
792 fprintf (out, "-version %s ", VERSION); 1208 SEND_STRING ("-version ");
1209 SEND_STRING (VERSION);
1210 SEND_STRING (" ");
793 1211
794 /* Send over our environment. */ 1212 /* Send over our environment. */
795 if (!current_frame) 1213 if (!current_frame)
796 { 1214 {
797 extern char **environ; 1215 extern char **environ;
798 int i; 1216 int i;
799 for (i = 0; environ[i]; i++) 1217 for (i = 0; environ[i]; i++)
800 { 1218 {
801 char *name = xstrdup (environ[i]); 1219 char *name = xstrdup (environ[i]);
802 char *value = strchr (name, '='); 1220 char *value = strchr (name, '=');
803 fprintf (out, "-env "); 1221 SEND_STRING ("-env ");
804 quote_argument (environ[i], out); 1222 SEND_QUOTED (environ[i]);
805 fprintf (out, " "); 1223 SEND_STRING (" ");
806 } 1224 }
807 } 1225 }
808 1226
809 /* Send over our current directory. */ 1227 /* Send over our current directory. */
810 if (!current_frame) 1228 if (!current_frame)
811 { 1229 {
812 char *dir = get_current_dir_name (); 1230 SEND_STRING ("-dir ");
813 if (dir) 1231 SEND_QUOTED (cwd);
814 { 1232 SEND_STRING ("/");
815 fprintf (out, "-dir "); 1233 SEND_STRING (" ");
816 quote_argument (dir, out);
817 fprintf (out, "/");
818 fprintf (out, " ");
819 free (dir);
820 }
821 } 1234 }
822 1235
823 retry: 1236 retry:
824 if (nowait) 1237 if (nowait)
825 fprintf (out, "-nowait "); 1238 SEND_STRING ("-nowait ");
826 1239
827 if (current_frame) 1240 if (current_frame)
828 fprintf (out, "-current-frame "); 1241 SEND_STRING ("-current-frame ");
829 1242
830 if (display) 1243 if (display)
831 { 1244 {
832 fprintf (out, "-display "); 1245 SEND_STRING ("-display ");
833 quote_argument (display, out); 1246 SEND_QUOTED (display);
834 fprintf (out, " "); 1247 SEND_STRING (" ");
835 } 1248 }
836 1249
837 if (tty) 1250 if (tty)
838 { 1251 {
839 char *tty_name = ttyname (fileno (stdin)); 1252 char *tty_name = ttyname (fileno (stdin));
840 char *type = getenv ("TERM"); 1253 char *type = getenv ("TERM");
841 1254
842 if (! tty_name) 1255 if (! tty_name)
843 { 1256 {
844 fprintf (stderr, "%s: could not get terminal name\n", progname); 1257 message (TRUE, "%s: could not get terminal name\n", progname);
845 fail (); 1258 fail ();
846 } 1259 }
847 1260
848 if (! type) 1261 if (! type)
849 { 1262 {
850 fprintf (stderr, "%s: please set the TERM variable to your terminal type\n", 1263 message (TRUE, "%s: please set the TERM variable to your terminal type\n",
851 progname); 1264 progname);
852 fail (); 1265 fail ();
853 } 1266 }
854 1267
855 if (! strcmp (type, "eterm")) 1268 if (! strcmp (type, "eterm"))
856 { 1269 {
857 /* This causes nasty, MULTI_KBOARD-related input lockouts. */ 1270 /* This causes nasty, MULTI_KBOARD-related input lockouts. */
858 fprintf (stderr, "%s: opening a frame in an Emacs term buffer" 1271 message (TRUE, "%s: opening a frame in an Emacs term buffer"
859 " is not supported\n", progname); 1272 " is not supported\n", progname);
860 fail (); 1273 fail ();
861 } 1274 }
862 1275
863 init_signals (); 1276 init_signals ();
864 1277
865 fprintf (out, "-tty "); 1278 SEND_STRING ("-tty ");
866 quote_argument (tty_name, out); 1279 SEND_QUOTED (tty_name);
867 fprintf (out, " "); 1280 SEND_STRING (" ");
868 quote_argument (type, out); 1281 SEND_QUOTED (type);
869 fprintf (out, " "); 1282 SEND_STRING (" ");
870 } 1283 }
871 1284
872 if (window_system) 1285 if (window_system)
873 fprintf (out, "-window-system "); 1286 SEND_STRING ("-window-system ");
874 1287
875 if ((argc - optind > 0)) 1288 if ((argc - optind > 0))
876 { 1289 {
877 for (i = optind; i < argc; i++) 1290 for (i = optind; i < argc; i++)
878 { 1291 {
879 int relative = 0; 1292 int relative = 0;
880 1293
881 if (eval) 1294 if (eval)
882 { 1295 {
883 /* Don't prepend any cwd or anything like that. */ 1296 /* Don't prepend cwd or anything like that. */
884 fprintf (out, "-eval "); 1297 SEND_STRING ("-eval ");
885 quote_argument (argv[i], out); 1298 SEND_QUOTED (argv[i]);
886 fprintf (out, " "); 1299 SEND_STRING (" ");
887 continue; 1300 continue;
888 } 1301 }
889 1302
890 if (*argv[i] == '+') 1303 if (*argv[i] == '+')
891 { 1304 {
892 char *p = argv[i] + 1; 1305 char *p = argv[i] + 1;
893 while (isdigit ((unsigned char) *p) || *p == ':') p++; 1306 while (isdigit ((unsigned char) *p) || *p == ':') p++;
894 if (*p == 0) 1307 if (*p == 0)
895 { 1308 {
896 fprintf (out, "-position "); 1309 SEND_STRING ("-position ");
897 quote_argument (argv[i], out); 1310 SEND_QUOTED (argv[i]);
898 fprintf (out, " "); 1311 SEND_STRING (" ");
899 continue; 1312 continue;
900 } 1313 }
901 else 1314 else
902 relative = 1; 1315 relative = 1;
903 } 1316 }
904 else if (*argv[i] != '/') 1317 else if (! file_name_absolute_p (argv[i]))
905 relative = 1; 1318 relative = 1;
906 1319
907 fprintf (out, "-file "); 1320 SEND_STRING ("-file ");
908 if (relative) 1321 if (relative)
909 { 1322 {
910 quote_argument (cwd, out); 1323 SEND_QUOTED (cwd);
911 fprintf (out, "/"); 1324 SEND_STRING ("/");
912 } 1325 }
913 quote_argument (argv[i], out); 1326 SEND_QUOTED (argv[i]);
914 fprintf (out, " "); 1327 SEND_STRING (" ");
915 } 1328 }
916 } 1329 }
917 else 1330 else
918 { 1331 {
919 if (!tty && !window_system) 1332 if (!tty && !window_system)
920 { 1333 {
921 while ((str = fgets (string, BUFSIZ, stdin))) 1334 while ((str = fgets (string, BUFSIZ, stdin)))
922 { 1335 {
923 if (eval) 1336 if (eval)
924 fprintf (out, "-eval "); 1337 SEND_STRING ("-eval ");
925 else 1338 else
926 fprintf (out, "-file "); 1339 SEND_STRING ("-file ");
927 quote_argument (str, out); 1340 SEND_QUOTED (out);
928 } 1341 }
929 fprintf (out, " "); 1342 SEND_STRING (" ");
930 } 1343 }
931 } 1344 }
932 1345
933 fprintf (out, "\n"); 1346 SEND_STRING ("\n");
934 fflush (out);
935 fsync (fileno (out));
936 1347
937 /* Wait for an answer. */ 1348 /* Wait for an answer. */
938 if (!eval && !tty && !nowait) 1349 if (!eval && !tty && !nowait)
939 { 1350 {
940 printf ("Waiting for Emacs..."); 1351 printf ("Waiting for Emacs...");
942 } 1353 }
943 fflush (stdout); 1354 fflush (stdout);
944 fsync (1); 1355 fsync (1);
945 1356
946 /* Now, wait for an answer and print any messages. */ 1357 /* Now, wait for an answer and print any messages. */
947 while ((str = fgets (string, BUFSIZ, in))) 1358 while ((rl = recv (s, string, BUFSIZ, 0)) > 0)
948 { 1359 {
949 char *p = str + strlen (str) - 1; 1360 char *p;
950 while (p > str && *p == '\n') 1361 string[rl] = '\0';
1362
1363 p = string + strlen (string) - 1;
1364 while (p > string && *p == '\n')
951 *p-- = 0; 1365 *p-- = 0;
952 1366
953 if (strprefix ("-good-version ", str)) 1367 if (strprefix ("-good-version ", string))
954 { 1368 {
955 /* -good-version: The versions match. */ 1369 /* -good-version: The versions match. */
956 } 1370 }
957 else if (strprefix ("-emacs-pid ", str)) 1371 else if (strprefix ("-emacs-pid ", string))
958 { 1372 {
959 /* -emacs-pid PID: The process id of the Emacs process. */ 1373 /* -emacs-pid PID: The process id of the Emacs process. */
960 emacs_pid = strtol (string + strlen ("-emacs-pid"), NULL, 10); 1374 emacs_pid = strtol (string + strlen ("-emacs-pid"), NULL, 10);
961 } 1375 }
962 else if (strprefix ("-window-system-unsupported ", str)) 1376 else if (strprefix ("-window-system-unsupported ", string))
963 { 1377 {
964 /* -window-system-unsupported: Emacs was compiled without X 1378 /* -window-system-unsupported: Emacs was compiled without X
965 support. Try again on the terminal. */ 1379 support. Try again on the terminal. */
966 window_system = 0; 1380 window_system = 0;
967 nowait = 0; 1381 nowait = 0;
968 tty = 1; 1382 tty = 1;
969 goto retry; 1383 goto retry;
970 } 1384 }
971 else if (strprefix ("-print ", str)) 1385 else if (strprefix ("-print ", string))
972 { 1386 {
973 /* -print STRING: Print STRING on the terminal. */ 1387 /* -print STRING: Print STRING on the terminal. */
974 str = unquote_argument (str + strlen ("-print ")); 1388 str = unquote_argument (string + strlen ("-print "));
975 if (needlf) 1389 if (needlf)
976 printf ("\n"); 1390 printf ("\n");
977 printf ("%s", str); 1391 printf ("%s", str);
978 needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n'; 1392 needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n';
979 } 1393 }
980 else if (strprefix ("-error ", str)) 1394 else if (strprefix ("-error ", string))
981 { 1395 {
982 /* -error DESCRIPTION: Signal an error on the terminal. */ 1396 /* -error DESCRIPTION: Signal an error on the terminal. */
983 str = unquote_argument (str + strlen ("-error ")); 1397 str = unquote_argument (string + strlen ("-error "));
984 if (needlf) 1398 if (needlf)
985 printf ("\n"); 1399 printf ("\n");
986 printf ("*ERROR*: %s", str); 1400 fprintf (stderr, "*ERROR*: %s", str);
987 needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n'; 1401 needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n';
988 } 1402 }
989 else if (strprefix ("-suspend ", str)) 1403 else if (strprefix ("-suspend ", str))
990 { 1404 {
991 /* -suspend: Suspend this terminal, i.e., stop the process. */ 1405 /* -suspend: Suspend this terminal, i.e., stop the process. */
997 else 1411 else
998 { 1412 {
999 /* Unknown command. */ 1413 /* Unknown command. */
1000 if (needlf) 1414 if (needlf)
1001 printf ("\n"); 1415 printf ("\n");
1002 printf ("*ERROR*: Unknown message: %s", str); 1416 printf ("*ERROR*: Unknown message: %s", string);
1003 needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n'; 1417 needlf = string[0] == '\0' ? needlf : string[strlen (string) - 1] != '\n';
1004 } 1418 }
1005 } 1419 }
1006 1420
1007 if (needlf) 1421 if (needlf)
1008 printf ("\n"); 1422 printf ("\n");
1009 fflush (stdout); 1423 fflush (stdout);
1010 fsync (1); 1424 fsync (1);
1011 1425
1426 CLOSE_SOCKET (s);
1012 return EXIT_SUCCESS; 1427 return EXIT_SUCCESS;
1013 } 1428 }
1014 1429
1015 #endif /* HAVE_SOCKETS */ 1430 #endif /* HAVE_SOCKETS && HAVE_INET_SOCKETS */
1431
1016 1432
1017 #ifndef HAVE_STRERROR 1433 #ifndef HAVE_STRERROR
1018 char * 1434 char *
1019 strerror (errnum) 1435 strerror (errnum)
1020 int errnum; 1436 int errnum;