comparison src/keyboard.c @ 83011:c4d4cbf86260

Changed tty input code to use read_socket_hook. src/keyboard.c (read_avail_input): Removed tty-related code. (tty_read_avail_input): New function. src/keyboard.h (tty_read_avail_input): New prototype. src/term.c (term_init): Set read_socket_hook. Removed bogus baud rate initialization. src/termhooks.h (read_socket_hook): Added display parameter. src/xterm.c (XTread_socket): Added display parameter (unused). git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-51
author Karoly Lorentey <lorentey@elte.hu>
date Sun, 11 Jan 2004 01:18:45 +0000
parents 82554ed1aed8
children 4aa172a45af1
comparison
equal deleted inserted replaced
83010:82554ed1aed8 83011:c4d4cbf86260
6609 read_avail_input (expected) 6609 read_avail_input (expected)
6610 int expected; 6610 int expected;
6611 { 6611 {
6612 struct input_event buf[KBD_BUFFER_SIZE]; 6612 struct input_event buf[KBD_BUFFER_SIZE];
6613 register int i; 6613 register int i;
6614 struct display *d;
6614 int nread = 0; 6615 int nread = 0;
6615 6616
6616 for (i = 0; i < KBD_BUFFER_SIZE; i++) 6617 for (i = 0; i < KBD_BUFFER_SIZE; i++)
6617 EVENT_INIT (buf[i]); 6618 EVENT_INIT (buf[i]);
6618 6619
6619 { 6620 for (d = display_list; d; d = d->next_display)
6620 struct display *d; 6621 {
6621 6622 if (d->read_socket_hook)
6622 for (d = display_list; d; d = d->next_display) 6623 /* No need for FIONREAD or fcntl; just say don't wait. */
6623 { 6624 nread = (*d->read_socket_hook) (d, buf, KBD_BUFFER_SIZE, expected);
6624 if (d->read_socket_hook) 6625
6625 /* No need for FIONREAD or fcntl; just say don't wait. */ 6626 if (nread > 0)
6626 nread = (*d->read_socket_hook) (buf, KBD_BUFFER_SIZE, expected); 6627 break;
6627
6628 if (nread > 0)
6629 break;
6630 }
6631 }
6632
6633 if (nread <= 0 && tty_list)
6634 {
6635 /* Using KBD_BUFFER_SIZE - 1 here avoids reading more than
6636 the kbd_buffer can really hold. That may prevent loss
6637 of characters on some systems when input is stuffed at us. */
6638 unsigned char cbuf[KBD_BUFFER_SIZE - 1];
6639 int n_to_read;
6640 struct tty_display_info *tty;
6641 Lisp_Object frame;
6642
6643 #ifdef WINDOWSNT
6644 return 0;
6645 #else /* not WINDOWSNT */
6646 #ifdef MSDOS
6647 n_to_read = dos_keysns ();
6648 if (n_to_read == 0)
6649 return 0;
6650
6651 cbuf[0] = dos_keyread ();
6652 nread = 1;
6653
6654 #else /* not MSDOS */
6655
6656 nread = 0;
6657
6658 /* Try to read from each available tty, until one succeeds. */
6659 for (tty = tty_list; tty; tty = tty->next) {
6660
6661 if (! tty->term_initted)
6662 continue;
6663
6664 /* Determine how many characters we should *try* to read. */
6665 #ifdef FIONREAD
6666 /* Find out how much input is available. */
6667 if (ioctl (fileno (TTY_INPUT (tty)), FIONREAD, &n_to_read) < 0)
6668 {
6669 /* Formerly simply reported no input, but that sometimes led to
6670 a failure of Emacs to terminate.
6671 SIGHUP seems appropriate if we can't reach the terminal. */
6672 /* ??? Is it really right to send the signal just to this process
6673 rather than to the whole process group?
6674 Perhaps on systems with FIONREAD Emacs is alone in its group. */
6675 /* It appears to be the case, see narrow_foreground_group. */
6676 if (! noninteractive)
6677 {
6678 if (! tty_list->next)
6679 kill (getpid (), SIGHUP); /* This was the last terminal. */
6680 else
6681 n_to_read = 0; /* XXX tty should be closed here. */
6682 }
6683 else
6684 {
6685 n_to_read = 0;
6686 }
6687 }
6688 if (n_to_read == 0)
6689 continue;
6690 if (n_to_read > sizeof cbuf)
6691 n_to_read = sizeof cbuf;
6692 #else /* no FIONREAD */
6693 #if defined (USG) || defined (DGUX) || defined(CYGWIN)
6694 /* Read some input if available, but don't wait. */
6695 n_to_read = sizeof cbuf;
6696 fcntl (fileno (TTY_INPUT (tty)), F_SETFL, O_NDELAY);
6697 #else
6698 you lose;
6699 #endif
6700 #endif
6701
6702 /* Now read; for one reason or another, this will not block.
6703 NREAD is set to the number of chars read. */
6704 do
6705 {
6706 nread = emacs_read (fileno (TTY_INPUT (tty)), cbuf, n_to_read);
6707 /* POSIX infers that processes which are not in the session leader's
6708 process group won't get SIGHUP's at logout time. BSDI adheres to
6709 this part standard and returns -1 from read (0) with errno==EIO
6710 when the control tty is taken away.
6711 Jeffrey Honig <jch@bsdi.com> says this is generally safe. */
6712 if (nread == -1 && errno == EIO)
6713 {
6714 if (! tty_list->next)
6715 kill (0, SIGHUP); /* This was the last terminal. */
6716 else
6717 delete_tty (tty); /* XXX I wonder if this is safe here. */
6718 }
6719 #if defined (AIX) && (! defined (aix386) && defined (_BSD))
6720 /* The kernel sometimes fails to deliver SIGHUP for ptys.
6721 This looks incorrect, but it isn't, because _BSD causes
6722 O_NDELAY to be defined in fcntl.h as O_NONBLOCK,
6723 and that causes a value other than 0 when there is no input. */
6724 if (nread == 0)
6725 {
6726 if (! tty_list->next)
6727 kill (0, SIGHUP); /* This was the last terminal. */
6728 else
6729 delete_tty (tty); /* XXX I wonder if this is safe here. */
6730 }
6731 #endif
6732 }
6733 while (
6734 /* We used to retry the read if it was interrupted.
6735 But this does the wrong thing when O_NDELAY causes
6736 an EAGAIN error. Does anybody know of a situation
6737 where a retry is actually needed? */
6738 #if 0
6739 nread < 0 && (errno == EAGAIN
6740 #ifdef EFAULT
6741 || errno == EFAULT
6742 #endif
6743 #ifdef EBADSLT
6744 || errno == EBADSLT
6745 #endif
6746 )
6747 #else
6748 0
6749 #endif
6750 );
6751
6752 #ifndef FIONREAD
6753 #if defined (USG) || defined (DGUX) || defined (CYGWIN)
6754 fcntl (fileno (TTY_INPUT (tty)), F_SETFL, 0);
6755 #endif /* USG or DGUX or CYGWIN */
6756 #endif /* no FIONREAD */
6757
6758 if (nread > 0)
6759 break;
6760 } /* for each tty */
6761
6762 if (nread <= 0)
6763 return 0;
6764
6765 #endif /* not MSDOS */
6766 #endif /* not WINDOWSNT */
6767
6768 if (!tty)
6769 abort ();
6770
6771 /* Select frame corresponding to the active tty. Note that the
6772 value of selected_frame is not reliable here, redisplay tends
6773 to temporarily change it. But tty should always be non-NULL. */
6774 frame = tty->top_frame;
6775
6776 for (i = 0; i < nread; i++)
6777 {
6778 buf[i].kind = ASCII_KEYSTROKE_EVENT;
6779 buf[i].modifiers = 0;
6780 if (tty->meta_key == 1 && (cbuf[i] & 0x80))
6781 buf[i].modifiers = meta_modifier;
6782 if (tty->meta_key != 2)
6783 cbuf[i] &= ~0x80;
6784
6785 buf[i].code = cbuf[i];
6786 buf[i].frame_or_window = frame;
6787 buf[i].arg = Qnil;
6788 }
6789 } 6628 }
6790 6629
6791 /* Scan the chars for C-g and store them in kbd_buffer. */ 6630 /* Scan the chars for C-g and store them in kbd_buffer. */
6792 for (i = 0; i < nread; i++) 6631 for (i = 0; i < nread; i++)
6793 { 6632 {
6799 break; 6638 break;
6800 } 6639 }
6801 6640
6802 return nread; 6641 return nread;
6803 } 6642 }
6643
6644 /* This is the tty way of reading available input.
6645
6646 Note that each terminal device has its own `struct display' object,
6647 and so this function is called once for each individual termcap
6648 display. The first parameter indicates which device to read from. */
6649 int
6650 tty_read_avail_input (struct display *display,
6651 struct input_event *buf,
6652 int numchars, int expected)
6653 {
6654 /* Using KBD_BUFFER_SIZE - 1 here avoids reading more than
6655 the kbd_buffer can really hold. That may prevent loss
6656 of characters on some systems when input is stuffed at us. */
6657 unsigned char cbuf[KBD_BUFFER_SIZE - 1];
6658 int n_to_read, i;
6659 struct tty_display_info *tty = display->display_info.tty;
6660 Lisp_Object frame;
6661 int nread = 0;
6662
6663 if (display->type != output_termcap)
6664 abort ();
6665
6666 /* XXX I think the following code should be moved to separate
6667 functions in system-dependent files. */
6668 #ifdef WINDOWSNT
6669 return 0;
6670 #else /* not WINDOWSNT */
6671 #ifdef MSDOS
6672 n_to_read = dos_keysns ();
6673 if (n_to_read == 0)
6674 return 0;
6675
6676 cbuf[0] = dos_keyread ();
6677 nread = 1;
6678
6679 #else /* not MSDOS */
6680
6681 if (! tty->term_initted)
6682 return 0;
6683
6684 /* Determine how many characters we should *try* to read. */
6685 #ifdef FIONREAD
6686 /* Find out how much input is available. */
6687 if (ioctl (fileno (TTY_INPUT (tty)), FIONREAD, &n_to_read) < 0)
6688 {
6689 if (! noninteractive)
6690 {
6691 delete_tty (tty); /* XXX I wonder if this is safe here. */
6692
6693 /* Formerly simply reported no input, but that sometimes led to
6694 a failure of Emacs to terminate.
6695 SIGHUP seems appropriate if we can't reach the terminal. */
6696 /* ??? Is it really right to send the signal just to this process
6697 rather than to the whole process group?
6698 Perhaps on systems with FIONREAD Emacs is alone in its group. */
6699 /* It appears to be the case, see narrow_foreground_group. */
6700 if (! tty_list->next)
6701 kill (getpid (), SIGHUP); /* This was the last terminal. */
6702 }
6703 else
6704 {
6705 n_to_read = 0;
6706 }
6707 }
6708 if (n_to_read == 0)
6709 return 0;
6710 if (n_to_read > sizeof cbuf)
6711 n_to_read = sizeof cbuf;
6712 #else /* no FIONREAD */
6713 #if defined (USG) || defined (DGUX) || defined(CYGWIN)
6714 /* Read some input if available, but don't wait. */
6715 n_to_read = sizeof cbuf;
6716 fcntl (fileno (TTY_INPUT (tty)), F_SETFL, O_NDELAY);
6717 #else
6718 you lose;
6719 #endif
6720 #endif
6721
6722 /* Now read; for one reason or another, this will not block.
6723 NREAD is set to the number of chars read. */
6724 do
6725 {
6726 nread = emacs_read (fileno (TTY_INPUT (tty)), cbuf, n_to_read);
6727 /* POSIX infers that processes which are not in the session leader's
6728 process group won't get SIGHUP's at logout time. BSDI adheres to
6729 this part standard and returns -1 from read (0) with errno==EIO
6730 when the control tty is taken away.
6731 Jeffrey Honig <jch@bsdi.com> says this is generally safe. */
6732 if (nread == -1 && errno == EIO)
6733 {
6734 if (! tty_list->next)
6735 kill (0, SIGHUP); /* This was the last terminal. */
6736 else
6737 delete_tty (tty); /* XXX I wonder if this is safe here. */
6738 }
6739 #if defined (AIX) && (! defined (aix386) && defined (_BSD))
6740 /* The kernel sometimes fails to deliver SIGHUP for ptys.
6741 This looks incorrect, but it isn't, because _BSD causes
6742 O_NDELAY to be defined in fcntl.h as O_NONBLOCK,
6743 and that causes a value other than 0 when there is no input. */
6744 if (nread == 0)
6745 {
6746 if (! tty_list->next)
6747 kill (0, SIGHUP); /* This was the last terminal. */
6748 else
6749 delete_tty (tty); /* XXX I wonder if this is safe here. */
6750 }
6751 #endif
6752 }
6753 while (
6754 /* We used to retry the read if it was interrupted.
6755 But this does the wrong thing when O_NDELAY causes
6756 an EAGAIN error. Does anybody know of a situation
6757 where a retry is actually needed? */
6758 #if 0
6759 nread < 0 && (errno == EAGAIN
6760 #ifdef EFAULT
6761 || errno == EFAULT
6762 #endif
6763 #ifdef EBADSLT
6764 || errno == EBADSLT
6765 #endif
6766 )
6767 #else
6768 0
6769 #endif
6770 );
6771
6772 #ifndef FIONREAD
6773 #if defined (USG) || defined (DGUX) || defined (CYGWIN)
6774 fcntl (fileno (TTY_INPUT (tty)), F_SETFL, 0);
6775 #endif /* USG or DGUX or CYGWIN */
6776 #endif /* no FIONREAD */
6777
6778 if (nread <= 0)
6779 return nread;
6780
6781 #endif /* not MSDOS */
6782 #endif /* not WINDOWSNT */
6783
6784 /* Select the frame corresponding to the active tty. Note that the
6785 value of selected_frame is not reliable here, redisplay tends to
6786 temporarily change it. */
6787 frame = tty->top_frame;
6788
6789 for (i = 0; i < nread; i++)
6790 {
6791 buf[i].kind = ASCII_KEYSTROKE_EVENT;
6792 buf[i].modifiers = 0;
6793 if (tty->meta_key == 1 && (cbuf[i] & 0x80))
6794 buf[i].modifiers = meta_modifier;
6795 if (tty->meta_key != 2)
6796 cbuf[i] &= ~0x80;
6797
6798 buf[i].code = cbuf[i];
6799 buf[i].frame_or_window = frame;
6800 buf[i].arg = Qnil;
6801 }
6802
6803 return nread;
6804 }
6805
6804 #endif /* not VMS */ 6806 #endif /* not VMS */
6805 6807
6806 #ifdef SIGIO /* for entire page */ 6808 #ifdef SIGIO /* for entire page */
6807 /* Note SIGIO has been undef'd if FIONREAD is missing. */ 6809 /* Note SIGIO has been undef'd if FIONREAD is missing. */
6808 6810