Mercurial > emacs
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; |