aboutsummaryrefslogtreecommitdiffstats
path: root/lib-src
diff options
context:
space:
mode:
authorKaroly Lorentey2004-02-28 01:23:39 +0000
committerKaroly Lorentey2004-02-28 01:23:39 +0000
commit0b0d3e0bcefdde298893aaad2e816e1503cef222 (patch)
tree439342044857514ad784de0470f5546eb9c3ef9a /lib-src
parent2fc0cf2aefa777e5fe48596e2d43774b28051931 (diff)
downloademacs-0b0d3e0bcefdde298893aaad2e816e1503cef222.tar.gz
emacs-0b0d3e0bcefdde298893aaad2e816e1503cef222.zip
Implemented suspending of emacsclient frames.
lib-src/emacsclient.c (quote_file_name): Renamed to quote_argument. (unquote_argument, handle_sigcont, handle_sigtstp): New functions. (out, in): New global variables for communicating with the Emacs process. (init_signals): Set up handlers for SIGCONT, SIGTSTP and SIGTTOU. (main): Changed out and in to global variables. Prepend `-eval' or '-file' to each argument. Use fsync to force sending the strings to Emacs. Removed obsolete -bad-version code. Support the -suspend command. Cleaned up newline handling. lisp/frame.el (suspend-frame): New function. Substitute key definition of suspend-emacs with suspend-frame. lisp/server.el (server-log): Cosmetic change in log format. (server-handle-delete-tty, server-handle-delete-frame): Added logging. (server-handle-suspend-tty, server-quote-arg): New functions. (server-start): Install server-handle-suspend-tty. (server-process-filter): Reorganized source code for clarity. Implemented -resume, -suspend and -ignore commands. lisp/term/x-win.el (x-initialize-window-system): Don't change the binding of C-z. src/cm.c: Replaced TTY_INPUT, TTY_OUTPUT, TTY_TERMSCRIPT calls with their macro expansion. src/dispnew.c: Ditto. src/frame.c: Ditto. src/keyboard.c: Ditto. src/sysdep.c: Ditto. src/keyboard.c (tty_read_avail_input): Don't read if the terminal is suspended. src/sysdep.c (discard_tty_input, init_sys_modes, reset_sys_modes): Ditto. src/term.c (tty_set_terminal_modes, tty_reset_terminal_modes): Ditto. src/term.c (Vsuspend_tty_functions, Vresume_tty_functions): New hooks. (syms_of_term): Defvar them. (term_init): Don't allow opening a new frame on a suspended tty device. (Fsuspend_tty, Fresume_tty): New functions. (syms_of_term): Defsubr them. src/termchar.c (struct tty_display_info): Update documentation of input and output. (TTY_INPUT, TTY_OUTPUT, TTY_TERMSCRIPT): Removed. git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-105
Diffstat (limited to 'lib-src')
-rw-r--r--lib-src/emacsclient.c244
1 files changed, 183 insertions, 61 deletions
diff --git a/lib-src/emacsclient.c b/lib-src/emacsclient.c
index c1c8ee8f160..79642cbe47e 100644
--- a/lib-src/emacsclient.c
+++ b/lib-src/emacsclient.c
@@ -114,7 +114,7 @@ decode_options (argc, argv)
114 display = getenv ("DISPLAY"); 114 display = getenv ("DISPLAY");
115 if (display && strlen (display) == 0) 115 if (display && strlen (display) == 0)
116 display = NULL; 116 display = NULL;
117 117
118 if (display) 118 if (display)
119 window_system = 1; 119 window_system = 1;
120 else 120 else
@@ -169,7 +169,7 @@ decode_options (argc, argv)
169 window_system = 0; 169 window_system = 0;
170 tty = 0; 170 tty = 0;
171 break; 171 break;
172 172
173 case 'H': 173 case 'H':
174 print_help_and_exit (); 174 print_help_and_exit ();
175 break; 175 break;
@@ -212,19 +212,21 @@ Report bugs to bug-gnu-emacs@gnu.org.\n", progname);
212 exit (0); 212 exit (0);
213} 213}
214 214
215/* In NAME, insert a & before each &, each space, each newline, and 215/* In STR, insert a & before each &, each space, each newline, and
216 any initial -. Change spaces to underscores, too, so that the 216 any initial -. Change spaces to underscores, too, so that the
217 return value never contains a space. */ 217 return value never contains a space.
218
219 Does not change the string. Outputs the result to STREAM. */
218 220
219void 221void
220quote_file_name (name, stream) 222quote_argument (str, stream)
221 char *name; 223 char *str;
222 FILE *stream; 224 FILE *stream;
223{ 225{
224 char *copy = (char *) malloc (strlen (name) * 2 + 1); 226 char *copy = (char *) malloc (strlen (str) * 2 + 1);
225 char *p, *q; 227 char *p, *q;
226 228
227 p = name; 229 p = str;
228 q = copy; 230 q = copy;
229 while (*p) 231 while (*p)
230 { 232 {
@@ -242,7 +244,7 @@ quote_file_name (name, stream)
242 } 244 }
243 else 245 else
244 { 246 {
245 if (*p == '&' || (*p == '-' && p == name)) 247 if (*p == '&' || (*p == '-' && p == str))
246 *q++ = '&'; 248 *q++ = '&';
247 *q++ = *p++; 249 *q++ = *p++;
248 } 250 }
@@ -254,6 +256,41 @@ quote_file_name (name, stream)
254 free (copy); 256 free (copy);
255} 257}
256 258
259
260/* The inverse of quote_argument. Removes quoting in string STR by
261 modifying the string in place. Returns STR. */
262
263char *
264unquote_argument (str)
265 char *str;
266{
267 char *p, *q;
268
269 if (! str)
270 return str;
271
272 p = str;
273 q = str;
274 while (*p)
275 {
276 if (*p == '&')
277 {
278 p++;
279 if (*p == '&')
280 *p = '&';
281 else if (*p == '_')
282 *p = ' ';
283 else if (*p == 'n')
284 *p = '\n';
285 else if (*p == '-')
286 *p = '-';
287 }
288 *q++ = *p++;
289 }
290 *q = 0;
291 return str;
292}
293
257/* Like malloc but get fatal error if memory is exhausted. */ 294/* Like malloc but get fatal error if memory is exhausted. */
258 295
259long * 296long *
@@ -288,8 +325,12 @@ fail (void)
288 } 325 }
289} 326}
290 327
328/* The process id of Emacs. */
291int emacs_pid; 329int emacs_pid;
292 330
331/* File handles for communicating with Emacs. */
332FILE *out, *in;
333
293/* A signal handler that passes the signal to the Emacs process. 334/* A signal handler that passes the signal to the Emacs process.
294 Useful for SIGWINCH. */ 335 Useful for SIGWINCH. */
295 336
@@ -305,8 +346,62 @@ pass_signal_to_emacs (int signalnum)
305 errno = old_errno; 346 errno = old_errno;
306} 347}
307 348
349/* Signal handler for SIGCONT; notify the Emacs process that it can
350 now resume our tty frame. */
351
352SIGTYPE
353handle_sigcont (int signalnum)
354{
355 int old_errno = errno;
356
357 if (tcgetpgrp (1) == getpgrp ())
358 {
359 /* We are in the foreground. */
360 fprintf (out, "-resume \n");
361 fflush (out);
362 fsync (fileno (out));
363 }
364 else
365 {
366 /* We are in the background; cancel the continue. */
367 kill (getpid (), SIGSTOP);
368 }
369 errno = old_errno;
370}
371
372/* Signal handler for SIGTSTP; notify the Emacs process that we are
373 going to sleep. Normally the suspend is initiated by Emacs via
374 server-handle-suspend-tty, but if the server gets out of sync with
375 reality, we may get a SIGTSTP on C-z. Handling this signal and
376 notifying Emacs about it should get things under control again. */
377
378SIGTYPE
379handle_sigtstp (int signalnum)
380{
381 int old_errno = errno;
382 sigset_t set;
383
384 if (out)
385 {
386 fprintf (out, "-suspend \n");
387 fflush (out);
388 fsync (fileno (out));
389 }
390
391 /* Unblock this signal and call the default handler by temprarily
392 changing the handler and resignalling. */
393 sigprocmask (SIG_BLOCK, NULL, &set);
394 sigdelset (&set, signalnum);
395 signal (signalnum, SIG_DFL);
396 kill (getpid (), signalnum);
397 sigprocmask (SIG_SETMASK, &set, NULL); /* Let's the above signal through. */
398 signal (signalnum, handle_sigtstp);
399
400 errno = old_errno;
401}
402
308/* Set up signal handlers before opening a frame on the current tty. */ 403/* Set up signal handlers before opening a frame on the current tty. */
309 404
310void 405void
311init_signals (void) 406init_signals (void)
312{ 407{
@@ -320,6 +415,10 @@ init_signals (void)
320 signal (SIGINT, pass_signal_to_emacs); 415 signal (SIGINT, pass_signal_to_emacs);
321 signal (SIGQUIT, pass_signal_to_emacs); 416 signal (SIGQUIT, pass_signal_to_emacs);
322#endif 417#endif
418
419 signal (SIGCONT, handle_sigcont);
420 signal (SIGTSTP, handle_sigtstp);
421 signal (SIGTTOU, handle_sigtstp);
323} 422}
324 423
325 424
@@ -378,7 +477,7 @@ strprefix (char *prefix, char *string)
378 477
379 if (!string) 478 if (!string)
380 return 0; 479 return 0;
381 480
382 for (i = 0; prefix[i]; i++) 481 for (i = 0; prefix[i]; i++)
383 if (!string[i] || string[i] != prefix[i]) 482 if (!string[i] || string[i] != prefix[i])
384 return 0; 483 return 0;
@@ -391,7 +490,6 @@ main (argc, argv)
391 char **argv; 490 char **argv;
392{ 491{
393 int s, i, needlf = 0; 492 int s, i, needlf = 0;
394 FILE *out, *in;
395 struct sockaddr_un server; 493 struct sockaddr_un server;
396 char *cwd, *str; 494 char *cwd, *str;
397 char string[BUFSIZ]; 495 char string[BUFSIZ];
@@ -427,9 +525,9 @@ main (argc, argv)
427 int sock_status = 0; 525 int sock_status = 0;
428 int default_sock = !socket_name; 526 int default_sock = !socket_name;
429 int saved_errno = 0; 527 int saved_errno = 0;
430 528
431 char *server_name = "server"; 529 char *server_name = "server";
432 530
433 if (socket_name && !index (socket_name, '/') && !index (socket_name, '\\')) 531 if (socket_name && !index (socket_name, '/') && !index (socket_name, '\\'))
434 { /* socket_name is a file name component. */ 532 { /* socket_name is a file name component. */
435 server_name = socket_name; 533 server_name = socket_name;
@@ -571,17 +669,14 @@ To start the server in Emacs, type \"M-x server-start\".\n",
571 669
572 /* First of all, send our version number for verification. */ 670 /* First of all, send our version number for verification. */
573 fprintf (out, "-version %s ", VERSION); 671 fprintf (out, "-version %s ", VERSION);
574 672
575 if (nowait) 673 if (nowait)
576 fprintf (out, "-nowait "); 674 fprintf (out, "-nowait ");
577 675
578 if (eval)
579 fprintf (out, "-eval ");
580
581 if (display) 676 if (display)
582 { 677 {
583 fprintf (out, "-display "); 678 fprintf (out, "-display ");
584 quote_file_name (display, out); 679 quote_argument (display, out);
585 fprintf (out, " "); 680 fprintf (out, " ");
586 } 681 }
587 682
@@ -589,7 +684,7 @@ To start the server in Emacs, type \"M-x server-start\".\n",
589 { 684 {
590 char *tty_name = ttyname (fileno (stdin)); 685 char *tty_name = ttyname (fileno (stdin));
591 char *type = getenv ("TERM"); 686 char *type = getenv ("TERM");
592 687
593 if (! tty_name) 688 if (! tty_name)
594 { 689 {
595 fprintf (stderr, "%s: could not get terminal name\n", progname); 690 fprintf (stderr, "%s: could not get terminal name\n", progname);
@@ -610,44 +705,60 @@ To start the server in Emacs, type \"M-x server-start\".\n",
610 " is not supported\n", progname); 705 " is not supported\n", progname);
611 fail (); 706 fail ();
612 } 707 }
613 708
614 init_signals (); 709 init_signals ();
615 710
616 fprintf (out, "-tty "); 711 fprintf (out, "-tty ");
617 quote_file_name (tty_name, out); 712 quote_argument (tty_name, out);
618 fprintf (out, " "); 713 fprintf (out, " ");
619 quote_file_name (type, out); 714 quote_argument (type, out);
620 fprintf (out, " "); 715 fprintf (out, " ");
621 } 716 }
622 717
623 if (window_system) 718 if (window_system)
624 fprintf (out, "-window-system "); 719 fprintf (out, "-window-system ");
625 720
626 if ((argc - optind > 0)) 721 if ((argc - optind > 0))
627 { 722 {
628 for (i = optind; i < argc; i++) 723 for (i = optind; i < argc; i++)
629 { 724 {
725 int relative = 0;
726
630 if (eval) 727 if (eval)
631 ; /* Don't prepend any cwd or anything like that. */ 728 {
632 else if (*argv[i] == '+') 729 /* Don't prepend any cwd or anything like that. */
633 { 730 fprintf (out, "-eval ");
731 quote_argument (argv[i], out);
732 fprintf (out, " ");
733 continue;
734 }
735
736 if (*argv[i] == '+')
737 {
634 char *p = argv[i] + 1; 738 char *p = argv[i] + 1;
635 while (isdigit ((unsigned char) *p) || *p == ':') p++; 739 while (isdigit ((unsigned char) *p) || *p == ':') p++;
636 if (*p != 0) 740 if (*p == 0)
637 { 741 {
638 quote_file_name (cwd, out); 742 fprintf (out, "-position ");
639 fprintf (out, "/"); 743 quote_argument (argv[i], out);
640 } 744 fprintf (out, " ");
641 } 745 continue;
642 else if (*argv[i] != '/') 746 }
643 { 747 else
644 quote_file_name (cwd, out); 748 relative = 1;
645 fprintf (out, "/"); 749 }
646 } 750 else if (*argv[i] != '/')
647 751 relative = 1;
648 quote_file_name (argv[i], out); 752
649 fprintf (out, " "); 753 fprintf (out, "-file ");
650 } 754 if (relative)
755 {
756 quote_argument (cwd, out);
757 fprintf (out, "/");
758 }
759 quote_argument (argv[i], out);
760 fprintf (out, " ");
761 }
651 } 762 }
652 else 763 else
653 { 764 {
@@ -655,14 +766,19 @@ To start the server in Emacs, type \"M-x server-start\".\n",
655 { 766 {
656 while ((str = fgets (string, BUFSIZ, stdin))) 767 while ((str = fgets (string, BUFSIZ, stdin)))
657 { 768 {
658 quote_file_name (str, out); 769 if (eval)
770 fprintf (out, "-eval ");
771 else
772 fprintf (out, "-file ");
773 quote_argument (str, out);
659 } 774 }
660 fprintf (out, " "); 775 fprintf (out, " ");
661 } 776 }
662 } 777 }
663 778
664 fprintf (out, "\n"); 779 fprintf (out, "\n");
665 fflush (out); 780 fflush (out);
781 fsync (fileno (out));
666 782
667 /* Maybe wait for an answer. */ 783 /* Maybe wait for an answer. */
668 if (nowait) 784 if (nowait)
@@ -676,44 +792,49 @@ To start the server in Emacs, type \"M-x server-start\".\n",
676 needlf = 2; 792 needlf = 2;
677 } 793 }
678 fflush (stdout); 794 fflush (stdout);
795 fsync (1);
679 796
680 /* Now, wait for an answer and print any messages. */ 797 /* Now, wait for an answer and print any messages. */
681 while ((str = fgets (string, BUFSIZ, in))) 798 while ((str = fgets (string, BUFSIZ, in)))
682 { 799 {
800 char *p = str + strlen (str) - 1;
801 while (p > str && *p == '\n')
802 *p-- = 0;
803
683 if (strprefix ("-good-version ", str)) 804 if (strprefix ("-good-version ", str))
684 { 805 {
685 /* OK, we got the green light. */ 806 /* OK, we got the green light. */
686 } 807 }
687 else if (strprefix ("-bad-version ", str))
688 {
689 if (str[strlen (str) - 1] == '\n')
690 str[strlen (str) - 1] = 0;
691
692 fprintf (stderr, "%s: Version mismatch: Emacs is %s, but we are %s\n",
693 argv[0], str + strlen ("-bad-version "), VERSION);
694 fail ();
695 }
696 else if (strprefix ("-emacs-pid ", str)) 808 else if (strprefix ("-emacs-pid ", str))
697 { 809 {
698 emacs_pid = strtol (string + strlen ("-emacs-pid"), NULL, 10); 810 emacs_pid = strtol (string + strlen ("-emacs-pid"), NULL, 10);
699 } 811 }
700 else if (strprefix ("-print ", str)) 812 else if (strprefix ("-print ", str))
701 { 813 {
702 if (needlf == 2) 814 str = unquote_argument (str + strlen ("-print "));
815 if (needlf)
703 printf ("\n"); 816 printf ("\n");
704 printf ("%s", str + strlen ("-print ")); 817 printf ("%s", str);
705 needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n'; 818 needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n';
706 } 819 }
707 else if (strprefix ("-error ", str)) 820 else if (strprefix ("-error ", str))
708 { 821 {
709 if (needlf == 2) 822 str = unquote_argument (str + strlen ("-error "));
823 if (needlf)
824 printf ("\n");
825 printf ("*ERROR*: %s", str);
826 needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n';
827 }
828 else if (strprefix ("-suspend ", str))
829 {
830 if (needlf)
710 printf ("\n"); 831 printf ("\n");
711 printf ("*ERROR*: %s", str + strlen ("-print ")); 832 needlf = 0;
712 needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n'; 833 kill (0, SIGSTOP);
713 } 834 }
714 else 835 else
715 { 836 {
716 if (needlf == 2) 837 if (needlf)
717 printf ("\n"); 838 printf ("\n");
718 printf ("*ERROR*: Unknown message: %s", str); 839 printf ("*ERROR*: Unknown message: %s", str);
719 needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n'; 840 needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n';
@@ -723,6 +844,7 @@ To start the server in Emacs, type \"M-x server-start\".\n",
723 if (needlf) 844 if (needlf)
724 printf ("\n"); 845 printf ("\n");
725 fflush (stdout); 846 fflush (stdout);
847 fsync (1);
726 848
727 return 0; 849 return 0;
728} 850}