Mercurial > emacs
comparison lib-src/emacsclient.c @ 74118:bee73d83d967
Include <stdarg.h>.
[WINDOWSNT]: Include <windows.h>.
(w32_check_console_app): New function.
(message): New function.
(decode_options, print_help_and_exit, fail, main, initialize_sockets,
get_server_config, set_tcp_socket, set_local_socket, set_socket):
Use message().
author | Juanma Barranquero <lekktu@gmail.com> |
---|---|
date | Wed, 22 Nov 2006 14:16:42 +0000 |
parents | 7c6eb34059d6 |
children | 46dc2e041725 |
comparison
equal
deleted
inserted
replaced
74117:db85df5747ae | 74118:bee73d83d967 |
---|---|
32 # undef _WINSOCKAPI_ | 32 # undef _WINSOCKAPI_ |
33 # undef _WINSOCK_H | 33 # undef _WINSOCK_H |
34 | 34 |
35 # include <malloc.h> | 35 # include <malloc.h> |
36 # include <stdlib.h> | 36 # include <stdlib.h> |
37 # include <windows.h> | |
37 | 38 |
38 # define NO_SOCKETS_IN_FILE_SYSTEM | 39 # define NO_SOCKETS_IN_FILE_SYSTEM |
39 | 40 |
40 # define HSOCKET SOCKET | 41 # define HSOCKET SOCKET |
41 # define CLOSE_SOCKET closesocket | 42 # define CLOSE_SOCKET closesocket |
56 | 57 |
57 #endif /* !WINDOWSNT */ | 58 #endif /* !WINDOWSNT */ |
58 | 59 |
59 #undef signal | 60 #undef signal |
60 | 61 |
62 #include <stdarg.h> | |
61 #include <ctype.h> | 63 #include <ctype.h> |
62 #include <stdio.h> | 64 #include <stdio.h> |
63 #include "getopt.h" | 65 #include "getopt.h" |
64 #ifdef HAVE_UNISTD_H | 66 #ifdef HAVE_UNISTD_H |
65 #include <unistd.h> | 67 #include <unistd.h> |
142 { "server-file", required_argument, NULL, 'f' }, | 144 { "server-file", required_argument, NULL, 'f' }, |
143 { "display", required_argument, NULL, 'd' }, | 145 { "display", required_argument, NULL, 'd' }, |
144 { 0, 0, 0, 0 } | 146 { 0, 0, 0, 0 } |
145 }; | 147 }; |
146 | 148 |
149 /* Message functions. */ | |
150 | |
151 #ifdef WINDOWSNT | |
152 /* I first tried to check for STDOUT. The check did not work, | |
153 I get a valid handle also in nonconsole apps. | |
154 Instead I test for console title, which seems to work. */ | |
155 int | |
156 w32_window_app() | |
157 { | |
158 static int window_app = -1; | |
159 char szTitle[MAX_PATH]; | |
160 | |
161 if (window_app < 0) | |
162 window_app = (GetConsoleTitleA (szTitle, MAX_PATH) == 0); | |
163 | |
164 return window_app; | |
165 } | |
166 #endif | |
167 | |
168 void | |
169 message (int is_error, char *message, ...) | |
170 { | |
171 char buf [2048]; | |
172 char *msg = buf; | |
173 va_list args; | |
174 | |
175 va_start (args, message); | |
176 | |
177 if (is_error) | |
178 { | |
179 sprintf (buf, "%s: ", progname); | |
180 msg = strchr (buf, '\0'); | |
181 } | |
182 | |
183 vsprintf (msg, message, args); | |
184 va_end (args); | |
185 | |
186 #ifdef WINDOWSNT | |
187 if (w32_window_app ()) | |
188 { | |
189 if (is_error) | |
190 MessageBox (NULL, msg, "Emacsclient ERROR", MB_ICONERROR); | |
191 else | |
192 MessageBox (NULL, msg, "Emacsclient", MB_ICONINFORMATION); | |
193 } | |
194 else | |
195 #endif | |
196 fprintf (is_error ? stderr : stdout, msg); | |
197 } | |
198 | |
147 /* Decode the options from argv and argc. | 199 /* Decode the options from argv and argc. |
148 The global variable `optind' will say how many arguments we used up. */ | 200 The global variable `optind' will say how many arguments we used up. */ |
149 | 201 |
150 void | 202 void |
151 decode_options (argc, argv) | 203 decode_options (argc, argv) |
199 case 'e': | 251 case 'e': |
200 eval = 1; | 252 eval = 1; |
201 break; | 253 break; |
202 | 254 |
203 case 'V': | 255 case 'V': |
204 printf ("emacsclient %s\n", VERSION); | 256 message (FALSE, "emacsclient %s\n", VERSION); |
205 exit (EXIT_SUCCESS); | 257 exit (EXIT_SUCCESS); |
206 break; | 258 break; |
207 | 259 |
208 case 'H': | 260 case 'H': |
209 print_help_and_exit (); | 261 print_help_and_exit (); |
210 break; | 262 break; |
211 | 263 |
212 default: | 264 default: |
213 fprintf (stderr, "Try `%s --help' for more information\n", progname); | 265 message (TRUE, "Try `%s --help' for more information\n", progname); |
214 exit (EXIT_FAILURE); | 266 exit (EXIT_FAILURE); |
215 break; | 267 break; |
216 } | 268 } |
217 } | 269 } |
218 } | 270 } |
219 | 271 |
220 void | 272 void |
221 print_help_and_exit () | 273 print_help_and_exit () |
222 { | 274 { |
223 printf ( | 275 message (FALSE, |
224 "Usage: %s [OPTIONS] FILE...\n\ | 276 "Usage: %s [OPTIONS] FILE...\n\ |
225 Tell the Emacs server to visit the specified files.\n\ | 277 Tell the Emacs server to visit the specified files.\n\ |
226 Every FILE can be either just a FILENAME or [+LINE[:COLUMN]] FILENAME.\n\ | 278 Every FILE can be either just a FILENAME or [+LINE[:COLUMN]] FILENAME.\n\ |
227 \n\ | 279 \n\ |
228 The following OPTIONS are accepted:\n\ | 280 The following OPTIONS are accepted:\n\ |
259 int i = optind - 1; | 311 int i = optind - 1; |
260 #ifdef WINDOWSNT | 312 #ifdef WINDOWSNT |
261 argv[i] = (char *)alternate_editor; | 313 argv[i] = (char *)alternate_editor; |
262 #endif | 314 #endif |
263 execvp (alternate_editor, argv + i); | 315 execvp (alternate_editor, argv + i); |
264 fprintf (stderr, "%s: error executing alternate editor \"%s\"\n", | 316 message (TRUE, "%s: error executing alternate editor \"%s\"\n", |
265 progname, alternate_editor); | 317 progname, alternate_editor); |
266 } | 318 } |
267 exit (EXIT_FAILURE); | 319 exit (EXIT_FAILURE); |
268 } | 320 } |
269 | 321 |
273 int | 325 int |
274 main (argc, argv) | 326 main (argc, argv) |
275 int argc; | 327 int argc; |
276 char **argv; | 328 char **argv; |
277 { | 329 { |
278 fprintf (stderr, "%s: Sorry, the Emacs server is supported only\n", | 330 message (TRUE, "%s: Sorry, the Emacs server is supported only\non systems with Berkely sockets.\n", |
279 argv[0]); | 331 argv[0]); |
280 fprintf (stderr, "on systems with Berkeley sockets.\n"); | |
281 | 332 |
282 fail (argc, argv); | 333 fail (argc, argv); |
283 } | 334 } |
284 | 335 |
285 #else /* HAVE_SOCKETS && HAVE_INET_SOCKETS */ | 336 #else /* HAVE_SOCKETS && HAVE_INET_SOCKETS */ |
424 { | 475 { |
425 WSADATA wsaData; | 476 WSADATA wsaData; |
426 | 477 |
427 if (WSAStartup (MAKEWORD (2, 0), &wsaData)) | 478 if (WSAStartup (MAKEWORD (2, 0), &wsaData)) |
428 { | 479 { |
429 fprintf (stderr, "%s: error initializing WinSock2", progname); | 480 message (TRUE, "%s: error initializing WinSock2", progname); |
430 exit (EXIT_FAILURE); | 481 exit (EXIT_FAILURE); |
431 } | 482 } |
432 | 483 |
433 atexit (close_winsock); | 484 atexit (close_winsock); |
434 } | 485 } |
480 *port++ = '\0'; | 531 *port++ = '\0'; |
481 *pid++ = '\0'; | 532 *pid++ = '\0'; |
482 } | 533 } |
483 else | 534 else |
484 { | 535 { |
485 fprintf (stderr, "%s: invalid configuration info", progname); | 536 message (TRUE, "%s: invalid configuration info", progname); |
486 exit (EXIT_FAILURE); | 537 exit (EXIT_FAILURE); |
487 } | 538 } |
488 | 539 |
489 server->sin_family = AF_INET; | 540 server->sin_family = AF_INET; |
490 server->sin_addr.s_addr = inet_addr (dotted); | 541 server->sin_addr.s_addr = inet_addr (dotted); |
491 server->sin_port = htons (atoi (port)); | 542 server->sin_port = htons (atoi (port)); |
492 | 543 |
493 if (! fread (authentication, AUTH_KEY_LENGTH, 1, config)) | 544 if (! fread (authentication, AUTH_KEY_LENGTH, 1, config)) |
494 { | 545 { |
495 fprintf (stderr, "%s: cannot read authentication info", progname); | 546 message (TRUE, "%s: cannot read authentication info", progname); |
496 exit (EXIT_FAILURE); | 547 exit (EXIT_FAILURE); |
497 } | 548 } |
498 | 549 |
499 fclose (config); | 550 fclose (config); |
500 | 551 |
535 | 586 |
536 if (! get_server_config (&server, auth_string)) | 587 if (! get_server_config (&server, auth_string)) |
537 return INVALID_SOCKET; | 588 return INVALID_SOCKET; |
538 | 589 |
539 if (server.sin_addr.s_addr != inet_addr ("127.0.0.1")) | 590 if (server.sin_addr.s_addr != inet_addr ("127.0.0.1")) |
540 fprintf (stderr, "%s: connected to remote socket at %s\n", | 591 message (TRUE, "%s: connected to remote socket at %s\n", |
541 progname, inet_ntoa (server.sin_addr)); | 592 progname, inet_ntoa (server.sin_addr)); |
542 | 593 |
543 /* | 594 /* |
544 * Open up an AF_INET socket | 595 * Open up an AF_INET socket |
545 */ | 596 */ |
546 if ((s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) | 597 if ((s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) |
547 { | 598 { |
548 fprintf (stderr, "%s: ", progname); | 599 message (TRUE, "%s: socket: %s\n", progname, strerror (errno)); |
549 perror ("socket"); | |
550 return INVALID_SOCKET; | 600 return INVALID_SOCKET; |
551 } | 601 } |
552 | 602 |
553 /* | 603 /* |
554 * Set up the socket | 604 * Set up the socket |
555 */ | 605 */ |
556 if (connect (s, (struct sockaddr *) &server, sizeof server) < 0) | 606 if (connect (s, (struct sockaddr *) &server, sizeof server) < 0) |
557 { | 607 { |
558 fprintf (stderr, "%s: ", progname); | 608 message (TRUE, "%s: connect: %s\n", progname, strerror (errno)); |
559 perror ("connect"); | |
560 return INVALID_SOCKET; | 609 return INVALID_SOCKET; |
561 } | 610 } |
562 | 611 |
563 setsockopt (s, SOL_SOCKET, SO_LINGER, (char *) &l_arg, sizeof l_arg); | 612 setsockopt (s, SOL_SOCKET, SO_LINGER, (char *) &l_arg, sizeof l_arg); |
564 | 613 |
606 * Open up an AF_UNIX socket in this person's home directory | 655 * Open up an AF_UNIX socket in this person's home directory |
607 */ | 656 */ |
608 | 657 |
609 if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) | 658 if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) |
610 { | 659 { |
611 fprintf (stderr, "%s: ", progname); | 660 message (TRUE, "%s: socket: %s\n", progname, strerror (errno)); |
612 perror ("socket"); | |
613 return INVALID_SOCKET; | 661 return INVALID_SOCKET; |
614 } | 662 } |
615 | 663 |
616 server.sun_family = AF_UNIX; | 664 server.sun_family = AF_UNIX; |
617 | 665 |
637 | 685 |
638 if (strlen (socket_name) < sizeof (server.sun_path)) | 686 if (strlen (socket_name) < sizeof (server.sun_path)) |
639 strcpy (server.sun_path, socket_name); | 687 strcpy (server.sun_path, socket_name); |
640 else | 688 else |
641 { | 689 { |
642 fprintf (stderr, "%s: socket-name %s too long", | 690 message (TRUE, "%s: socket-name %s too long", |
643 progname, socket_name); | 691 progname, socket_name); |
644 exit (EXIT_FAILURE); | 692 exit (EXIT_FAILURE); |
645 } | 693 } |
646 | 694 |
647 /* See if the socket exists, and if it's owned by us. */ | 695 /* See if the socket exists, and if it's owned by us. */ |
672 | 720 |
673 if (strlen (socket_name) < sizeof (server.sun_path)) | 721 if (strlen (socket_name) < sizeof (server.sun_path)) |
674 strcpy (server.sun_path, socket_name); | 722 strcpy (server.sun_path, socket_name); |
675 else | 723 else |
676 { | 724 { |
677 fprintf (stderr, "%s: socket-name %s too long", | 725 message (TRUE, "%s: socket-name %s too long", |
678 progname, socket_name); | 726 progname, socket_name); |
679 exit (EXIT_FAILURE); | 727 exit (EXIT_FAILURE); |
680 } | 728 } |
681 | 729 |
682 sock_status = socket_status (server.sun_path); | 730 sock_status = socket_status (server.sun_path); |
692 case 1: | 740 case 1: |
693 /* There's a socket, but it isn't owned by us. This is OK if | 741 /* There's a socket, but it isn't owned by us. This is OK if |
694 we are root. */ | 742 we are root. */ |
695 if (0 != geteuid ()) | 743 if (0 != geteuid ()) |
696 { | 744 { |
697 fprintf (stderr, "%s: Invalid socket owner\n", progname); | 745 message (TRUE, "%s: Invalid socket owner\n", progname); |
698 return INVALID_SOCKET; | 746 return INVALID_SOCKET; |
699 } | 747 } |
700 break; | 748 break; |
701 | 749 |
702 case 2: | 750 case 2: |
703 /* `stat' failed */ | 751 /* `stat' failed */ |
704 if (saved_errno == ENOENT) | 752 if (saved_errno == ENOENT) |
705 fprintf (stderr, | 753 message (TRUE, |
706 "%s: can't find socket; have you started the server?\n\ | 754 "%s: can't find socket; have you started the server?\n\ |
707 To start the server in Emacs, type \"M-x server-start\".\n", | 755 To start the server in Emacs, type \"M-x server-start\".\n", |
708 progname); | 756 progname); |
709 else | 757 else |
710 fprintf (stderr, "%s: can't stat %s: %s\n", | 758 message (TRUE, "%s: can't stat %s: %s\n", |
711 progname, server.sun_path, strerror (saved_errno)); | 759 progname, server.sun_path, strerror (saved_errno)); |
712 return INVALID_SOCKET; | 760 return INVALID_SOCKET; |
713 } | 761 } |
714 } | 762 } |
715 | 763 |
716 if (connect (s, (struct sockaddr *) &server, strlen (server.sun_path) + 2) | 764 if (connect (s, (struct sockaddr *) &server, strlen (server.sun_path) + 2) |
717 < 0) | 765 < 0) |
718 { | 766 { |
719 fprintf (stderr, "%s: ", progname); | 767 message (TRUE, "%s: connect: %s\n", progname, strerror (errno)); |
720 perror ("connect"); | |
721 return INVALID_SOCKET; | 768 return INVALID_SOCKET; |
722 } | 769 } |
723 | 770 |
724 return s; | 771 return s; |
725 } | 772 } |
738 { | 785 { |
739 s = set_local_socket (); | 786 s = set_local_socket (); |
740 if ((s != INVALID_SOCKET) || alternate_editor) | 787 if ((s != INVALID_SOCKET) || alternate_editor) |
741 return s; | 788 return s; |
742 | 789 |
743 fprintf (stderr, "%s: error accessing socket \"%s\"", | 790 message (TRUE, "%s: error accessing socket \"%s\"", |
744 progname, socket_name); | 791 progname, socket_name); |
745 exit (EXIT_FAILURE); | 792 exit (EXIT_FAILURE); |
746 } | 793 } |
747 #endif | 794 #endif |
748 | 795 |
754 { | 801 { |
755 s = set_tcp_socket (); | 802 s = set_tcp_socket (); |
756 if ((s != INVALID_SOCKET) || alternate_editor) | 803 if ((s != INVALID_SOCKET) || alternate_editor) |
757 return s; | 804 return s; |
758 | 805 |
759 fprintf (stderr, "%s: error accessing server file \"%s\"", | 806 message (TRUE, "%s: error accessing server file \"%s\"", |
760 progname, server_file); | 807 progname, server_file); |
761 exit (EXIT_FAILURE); | 808 exit (EXIT_FAILURE); |
762 } | 809 } |
763 | 810 |
764 #ifndef NO_SOCKETS_IN_FILE_SYSTEM | 811 #ifndef NO_SOCKETS_IN_FILE_SYSTEM |
773 s = set_tcp_socket (); | 820 s = set_tcp_socket (); |
774 if ((s != INVALID_SOCKET) || alternate_editor) | 821 if ((s != INVALID_SOCKET) || alternate_editor) |
775 return s; | 822 return s; |
776 | 823 |
777 /* No implicit or explicit socket, and no alternate editor. */ | 824 /* No implicit or explicit socket, and no alternate editor. */ |
778 fprintf (stderr, "%s: No socket or alternate editor. Please use:\n\n" | 825 message (TRUE, "%s: No socket or alternate editor. Please use:\n\n" |
779 #ifndef NO_SOCKETS_IN_FILE_SYSTEM | 826 #ifndef NO_SOCKETS_IN_FILE_SYSTEM |
780 "\t--socket-name\n" | 827 "\t--socket-name\n" |
781 #endif | 828 #endif |
782 "\t--server-file (or environment variable EMACS_SERVER_FILE)\n\ | 829 "\t--server-file (or environment variable EMACS_SERVER_FILE)\n\ |
783 \t--alternate-editor (or environment variable ALTERNATE_EDITOR)\n", | 830 \t--alternate-editor (or environment variable ALTERNATE_EDITOR)\n", |
800 /* Process options. */ | 847 /* Process options. */ |
801 decode_options (argc, argv); | 848 decode_options (argc, argv); |
802 | 849 |
803 if ((argc - optind < 1) && !eval) | 850 if ((argc - optind < 1) && !eval) |
804 { | 851 { |
805 fprintf (stderr, "%s: file name or argument required\n", progname); | 852 message (TRUE, "%s: file name or argument required\nTry `%s --help' for more information\n", |
806 fprintf (stderr, "Try `%s --help' for more information\n", progname); | 853 progname, progname); |
807 exit (EXIT_FAILURE); | 854 exit (EXIT_FAILURE); |
808 } | 855 } |
809 | 856 |
810 if ((s = set_socket ()) == INVALID_SOCKET) | 857 if ((s = set_socket ()) == INVALID_SOCKET) |
811 fail (argc, argv); | 858 fail (argc, argv); |
817 #endif | 864 #endif |
818 if (cwd == 0) | 865 if (cwd == 0) |
819 { | 866 { |
820 /* getwd puts message in STRING if it fails. */ | 867 /* getwd puts message in STRING if it fails. */ |
821 #ifdef HAVE_GETCWD | 868 #ifdef HAVE_GETCWD |
822 fprintf (stderr, "%s: %s (%s)\n", progname, | 869 message (TRUE, "%s: %s (%s)\n", progname, |
823 "Cannot get current working directory", strerror (errno)); | 870 "Cannot get current working directory", strerror (errno)); |
824 #else | 871 #else |
825 fprintf (stderr, "%s: %s (%s)\n", progname, string, strerror (errno)); | 872 message (TRUE, "%s: %s (%s)\n", progname, string, strerror (errno)); |
826 #endif | 873 #endif |
827 fail (argc, argv); | 874 fail (argc, argv); |
828 } | 875 } |
829 | 876 |
830 if (nowait) | 877 if (nowait) |