aboutsummaryrefslogtreecommitdiffstats
path: root/lib-src
diff options
context:
space:
mode:
authorKaroly Lorentey2003-12-26 04:24:54 +0000
committerKaroly Lorentey2003-12-26 04:24:54 +0000
commit9628b8878f46b2b7eeeb4f272d20f2e64de19f4a (patch)
treecfccb4da4a6b898780d3bc9856b377fd5d85e4e6 /lib-src
parent4f0359deff8eb9ec9ed95e75d77a0dd59f39428c (diff)
downloademacs-9628b8878f46b2b7eeeb4f272d20f2e64de19f4a.tar.gz
emacs-9628b8878f46b2b7eeeb4f272d20f2e64de19f4a.zip
lib-src/emacsclient.c: Implemented --here option (open a new Emacs tty). Needs more work.
(here): New variable. (decode_options): Use it. (ec_get_tty, ec_set_tty, init_tty, window_change, hang_up_signal): New functions. (window_change_signal, init_signals, reset_tty, init_pty, copy_from_to): Ditto. (pty_conversation): Ditto. (main): Use them. (master, pty_name, old_tty, tty, old_tty_valid, tty_erase_char): New variables. (flow_control, meta_key, _sobuf, in_conversation, quit_conversation): Ditto. lisp/server.el (server-process-filter): Added support for opening a new terminal frame. dispextern.h (get_frame_size): Renamed to get_tty_size, added tty_output parameter. dispnew.c (Fredraw_frame): fflush the current terminal instead of stdout. (direct_output_for_insert, direct_output_forward_char, update_frame_1): Ditto. (Fding, bitch_at_user): Ditto. (update_frame_1): Count pending output for current terminal instead of stdout. (window_change_signal): Resize all terminals. (change_frame_size): Don't resize all terminals to the same size. frame.c (Vterminal_frame): Removed. (syms_of_frame): Removed declaration of Vterminal_frame. (make_terminal_frame): Set the top frame of the terminal to the new frame. (Fmake_terminal_frame): Get a new frame size from get_tty_size, don't copy it. (do_switch_frame): Handle terminal frame visibility. (next_frame, prev_frame): Skip over frames on different terminals. frame.h (Vterminal_frame): Removed. keyboard.c (input_fd): Removed. (read_avail_input): Removed first argument from read_socket_hook. Try to read from each available tty, until one succeeds. (Fsuspend_emacs): Don't suspend if there are multiple terminals. lisp.h (get_frame_size): Removed superflous declaration. xterm.c (Xtread_socket): Removed first parameter. macterm.h (XTread_socket): Ditto. w32inevt.c (w32_console_read_socket): Ditto. w32term.c (w32_read_socket): Ditto. sysdep.c (input_fd): Removed. (change_input_fd): Removed. (discard_tty_input): Discard pending input on _all_ input descriptors. (stuff_char, tabs_safe_p): Use current terminal instead of input_fd. (init_baud_rate, request_sigio, unrequest_sigio): Ditto. (init_sys_modes, reset_sys_modes): Ditto. (narrow_foreground_group, widen_foreground_group): Use stdin. (init_sys_modes, reset_sys_modes): otty parameter renamed to tty_out. (get_frame_size): Renamed to get_tty_size, added tty_out parameter. term.c (read_socket_hook): Removed first parameter. (clear_end_of_line): Use updating_frame, if possible. (write_glyphs, insert_glyphs, ins_del_lines): Ditto. (term_init): Renamed get_frame_size to get_tty_size. termchar.h (struct tty_output): New entries: top_frame, previous_terminal_frame. termhooks.h (read_socket_hook): Removed first parameter. window.c (init_window_once): Removed reference to Vterminal_frame. xdisp.c (previous_terminal_frame): Moved to struct tty_output. (redisplay_internal): Updated to use previous_terminal_frame in tty_output. Allow for simultaneous refresh of multiple ttys. git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-5
Diffstat (limited to 'lib-src')
-rw-r--r--lib-src/emacsclient.c581
-rw-r--r--lib-src/pty.c20
-rw-r--r--lib-src/pty.h224
3 files changed, 817 insertions, 8 deletions
diff --git a/lib-src/emacsclient.c b/lib-src/emacsclient.c
index aafc531ac5b..2f0f45e1f59 100644
--- a/lib-src/emacsclient.c
+++ b/lib-src/emacsclient.c
@@ -41,6 +41,54 @@ Boston, MA 02111-1307, USA. */
41# include <pwd.h> 41# include <pwd.h>
42#endif /* not VMS */ 42#endif /* not VMS */
43 43
44
45/****************************************/
46
47#include <errno.h>
48#include <signal.h>
49
50#ifndef INCLUDED_FCNTL
51#define INCLUDED_FCNTL
52#include <fcntl.h>
53#endif
54
55#ifdef HAVE_TERMIOS
56#ifndef NO_TERMIO
57#include <termio.h>
58#endif
59#include <termios.h>
60#endif /* not HAVE_TERMIOS */
61
62#ifdef __GNU_LIBRARY__
63#include <sys/ioctl.h>
64#include <termios.h>
65#endif
66
67#if (defined (POSIX) || defined (NEED_UNISTD_H)) && defined (HAVE_UNISTD_H)
68#include <unistd.h>
69#endif
70
71
72
73/* Try to establish the correct character to disable terminal functions
74 in a system-independent manner. Note that USG (at least) define
75 _POSIX_VDISABLE as 0! */
76
77#ifdef _POSIX_VDISABLE
78#define CDISABLE _POSIX_VDISABLE
79#else /* not _POSIX_VDISABLE */
80#ifdef CDEL
81#undef CDISABLE
82#define CDISABLE CDEL
83#else /* not CDEL */
84#define CDISABLE 255
85#endif /* not CDEL */
86#endif /* not _POSIX_VDISABLE */
87
88
89
90/****************************************/
91
44char *getenv (), *getwd (); 92char *getenv (), *getwd ();
45char *getcwd (); 93char *getcwd ();
46 94
@@ -63,6 +111,9 @@ int eval = 0;
63/* The display on which Emacs should work. --display. */ 111/* The display on which Emacs should work. --display. */
64char *display = NULL; 112char *display = NULL;
65 113
114/* Nonzero means open a new Emacs frame on the current terminal. */
115int here = 0;
116
66/* If non-NULL, the name of an editor to fallback to if the server 117/* If non-NULL, the name of an editor to fallback to if the server
67 is not running. --alternate-editor. */ 118 is not running. --alternate-editor. */
68const char * alternate_editor = NULL; 119const char * alternate_editor = NULL;
@@ -78,6 +129,7 @@ struct option longopts[] =
78 { "eval", no_argument, NULL, 'e' }, 129 { "eval", no_argument, NULL, 'e' },
79 { "help", no_argument, NULL, 'H' }, 130 { "help", no_argument, NULL, 'H' },
80 { "version", no_argument, NULL, 'V' }, 131 { "version", no_argument, NULL, 'V' },
132 { "here", no_argument, NULL, 'h' },
81 { "alternate-editor", required_argument, NULL, 'a' }, 133 { "alternate-editor", required_argument, NULL, 'a' },
82 { "socket-name", required_argument, NULL, 's' }, 134 { "socket-name", required_argument, NULL, 's' },
83 { "display", required_argument, NULL, 'd' }, 135 { "display", required_argument, NULL, 'd' },
@@ -95,7 +147,7 @@ decode_options (argc, argv)
95 while (1) 147 while (1)
96 { 148 {
97 int opt = getopt_long (argc, argv, 149 int opt = getopt_long (argc, argv,
98 "VHnea:s:d:", longopts, 0); 150 "VHnea:s:d:h", longopts, 0);
99 151
100 if (opt == EOF) 152 if (opt == EOF)
101 break; 153 break;
@@ -134,6 +186,10 @@ decode_options (argc, argv)
134 exit (0); 186 exit (0);
135 break; 187 break;
136 188
189 case 'h':
190 here = 1;
191 break;
192
137 case 'H': 193 case 'H':
138 print_help_and_exit (); 194 print_help_and_exit ();
139 break; 195 break;
@@ -144,6 +200,12 @@ decode_options (argc, argv)
144 break; 200 break;
145 } 201 }
146 } 202 }
203
204 if (here) {
205 nowait = 0;
206 display = 0;
207 }
208
147} 209}
148 210
149void 211void
@@ -157,6 +219,7 @@ Every FILE can be either just a FILENAME or [+LINE[:COLUMN]] FILENAME.\n\
157The following OPTIONS are accepted:\n\ 219The following OPTIONS are accepted:\n\
158-V, --version Just print a version info and return\n\ 220-V, --version Just print a version info and return\n\
159-H, --help Print this usage information message\n\ 221-H, --help Print this usage information message\n\
222-h, --here Open a new Emacs frame on the current terminal\n\
160-n, --no-wait Don't wait for the server to return\n\ 223-n, --no-wait Don't wait for the server to return\n\
161-e, --eval Evaluate the FILE arguments as ELisp expressions\n\ 224-e, --eval Evaluate the FILE arguments as ELisp expressions\n\
162-d, --display=DISPLAY Visit the file in the given display\n\ 225-d, --display=DISPLAY Visit the file in the given display\n\
@@ -247,6 +310,455 @@ fail (argc, argv)
247 } 310 }
248} 311}
249 312
313
314#ifdef HAVE_TERMIOS
315
316/* Adapted from emacs_get_tty() in sysdep.c. */
317int
318ec_get_tty (int fd, struct termios *settings)
319{
320 bzero (settings, sizeof (struct termios));
321 if (tcgetattr (fd, settings) < 0)
322 return -1;
323 return 0;
324}
325
326/* Adapted from emacs_set_tty() in sysdep.c. */
327int
328ec_set_tty (int fd, struct termios *settings, int flushp)
329{
330 /* Set the primary parameters - baud rate, character size, etcetera. */
331
332 int i;
333 /* We have those nifty POSIX tcmumbleattr functions.
334 William J. Smith <wjs@wiis.wang.com> writes:
335 "POSIX 1003.1 defines tcsetattr to return success if it was
336 able to perform any of the requested actions, even if some
337 of the requested actions could not be performed.
338 We must read settings back to ensure tty setup properly.
339 AIX requires this to keep tty from hanging occasionally." */
340 /* This make sure that we don't loop indefinitely in here. */
341 for (i = 0 ; i < 10 ; i++)
342 if (tcsetattr (fd, flushp ? TCSAFLUSH : TCSADRAIN, settings) < 0)
343 {
344 if (errno == EINTR)
345 continue;
346 else
347 return -1;
348 }
349 else
350 {
351 struct termios new;
352
353 bzero (&new, sizeof (new));
354 /* Get the current settings, and see if they're what we asked for. */
355 tcgetattr (fd, &new);
356 /* We cannot use memcmp on the whole structure here because under
357 * aix386 the termios structure has some reserved field that may
358 * not be filled in.
359 */
360 if ( new.c_iflag == settings->c_iflag
361 && new.c_oflag == settings->c_oflag
362 && new.c_cflag == settings->c_cflag
363 && new.c_lflag == settings->c_lflag
364 && memcmp (new.c_cc, settings->c_cc, NCCS) == 0)
365 break;
366 else
367 continue;
368 }
369 return 0;
370}
371
372int master;
373char *pty_name;
374
375struct termios old_tty;
376struct termios tty;
377int old_tty_valid;
378
379int tty_erase_char;
380int flow_control = 0;
381int meta_key = 0;
382char _sobuf[BUFSIZ];
383
384/* Adapted from init_sys_modes() in sysdep.c. */
385int
386init_tty ()
387{
388 if (! isatty (0))
389 {
390 fprintf (stderr, "%s: Input is not a terminal", "init_tty");
391 return 0;
392 }
393
394 ec_get_tty (0, &old_tty);
395 old_tty_valid = 1;
396 tty = old_tty;
397
398 tty_erase_char = old_tty.c_cc[VERASE];
399
400 tty.c_iflag |= (IGNBRK); /* Ignore break condition */
401 tty.c_iflag &= ~ICRNL; /* Disable map of CR to NL on input */
402#ifdef INLCR
403 tty.c_iflag &= ~INLCR; /* Disable map of NL to CR on input */
404#endif
405#ifdef ISTRIP
406 tty.c_iflag &= ~ISTRIP; /* don't strip 8th bit on input */
407#endif
408 tty.c_lflag &= ~ECHO; /* Disable echo */
409 tty.c_lflag &= ~ICANON; /* Disable erase/kill processing */
410#ifdef IEXTEN
411 tty.c_lflag &= ~IEXTEN; /* Disable other editing characters. */
412#endif
413 tty.c_lflag |= ISIG; /* Enable signals */
414 if (flow_control)
415 {
416 tty.c_iflag |= IXON; /* Enable start/stop output control */
417#ifdef IXANY
418 tty.c_iflag &= ~IXANY;
419#endif /* IXANY */
420 }
421 else
422 tty.c_iflag &= ~IXON; /* Disable start/stop output control */
423 tty.c_oflag &= ~ONLCR; /* Disable map of NL to CR-NL
424 on output */
425 tty.c_oflag &= ~TAB3; /* Disable tab expansion */
426#ifdef CS8
427 if (meta_key)
428 {
429 tty.c_cflag |= CS8; /* allow 8th bit on input */
430 tty.c_cflag &= ~PARENB; /* Don't check parity */
431 }
432#endif
433 tty.c_cc[VINTR] = CDISABLE;
434 tty.c_cc[VQUIT] = CDISABLE;
435 tty.c_cc[VMIN] = 1; /* Input should wait for at least 1 char */
436 tty.c_cc[VTIME] = 0; /* no matter how long that takes. */
437#ifdef VSWTCH
438 tty.c_cc[VSWTCH] = CDISABLE; /* Turn off shell layering use of C-z */
439#endif
440
441#ifdef VSUSP
442 tty.c_cc[VSUSP] = CDISABLE; /* Turn off mips handling of C-z. */
443#endif /* VSUSP */
444#ifdef V_DSUSP
445 tty.c_cc[V_DSUSP] = CDISABLE; /* Turn off mips handling of C-y. */
446#endif /* V_DSUSP */
447#ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP. */
448 tty.c_cc[VDSUSP] = CDISABLE;
449#endif /* VDSUSP */
450#ifdef VLNEXT
451 tty.c_cc[VLNEXT] = CDISABLE;
452#endif /* VLNEXT */
453#ifdef VREPRINT
454 tty.c_cc[VREPRINT] = CDISABLE;
455#endif /* VREPRINT */
456#ifdef VWERASE
457 tty.c_cc[VWERASE] = CDISABLE;
458#endif /* VWERASE */
459#ifdef VDISCARD
460 tty.c_cc[VDISCARD] = CDISABLE;
461#endif /* VDISCARD */
462
463 if (flow_control)
464 {
465#ifdef VSTART
466 tty.c_cc[VSTART] = '\021';
467#endif /* VSTART */
468#ifdef VSTOP
469 tty.c_cc[VSTOP] = '\023';
470#endif /* VSTOP */
471 }
472 else
473 {
474#ifdef VSTART
475 tty.c_cc[VSTART] = CDISABLE;
476#endif /* VSTART */
477#ifdef VSTOP
478 tty.c_cc[VSTOP] = CDISABLE;
479#endif /* VSTOP */
480 }
481
482#ifdef SET_LINE_DISCIPLINE
483 /* Need to explicitly request TERMIODISC line discipline or
484 Ultrix's termios does not work correctly. */
485 tty.c_line = SET_LINE_DISCIPLINE;
486#endif
487
488#ifdef AIX
489#ifndef IBMR2AIX
490 /* AIX enhanced edit loses NULs, so disable it. */
491 tty.c_line = 0;
492 tty.c_iflag &= ~ASCEDIT;
493#else
494 tty.c_cc[VSTRT] = 255;
495 tty.c_cc[VSTOP] = 255;
496 tty.c_cc[VSUSP] = 255;
497 tty.c_cc[VDSUSP] = 255;
498#endif /* IBMR2AIX */
499 if (flow_control)
500 {
501#ifdef VSTART
502 tty.c_cc[VSTART] = '\021';
503#endif /* VSTART */
504#ifdef VSTOP
505 tty.c_cc[VSTOP] = '\023';
506#endif /* VSTOP */
507 }
508 /* Also, PTY overloads NUL and BREAK.
509 don't ignore break, but don't signal either, so it looks like NUL.
510 This really serves a purpose only if running in an XTERM window
511 or via TELNET or the like, but does no harm elsewhere. */
512 tty.c_iflag &= ~IGNBRK;
513 tty.c_iflag &= ~BRKINT;
514#endif /* AIX */
515
516 ec_set_tty (0, &tty, 0);
517
518 /* This code added to insure that, if flow-control is not to be used,
519 we have an unlocked terminal at the start. */
520
521#ifdef TCXONC
522 if (!flow_control) ioctl (0, TCXONC, 1);
523#endif
524#ifndef APOLLO
525#ifdef TIOCSTART
526 if (!flow_control) ioctl (0, TIOCSTART, 0);
527#endif
528#endif
529
530#if defined (HAVE_TERMIOS) || defined (HPUX9)
531#ifdef TCOON
532 if (!flow_control) tcflow (0, TCOON);
533#endif
534#endif
535
536#ifdef _IOFBF
537 /* This symbol is defined on recent USG systems.
538 Someone says without this call USG won't really buffer the file
539 even with a call to setbuf. */
540 setvbuf (stdout, (char *) _sobuf, _IOFBF, sizeof _sobuf);
541#else
542 setbuf (stdout, (char *) _sobuf);
543#endif
544
545 return 1;
546}
547
548void
549window_change ()
550{
551 int width, height;
552
553#ifdef TIOCGWINSZ
554 {
555 /* BSD-style. */
556 struct winsize size;
557
558 if (ioctl (0, TIOCGWINSZ, &size) == -1)
559 width = height = 0;
560 else
561 {
562 width = size.ws_col;
563 height = size.ws_row;
564 }
565 }
566#else
567#ifdef TIOCGSIZE
568 {
569 /* SunOS - style. */
570 struct ttysize size;
571
572 if (ioctl (0, TIOCGSIZE, &size) == -1)
573 width = height = 0;
574 else
575 {
576 width = size.ts_cols;
577 height = size.ts_lines;
578 }
579 }
580#endif /* not SunOS-style */
581#endif /* not BSD-style */
582
583#ifdef TIOCSWINSZ
584 {
585 /* BSD-style. */
586 struct winsize size;
587 size.ws_row = height;
588 size.ws_col = width;
589
590 ioctl (master, TIOCSWINSZ, &size);
591 }
592#else
593#ifdef TIOCSSIZE
594 {
595 /* SunOS - style. */
596 struct ttysize size;
597 size.ts_lines = height;
598 size.ts_cols = width;
599
600 ioctl (master, TIOCGSIZE, &size);
601 }
602#endif /* not SunOS-style */
603#endif /* not BSD-style */
604}
605
606int in_conversation = 0;
607int quit_conversation = 0;
608
609SIGTYPE
610hang_up_signal (int signalnum)
611{
612 int old_errno = errno;
613
614 if (! in_conversation)
615 return;
616
617 quit_conversation = 1;
618
619 errno = old_errno;
620}
621
622SIGTYPE
623window_change_signal (int signalnum)
624{
625 int old_errno = errno;
626
627 if (! in_conversation)
628 goto end;
629
630 window_change();
631
632 end:
633 signal (SIGWINCH, window_change_signal);
634 errno = old_errno;
635}
636
637int
638init_signals ()
639{
640 /* Set up signal handlers. */
641 signal (SIGWINCH, window_change_signal);
642 signal (SIGHUP, hang_up_signal);
643
644 return 1;
645}
646
647
648
649/* Adapted from reset_sys_modes in sysdep.c. */
650int
651reset_tty ()
652{
653 fflush (stdout);
654#ifdef BSD_SYSTEM
655#ifndef BSD4_1
656 /* Avoid possible loss of output when changing terminal modes. */
657 fsync (fileno (stdout));
658#endif
659#endif
660
661#ifdef F_SETFL
662#ifdef O_NDELAY
663 fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~O_NDELAY);
664#endif
665#endif /* F_SETFL */
666
667 if (old_tty_valid)
668 while (ec_set_tty (0, &old_tty, 0) < 0 && errno == EINTR)
669 ;
670
671 return 1;
672}
673
674
675int
676init_pty ()
677{
678 master = getpt ();
679 if (master < 0)
680 return 0;
681
682 if (grantpt (master) < 0 || unlockpt (master) < 0)
683 goto close_master;
684 pty_name = strdup (ptsname (master));
685 if (! pty_name)
686 goto close_master;
687
688 /* Propagate window size. */
689 window_change ();
690
691 return 1;
692
693 close_master:
694 close (master);
695 return 0;
696}
697
698int
699copy_from_to (int in, int out)
700{
701 static char buf[BUFSIZ];
702 int nread = read (in, &buf, BUFSIZ);
703 if (nread == 0)
704 return 1; /* EOF */
705 else if (nread < 0 && errno != EAGAIN)
706 return 0; /* Error */
707 else if (nread > 0)
708 {
709 int r = 0;
710 int written = 0;
711
712 do {
713 r = write (out, &buf, nread);
714 } while ((r < 0 && errno == EAGAIN)
715 || (r > 0 && (written += r) && written != nread));
716
717 if (r < 0)
718 return 0; /* Error */
719 }
720 return 1;
721}
722
723int
724pty_conversation ()
725{
726 fd_set set;
727
728 in_conversation = 1;
729
730 while (! quit_conversation) {
731 int res;
732
733 FD_ZERO (&set);
734 FD_SET (master, &set);
735 FD_SET (1, &set);
736 res = select (FD_SETSIZE, &set, NULL, NULL, NULL);
737 if (res < 0)
738 {
739 if (errno != EINTR)
740 return 0;
741 }
742 else if (res > 0)
743 {
744 if (FD_ISSET (master, &set))
745 {
746 /* Copy Emacs output to stdout. */
747 if (! copy_from_to (master, 0))
748 return 1;
749 }
750 if (FD_ISSET (1, &set))
751 {
752 /* Forward user input to Emacs. */
753 if (! copy_from_to (1, master))
754 return 1;
755 }
756 }
757 }
758 return 1;
759}
760
761#endif /* HAVE_TERMIOS */
250 762
251 763
252#if !defined (HAVE_SOCKETS) || defined (NO_SOCKETS_IN_FILE_SYSTEM) 764#if !defined (HAVE_SOCKETS) || defined (NO_SOCKETS_IN_FILE_SYSTEM)
@@ -312,7 +824,7 @@ main (argc, argv)
312 /* Process options. */ 824 /* Process options. */
313 decode_options (argc, argv); 825 decode_options (argc, argv);
314 826
315 if ((argc - optind < 1) && !eval) 827 if ((argc - optind < 1) && !eval && !here)
316 { 828 {
317 fprintf (stderr, "%s: file name or argument required\n", progname); 829 fprintf (stderr, "%s: file name or argument required\n", progname);
318 fprintf (stderr, "Try `%s --help' for more information\n", progname); 830 fprintf (stderr, "Try `%s --help' for more information\n", progname);
@@ -484,6 +996,38 @@ To start the server in Emacs, type \"M-x server-start\".\n",
484 fprintf (out, " "); 996 fprintf (out, " ");
485 } 997 }
486 998
999 if (here)
1000 {
1001 if (! init_signals ())
1002 {
1003 fprintf (stderr, "%s: ", argv[0]);
1004 perror ("fdopen");
1005 fail (argc, argv);
1006 }
1007
1008 if (! init_tty ())
1009 {
1010 reset_tty ();
1011 fprintf (stderr, "%s: ", argv[0]);
1012 perror ("fdopen");
1013 fail (argc, argv);
1014 }
1015
1016 if (! init_pty ())
1017 {
1018 reset_tty ();
1019 fprintf (stderr, "%s: ", argv[0]);
1020 perror ("fdopen");
1021 fail (argc, argv);
1022 }
1023
1024 fprintf (out, "-pty ");
1025 quote_file_name (pty_name, out);
1026 fprintf (out, " ");
1027 quote_file_name (getenv("TERM"), out);
1028 fprintf (out, " ");
1029 }
1030
487 if ((argc - optind > 0)) 1031 if ((argc - optind > 0))
488 { 1032 {
489 for (i = optind; i < argc; i++) 1033 for (i = optind; i < argc; i++)
@@ -512,11 +1056,14 @@ To start the server in Emacs, type \"M-x server-start\".\n",
512 } 1056 }
513 else 1057 else
514 { 1058 {
515 while ((str = fgets (string, BUFSIZ, stdin))) 1059 if (!here)
516 { 1060 {
517 quote_file_name (str, out); 1061 while ((str = fgets (string, BUFSIZ, stdin)))
518 } 1062 {
519 fprintf (out, " "); 1063 quote_file_name (str, out);
1064 }
1065 fprintf (out, " ");
1066 }
520 } 1067 }
521 1068
522 fprintf (out, "\n"); 1069 fprintf (out, "\n");
@@ -524,8 +1071,25 @@ To start the server in Emacs, type \"M-x server-start\".\n",
524 1071
525 /* Maybe wait for an answer. */ 1072 /* Maybe wait for an answer. */
526 if (nowait) 1073 if (nowait)
527 return 0; 1074 {
1075 reset_tty ();
1076 return 0;
1077 }
528 1078
1079 if (here)
1080 {
1081 if (! pty_conversation ())
1082 {
1083 reset_tty ();
1084 fprintf (stderr, "%s: ", argv[0]);
1085 perror ("fdopen");
1086 fail (argc, argv);
1087 }
1088 close (master);
1089 reset_tty ();
1090 return 0;
1091 }
1092
529 if (!eval) 1093 if (!eval)
530 { 1094 {
531 printf ("Waiting for Emacs..."); 1095 printf ("Waiting for Emacs...");
@@ -546,6 +1110,7 @@ To start the server in Emacs, type \"M-x server-start\".\n",
546 printf ("\n"); 1110 printf ("\n");
547 fflush (stdout); 1111 fflush (stdout);
548 1112
1113 reset_tty ();
549 return 0; 1114 return 0;
550} 1115}
551 1116
diff --git a/lib-src/pty.c b/lib-src/pty.c
new file mode 100644
index 00000000000..05c54c63ff5
--- /dev/null
+++ b/lib-src/pty.c
@@ -0,0 +1,20 @@
1/* Terminal initialization for emacsclient.
2 Copyright (C) 2003 Free Software Foundation, Inc.
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs; see the file COPYING. If not, write to
18the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
20
diff --git a/lib-src/pty.h b/lib-src/pty.h
new file mode 100644
index 00000000000..d8f6318176a
--- /dev/null
+++ b/lib-src/pty.h
@@ -0,0 +1,224 @@
1/* Terminal initialization for emacsclient.
2 Copyright (C) 2003 Free Software Foundation, Inc.
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs; see the file COPYING. If not, write to
18the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
20
21/* Adapted from systty.h */
22
23
24#ifdef HAVE_TERMIOS
25#define HAVE_TCATTR
26#endif
27
28
29/* Include the proper files. */
30#ifdef HAVE_TERMIO
31#ifdef __DGUX
32#include <sys/ioctl.h>
33#endif
34#ifndef NO_TERMIO
35#include <termio.h>
36#endif /* not NO_TERMIO */
37#ifndef INCLUDED_FCNTL
38#define INCLUDED_FCNTL
39#include <fcntl.h>
40#endif
41#else /* not HAVE_TERMIO */
42#ifdef HAVE_TERMIOS
43#if defined(_AIX) && defined(_I386)
44#include <termios.h> /* termios.h needs to be before termio.h */
45#include <termio.h>
46#else /* not (_AIX && _I386) */
47#ifndef NO_TERMIO
48#include <termio.h>
49#endif
50#include <termios.h>
51#endif /* not (_AIX && _I386) */
52#define INCLUDED_FCNTL
53#include <fcntl.h>
54#else /* neither HAVE_TERMIO nor HAVE_TERMIOS */
55#ifndef VMS
56#ifndef DOS_NT
57#include <sgtty.h>
58#endif /* not DOS_NT */
59#else /* VMS */
60#include <descrip.h>
61static struct iosb
62{
63 short status;
64 short offset;
65 short termlen;
66 short term;
67} input_iosb;
68
69extern int waiting_for_ast;
70extern int stop_input;
71extern int input_ef;
72extern int timer_ef;
73extern int process_ef;
74extern int input_eflist;
75extern int timer_eflist;
76
77static $DESCRIPTOR (input_dsc, "TT");
78static int terminator_mask[2] = { 0, 0 };
79
80static struct sensemode {
81 short status;
82 unsigned char xmit_baud;
83 unsigned char rcv_baud;
84 unsigned char crfill;
85 unsigned char lffill;
86 unsigned char parity;
87 unsigned char unused;
88 char class;
89 char type;
90 short scr_wid;
91 unsigned long tt_char : 24, scr_len : 8;
92 unsigned long tt2_char;
93} sensemode_iosb;
94#endif /* VMS */
95#endif /* not HAVE_TERMIOS */
96#endif /* not HAVE_TERMIO */
97
98#ifdef __GNU_LIBRARY__
99#include <sys/ioctl.h>
100#include <termios.h>
101#endif
102
103#ifdef AIXHFT
104/* Get files for keyboard remapping */
105#define HFNKEYS 2
106#include <sys/hft.h>
107#include <sys/devinfo.h>
108#endif
109
110/* Get rid of LLITOUT in 4.1, since it is said to stimulate kernel bugs. */
111#ifdef BSD4_1
112#undef LLITOUT
113#define LLITOUT 0
114#endif /* 4.1 */
115
116#ifdef NEED_BSDTTY
117#include <sys/bsdtty.h>
118#endif
119
120#if defined (HPUX) && defined (HAVE_PTYS)
121#include <sys/ptyio.h>
122#endif
123
124#ifdef AIX
125#include <sys/pty.h>
126#endif /* AIX */
127
128#if (defined (POSIX) || defined (NEED_UNISTD_H)) && defined (HAVE_UNISTD_H)
129#include <unistd.h>
130#endif
131
132#ifdef SYSV_PTYS
133#include <sys/types.h>
134#include <sys/tty.h>
135#ifdef titan
136#include <sys/ttyhw.h>
137#include <sys/stream.h>
138#endif
139#ifndef NO_PTY_H
140#include <sys/pty.h>
141#endif
142#endif
143
144/* saka@pfu.fujitsu.co.JP writes:
145 FASYNC defined in this file. But, FASYNC don't working.
146 so no problem, because unrequest_sigio only need. */
147#if defined (pfa)
148#include <sys/file.h>
149#endif
150
151
152/* Special cases - inhibiting the use of certain features. */
153
154#ifdef APOLLO
155#undef TIOCSTART
156#endif
157
158#ifdef XENIX
159#undef TIOCGETC /* Avoid confusing some conditionals that test this. */
160#endif
161
162#ifdef BROKEN_TIOCGETC
163#undef TIOCGETC /* Avoid confusing some conditionals that test this. */
164#endif
165
166/* UNIPLUS systems may have FIONREAD. */
167#ifdef UNIPLUS
168#include <sys.ioctl.h>
169#endif
170
171/* Allow m- file to inhibit use of FIONREAD. */
172#ifdef BROKEN_FIONREAD
173#undef FIONREAD
174#undef ASYNC
175#endif
176
177/* Interrupt input is not used if there is no FIONREAD. */
178#ifndef FIONREAD
179#undef SIGIO
180#endif
181
182/* On TERMIOS systems, the tcmumbleattr calls take care of these
183 parameters, and it's a bad idea to use them (on AIX, it makes the
184 tty hang for a long time). */
185#if defined (TIOCGLTC) && !defined (HAVE_TERMIOS)
186#define HAVE_LTCHARS
187#endif
188
189#if defined (TIOCGETC) && !defined (HAVE_TERMIOS)
190#define HAVE_TCHARS
191#endif
192
193
194/* Try to establish the correct character to disable terminal functions
195 in a system-independent manner. Note that USG (at least) define
196 _POSIX_VDISABLE as 0! */
197
198#ifdef _POSIX_VDISABLE
199#define CDISABLE _POSIX_VDISABLE
200#else /* not _POSIX_VDISABLE */
201#ifdef CDEL
202#undef CDISABLE
203#define CDISABLE CDEL
204#else /* not CDEL */
205#define CDISABLE 255
206#endif /* not CDEL */
207#endif /* not _POSIX_VDISABLE */
208
209/* Get the number of characters queued for output. */
210
211/* EMACS_OUTQSIZE(FD, int *SIZE) stores the number of characters
212 queued for output to the terminal FD in *SIZE, if FD is a tty.
213 Returns -1 if there was an error (i.e. FD is not a tty), 0
214 otherwise. */
215#ifdef TIOCOUTQ
216#define EMACS_OUTQSIZE(fd, size) (ioctl ((fd), TIOCOUTQ, (size)))
217#endif
218
219#ifdef HAVE_TERMIO
220#ifdef TCOUTQ
221#undef EMACS_OUTQSIZE
222#define EMACS_OUTQSIZE(fd, size) (ioctl ((fd), TCOUTQ, (size)))
223#endif
224#endif