Message-Id: <199904041935.TAA39174@out5.ibm.net> From: "Mark E." To: Eli Zaretskii , djgpp-workers AT delorie DOT com Date: Sun, 4 Apr 1999 15:35:26 -0400 MIME-Version: 1.0 Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7BIT Subject: Re: patches for locale.h and tcsetatr.c References: <199903311516 DOT PAA89402 AT out5 DOT ibm DOT net> In-reply-to: X-mailer: Pegasus Mail for Win32 (v3.01d) Reply-To: djgpp-workers AT delorie DOT com > How different is the version in the Bash distribution? The differences appear to be quite large I'm afraid: *** src/libc/posix/termios/tminit.c Sat Mar 20 19:13:44 1999 --- /djgpp/gnu/bash-2.03/tminit.c Thu Mar 18 13:33:48 1999 *************** *** 1,4 **** - /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */ /* * tminit.c - initializer and main part of termios emulation. * designed for DJGPP by Daisuke Aoyama --- 1,3 ---- *************** *** 6,11 **** --- 5,11 ---- */ #include + #include #include #include #include *************** *** 16,21 **** --- 16,23 ---- #include #include #include + #include + #include #include #include #include *************** *** 31,36 **** --- 33,59 ---- #define CPMEOF 0x1a /* Ctrl+Z */ + #define _REG_STATUS_CF 0x01 + #define _REG_STATUS_ZF 0x40 + #define _KEY_INS 0x80 + #define _KEY_CAPS 0x40 + #define _KEY_NUM 0x20 + #define _KEY_SCRL 0x10 + #define _KEY_ALT 0x08 + #define _KEY_CTRL 0x04 + #define _KEY_LSFT 0x02 + #define _KEY_RSFT 0x01 + #define _KEYE_SYSRQ 0x80 + #define _KEYE_CAPS 0x40 + #define _KEYE_NUM 0x20 + #define _KEYE_SCRL 0x10 + #define _KEYE_RALT 0x08 + #define _KEYE_RCTRL 0x04 + #define _KEYE_LALT 0x02 + #define _KEYE_LCTRL 0x01 + + #define CHECKBYTES 32 + /* tty buffers */ unsigned char __libc_tty_queue_buffer[_TTY_QUEUE_SIZE]; struct tty __libc_tty_internal = TTYDEFAULT; *************** *** 40,53 **** --- 63,85 ---- /* global only in the termios functions */ int __libc_termios_hook_common_count = -1; + /* static variables */ + static int __libc_use_function_and_arrow_keys = 0; + static int __libc_has_enhanced_keyboard = 0; + static int __libc_has_extended_keystroke = 0; + static unsigned char __libc_extended_keystroke[16] = { 0, }; + static ssize_t __libc_termios_check_bytes = CHECKBYTES; + /* static functions */ static void __libc_termios_fflushall (void); + static void __libc_termios_init_direct_functions (void); static ssize_t __libc_termios_read (int handle, void *buffer, size_t count, ssize_t *rv); static ssize_t __libc_termios_read_cooked_tty (int handle, void *buffer, size_t count); static ssize_t __libc_termios_read_raw_tty (int handle, void *buffer, size_t count); static ssize_t __libc_termios_write (int handle, const void *buffer, size_t count, ssize_t *rv); static ssize_t __libc_termios_write_cooked_tty (int handle, const void *buffer, size_t count); static ssize_t __libc_termios_write_raw_tty (int handle, const void *buffer, size_t count); + static int __libc_termios_fsext (__FSEXT_Fnumber n, int *rv, va_list ap); static void __libc_termios_echo_ctrl (unsigned char ch); static void __libc_termios_maybe_echo_ctrl (unsigned char ch); static void __libc_termios_maybe_echo (unsigned char ch); *************** *** 59,72 **** static void __libc_termios_clear_queue (void); static int __libc_termios_get_queue (void); static int __libc_termios_put_queue (unsigned char ch); static void __libc_termios_fill_queue (void); /* direct I/O functions */ ! static inline int __direct_keysense (void); ! static inline unsigned char __direct_keyinput (void); ! static inline int __direct_ctrlsense (void); ! static inline void __direct_output (unsigned char ch); ! static inline void __direct_outputs (const unsigned char *s); /************************************************************************ ******/ /* initialize function ********************************************************/ --- 91,132 ---- static void __libc_termios_clear_queue (void); static int __libc_termios_get_queue (void); static int __libc_termios_put_queue (unsigned char ch); + static void __libc_termios_raise_signal (unsigned char ch, int sig); static void __libc_termios_fill_queue (void); + void __libc_termios_check_signals (void); /* direct I/O functions */ ! static void __direct_add_keystroke (int c); ! static void __direct_add_keystrokes (char *s); ! static void __direct_check_extened_keystroke_at (int scan); ! /* AT keyboard */ ! static int __direct_keysense_at (void); ! static unsigned char __direct_keyinput_at (void); ! static int __direct_ctrlsense_at (void); ! /* AT enhanced keyboard */ ! static int __direct_keysense_ate (void); ! static unsigned char __direct_keyinput_ate (void); ! static int __direct_ctrlsense_ate (void); ! /* Output functions */ ! static void __direct_output_tab_at (void); ! static void __direct_output_at (unsigned char ch); ! static void __direct_outputns_at (int n, const unsigned char *s); ! static void __direct_outputs_at (const unsigned char *s); ! /* BIOS simulator */ ! static int __direct_keysense_simulator (void); ! static unsigned char __direct_keyinput_simulator (void); ! static int __direct_ctrlsense_simulator (void); ! static void __direct_output_tab_simulator (void); ! static void __direct_output_simulator (unsigned char ch); ! static void __direct_outputns_simulator (int n, const unsigned char *s); ! static void __direct_outputs_simulator (const unsigned char *s); ! /* function pointers */ ! static int (*__direct_keysense) (void) = __direct_keysense_at; ! static unsigned char (*__direct_keyinput) (void) = __direct_keyinput_at; ! static int (*__direct_ctrlsense) (void) = __direct_ctrlsense_at; ! static void (*__direct_output) (unsigned char ch) = __direct_output_at; ! static void (*__direct_outputns) (int n, const unsigned char *s) = __direct_outputns_at; ! static void (*__direct_outputs) (const unsigned char *s) = __direct_outputs_at; /************************************************************************ ******/ /* initialize function ********************************************************/ *************** *** 81,86 **** --- 141,172 ---- #endif } + static void + __libc_termios_init_direct_functions (void) + { + __libc_has_enhanced_keyboard = 0; + __libc_has_extended_keystroke = 0; + + if (_farpeekb (_dos_ds, 0x496) & 0x10) + __libc_has_enhanced_keyboard = 1; + + if (__libc_has_enhanced_keyboard) + { + __direct_keysense = __direct_keysense_ate; + __direct_keyinput = __direct_keyinput_ate; + __direct_ctrlsense = __direct_ctrlsense_ate; + } + else + { + __direct_keysense = __direct_keysense_at; + __direct_keyinput = __direct_keyinput_at; + __direct_ctrlsense = __direct_ctrlsense_at; + } + __direct_output = __direct_output_at; + __direct_outputns = __direct_outputns_at; + __direct_outputs = __direct_outputs_at; + } + void __libc_termios_init (void) { *************** *** 91,115 **** /* flush all buffered streams */ __libc_termios_fflushall (); /* set special hooks */ __libc_read_termios_hook = __libc_termios_read; __libc_write_termios_hook = __libc_termios_write; /* import parameters */ /* __libc_tty_p = ...; */ } } /************************************************************************ ******/ ! /* direct I/O function (inlined) **********************************************/ ! #define _REG_STATUS_ZF 0x40 ! static inline int ! __direct_keysense (void) { __dpmi_regs r; r.h.ah = 0x01; __dpmi_int (0x16, &r); if (r.x.flags & _REG_STATUS_ZF) --- 177,374 ---- /* flush all buffered streams */ __libc_termios_fflushall (); + /* check enhanced keyboard, etc */ + __libc_termios_init_direct_functions (); + /* set special hooks */ __libc_read_termios_hook = __libc_termios_read; __libc_write_termios_hook = __libc_termios_write; /* import parameters */ /* __libc_tty_p = ...; */ + + /* fsext */ + (void) __FSEXT_set_function (0, __libc_termios_fsext); + (void) __FSEXT_set_function (1, __libc_termios_fsext); + (void) __FSEXT_set_function (2, __libc_termios_fsext); + __libc_termios_check_bytes = CHECKBYTES; } } + int + __libc_termios_disable_function_and_arrow_keys (void) + { + int old_value; + + old_value = __libc_use_function_and_arrow_keys; + __libc_use_function_and_arrow_keys = 0; + + return old_value; + } + + int + __libc_termios_enable_function_and_arrow_keys (void) + { + int old_value; + + old_value = __libc_use_function_and_arrow_keys; + __libc_use_function_and_arrow_keys = 1; + + return old_value; + } + + int + __libc_termios_disable_bios_io (void) + { + int old_value; + + __libc_termios_init (); + if ((__direct_keysense == __direct_keysense_ate) + || (__direct_keysense == __direct_keysense_at)) + old_value = 1; + else + old_value = 0; + + __libc_termios_init_direct_functions (); + __direct_keysense = __direct_keysense_simulator; + __direct_keyinput = __direct_keyinput_simulator; + __direct_ctrlsense = __direct_ctrlsense_simulator; + __direct_output = __direct_output_simulator; + __direct_outputns = __direct_outputns_simulator; + __direct_outputs = __direct_outputs_simulator; + + return old_value; + } + + int + __libc_termios_enable_bios_io (void) + { + int old_value; + + __libc_termios_init (); + if ((__direct_keysense == __direct_keysense_ate) + || (__direct_keysense == __direct_keysense_at)) + old_value = 1; + else + old_value = 0; + + __libc_termios_init_direct_functions (); + + return old_value; + } + /************************************************************************ ******/ ! /* direct I/O function ********************************************************/ ! /* function key trans function */ ! static void ! __direct_add_keystroke (int c) ! { ! if (__libc_has_extended_keystroke + 1 > sizeof (__libc_extended_keystroke)) ! return; ! __libc_extended_keystroke[__libc_has_extended_keystroke++] = (unsigned char) c; ! } ! ! static void ! __direct_add_keystrokes (char *s) ! { ! int len; ! ! len = strlen (s); ! if (__libc_has_extended_keystroke + len > sizeof (__libc_extended_keystroke)) ! return; ! ! while (--len >= 0) ! __libc_extended_keystroke[__libc_has_extended_keystroke++] = (unsigned char) s[len]; ! } ! ! #define _NDUMMY (0xffU) ! #define _N(c) (0x00U|(c)) /* no shift */ ! #define _S(c) (0x40U|(c)) /* w/shift */ ! #define _C(c) (0x80U|(c)) /* w/ctrl */ ! #define _A(c) (0xc0U|(c)) /* w/alt */ ! #define _TRANS_NOSHIFT "\x1b[0" ! #define _TRANS_SHIFT "\x1b[1" ! #define _TRANS_CTRL "\x1b[2" ! #define _TRANS_ALT "\x1b[3" ! ! static unsigned char trans_alphabet_chars[64] = ! "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456ABCDEFGHIJKLMN OPQRSTUVWXYZ123456"; ! ! static unsigned char trans_mapping_chras_at[] = ! { ! /* 000-037: A-Z, 040-077: XA-XZ */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* 00-07 */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* 08-0F */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* 10-17 */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* 18-1F */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* 20-27 */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* 28-2F */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* 30-37 */ ! _NDUMMY, _NDUMMY, _NDUMMY, _N(040), _N(041), _N(042), _N(043), _N(044), /* 38-3F */ ! _N(045), _N(046), _N(047), _N(050), _N(051), _NDUMMY, _NDUMMY, _N(006), /* 40-47 */ ! _N(000), _N(010), _NDUMMY, _N(001), _NDUMMY, _N(002), _NDUMMY, _N(007), /* 48-4F */ ! _N(003), _N(011), _N(004), _N(005), _S(040), _S(041), _S(042), _S(043), /* 50-57 */ ! _S(044), _S(045), _S(046), _S(047), _S(050), _S(051), _C(040), _C(041), /* 58-5F */ ! _C(042), _C(043), _C(044), _C(045), _C(046), _C(047), _C(050), _C(051), /* 60-67 */ ! _A(040), _A(041), _A(042), _A(043), _A(044), _A(045), _A(046), _A(047), /* 68-6F */ ! _A(050), _A(051), _NDUMMY, _C(001), _C(002), _C(007), _C(011), _C(006), /* 70-77 */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* 78-7F */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _C(010), _N(052), _N(053), _S(052), /* 80-87 */ ! _S(053), _C(052), _C(053), _A(052), _A(053), _C(000), _NDUMMY, _NDUMMY, /* 88-8F */ ! _NDUMMY, _C(003), _C(004), _C(005), _NDUMMY, _NDUMMY, _NDUMMY, _A(006), /* 90-97 */ ! _A(000), _A(010), _NDUMMY, _A(001), _NDUMMY, _A(002), _NDUMMY, _A(007), /* 98-9F */ ! _A(003), _A(011), _A(004), _A(005), _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* A0-A7 */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* A8-AF */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* B0-B7 */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* B8-BF */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* C0-C7 */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* C8-CF */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* D0-D7 */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* D8-DF */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* E0-E7 */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* E8-EF */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* F0-F7 */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* F8-FF */ ! }; ! ! static void ! __direct_check_extened_keystroke_at (int scan) ! { ! int c, shift; ! ! if (!__libc_use_function_and_arrow_keys || scan < 0 || scan > 0xff) ! return; ! ! c = (int) trans_mapping_chras_at[scan]; ! if (c == (int) _NDUMMY) ! return; ! ! shift = c & 0xc0; ! c &= ~0xc0; ! __direct_add_keystroke (trans_alphabet_chars[c]); ! if (c >= 040) ! __direct_add_keystroke ('X'); ! if (shift == 0x00) ! __direct_add_keystrokes (_TRANS_NOSHIFT); ! else if (shift == 0x40) ! __direct_add_keystrokes (_TRANS_SHIFT); ! else if (shift == 0x80) ! __direct_add_keystrokes (_TRANS_CTRL); ! else if (shift == 0xc0) ! __direct_add_keystrokes (_TRANS_ALT); ! } ! ! /* Input form AT keyboard */ ! static int ! __direct_keysense_at (void) { __dpmi_regs r; + if (__libc_has_extended_keystroke) + return 1; + r.h.ah = 0x01; __dpmi_int (0x16, &r); if (r.x.flags & _REG_STATUS_ZF) *************** *** 118,148 **** return 1; } ! static inline unsigned char ! __direct_keyinput (void) { __dpmi_regs r; r.h.ah = 0x00; __dpmi_int (0x16, &r); ! return r.h.al; ! } ! #define _KEY_INS 0x80 ! #define _KEY_CAPS 0x40 ! #define _KEY_NUM 0x20 ! #define _KEY_SCRL 0x10 ! #define _KEY_ALT 0x08 ! #define _KEY_CTRL 0x04 ! #define _KEY_LSFT 0x02 ! #define _KEY_RSFT 0x01 ! static inline int ! __direct_ctrlsense (void) { __dpmi_regs r; r.h.ah = 0x02; __dpmi_int (0x16, &r); if (r.h.al & _KEY_CTRL) --- 377,410 ---- return 1; } ! static unsigned char ! __direct_keyinput_at (void) { __dpmi_regs r; + if (__libc_has_extended_keystroke) + return __libc_extended_keystroke[-- __libc_has_extended_keystroke]; + r.h.ah = 0x00; __dpmi_int (0x16, &r); + if (r.h.al != 0x00) + return r.h.al; ! __direct_check_extened_keystroke_at (r.h.ah); ! if (__libc_has_extended_keystroke) ! return __libc_extended_keystroke[-- __libc_has_extended_keystroke]; ! return 0; ! } ! static int ! __direct_ctrlsense_at (void) { __dpmi_regs r; + if (__libc_has_extended_keystroke) + return 0; + r.h.ah = 0x02; __dpmi_int (0x16, &r); if (r.h.al & _KEY_CTRL) *************** *** 151,173 **** return 0; } ! static inline void ! __direct_output (unsigned char ch) { __dpmi_regs r; ! if (ch == 0xff) return; r.h.al = ch; __dpmi_int (0x29, &r); } ! static inline void ! __direct_outputs (const unsigned char *s) { while (*s) ! __direct_output (*s++); } /************************************************************************ ******/ --- 413,658 ---- return 0; } ! /* Input from AT enhanced keyboard */ ! static int ! __direct_keysense_ate (void) { __dpmi_regs r; ! if (__libc_has_extended_keystroke) ! return 1; ! ! r.h.ah = 0x11; ! __dpmi_int (0x16, &r); ! if (r.x.flags & _REG_STATUS_ZF) ! return 0; ! ! return 1; ! } ! ! static unsigned char ! __direct_keyinput_ate (void) ! { ! __dpmi_regs r; ! ! if (__libc_has_extended_keystroke) ! return __libc_extended_keystroke[-- __libc_has_extended_keystroke]; ! ! r.h.ah = 0x10; ! __dpmi_int (0x16, &r); ! if (r.h.al != 0x00 && (r.h.al < 0xe0U ! || (r.h.al != 0xe0 && r.h.al != 0xf0))) ! return r.h.al; ! ! __direct_check_extened_keystroke_at (r.h.ah); ! if (__libc_has_extended_keystroke) ! return __libc_extended_keystroke[-- __libc_has_extended_keystroke]; ! ! return 0; ! } ! ! static int ! __direct_ctrlsense_ate (void) ! { ! __dpmi_regs r; ! ! if (__libc_has_extended_keystroke) ! return 0; ! ! r.h.ah = 0x12; ! __dpmi_int (0x16, &r); ! if (r.h.al & _KEY_CTRL) /* either CTRL */ ! return 1; ! ! return 0; ! } ! ! /* output to Screen */ ! static void ! __direct_output_tab_at (void) ! { ! __dpmi_regs r; ! int page, col; ! int x, y; ! ! page = _farpeekb (_dos_ds, 0x462); ! col = _farpeekw (_dos_ds, 0x44a); ! ! r.h.ah = 3; ! r.h.bh = page; ! __dpmi_int (0x10, &r); ! x = r.h.dl; ! y = r.h.dh; ! ! x += 8; ! x &= ~7; ! if (x > col) ! { ! #if 1 ! r.h.al = '\r'; ! __dpmi_int (0x29, &r); ! r.h.al = '\n'; ! __dpmi_int (0x29, &r); ! #else ! (void) putch ('\r'); ! (void) putch ('\n'); ! #endif ! } ! else ! { ! r.h.ah = 2; ! r.h.bh = page; ! r.h.dl = x; ! r.h.dh = y; ! __dpmi_int (0x10, &r); ! } ! } ! ! static void ! __direct_output_at (unsigned char ch) ! { ! #if 1 ! __dpmi_regs r; ! #endif ! ! if (ch == 0x09) ! { ! __direct_output_tab_at (); ! return; ! } ! else if (ch == 0xff) return; + #if 1 r.h.al = ch; __dpmi_int (0x29, &r); + #else + (void) putch (ch); + #endif } ! static void ! __direct_outputns_at (int n, const unsigned char *s) ! { ! #if 1 ! __dpmi_regs r; ! #endif ! unsigned char ch; ! ! while (--n >= 0) ! { ! ch = *s++; ! if (ch == 0x09) ! __direct_output_tab_at (); ! else if (ch != 0xff) ! { ! #if 1 ! r.h.al = ch; ! __dpmi_int (0x29, &r); ! #else ! (void) putch (ch); ! #endif ! } ! } ! } ! ! static void ! __direct_outputs_at (const unsigned char *s) { while (*s) ! __direct_output_at (*s++); ! } ! ! /* BIOS simulator */ ! static int ! __direct_keysense_simulator (void) ! { ! __dpmi_regs r; ! int c; ! ! if (__libc_has_extended_keystroke) ! return 1; ! ! r.h.ah = 0x06; ! r.h.dl = 0xff; ! __dpmi_int (0x21, &r); ! if (r.x.flags & _REG_STATUS_ZF) ! return 0; ! ! c = (int) r.h.al; ! if (c == 0) ! { ! r.h.ah = 0x06; ! r.h.dl = 0xff; ! __dpmi_int (0x21, &r); ! if (r.x.flags & _REG_STATUS_ZF) ! return 0; ! ! /* TODO: add trans code */ ! c = (int) r.h.al; ! { ! char tmp[128]; ! sprintf (tmp, "0x%x ", c); ! __direct_outputs_simulator ("Not supported code:"); ! __direct_outputs_simulator (tmp); ! } ! return 0; ! } ! __direct_add_keystroke (c); ! ! return 1; ! } ! ! static unsigned char ! __direct_keyinput_simulator (void) ! { ! __dpmi_regs r; ! ! if (__libc_has_extended_keystroke) ! return __libc_extended_keystroke[-- __libc_has_extended_keystroke]; ! ! if (! __direct_keysense_simulator () || ! __libc_has_extended_keystroke) ! return 0; ! ! return __libc_extended_keystroke[-- __libc_has_extended_keystroke]; ! } ! ! static int ! __direct_ctrlsense_simulator (void) ! { ! return 0; ! } ! ! static void ! __direct_output_tab_simulator (void) ! { ! } ! ! static void ! __direct_output_simulator (unsigned char ch) ! { ! __dpmi_regs r; ! ! if (ch == 0xff) ! return; ! ! r.h.ah = 0x06; ! r.h.dl = ch; ! __dpmi_int (0x21, &r); ! } ! ! static void ! __direct_outputns_simulator (int n, const unsigned char *s) ! { ! while (--n >= 0) ! __direct_output_simulator (*s++); ! } ! ! static void ! __direct_outputs_simulator (const unsigned char *s) ! { ! while (*s) ! __direct_output_simulator (*s++); } /************************************************************************ ******/ *************** *** 491,496 **** --- 976,988 ---- } } + __libc_termios_check_bytes -= bytes; + if (__libc_termios_check_bytes <= 0) + { + __libc_termios_check_bytes = CHECKBYTES; + __libc_termios_check_signals (); + } + /* result of write() */ *rv = bytes; return 1; *************** *** 506,529 **** { const unsigned char *rp; unsigned char ch; ! ssize_t n; rp = buffer; n = count; ! while (--n >= 0) { ! /* get character */ ! ch = *rp++; ! /* NOTE: multibyte character don't contain control character */ ! /* map NL to CRNL */ ! if (ch == '\n' && (__libc_tty_p->t_oflag & ONLCR)) ! __direct_output ('\r'); ! /* map CR to NL */ ! else if (ch == '\r' && (__libc_tty_p->t_oflag & OCRNL)) ! ch = '\n'; ! __direct_output (ch); } /* don't count CR */ --- 998,1034 ---- { const unsigned char *rp; unsigned char ch; ! ssize_t n, nn; rp = buffer; n = count; ! while (n > 0) { ! nn = (n < __libc_termios_check_bytes) ? n : __libc_termios_check_bytes; ! n -= nn; ! __libc_termios_check_bytes -= nn; ! while (--nn >= 0) ! { ! /* get character */ ! ch = *rp++; ! /* NOTE: multibyte character don't contain control character */ ! /* map NL to CRNL */ ! if (ch == '\n' && (__libc_tty_p->t_oflag & ONLCR)) ! __direct_output ('\r'); ! /* map CR to NL */ ! else if (ch == '\r' && (__libc_tty_p->t_oflag & OCRNL)) ! ch = '\n'; ! ! __direct_output (ch); ! } ! ! if (__libc_termios_check_bytes <= 0) ! { ! __libc_termios_check_bytes = CHECKBYTES; ! __libc_termios_check_signals (); ! } } /* don't count CR */ *************** *** 546,558 **** rp = buffer; n = count; ! while (--n >= 0) ! __direct_output (*rp++); return count; } /************************************************************************ ******/ /* echo routines **************************************************************/ static void --- 1051,1154 ---- rp = buffer; n = count; ! while (n > 0) ! { ! if (n < __libc_termios_check_bytes) ! { ! __libc_termios_check_bytes -= n; ! __direct_outputns (n, rp); ! rp += n; ! break; ! } ! else ! { ! n -= __libc_termios_check_bytes; ! __direct_outputns (__libc_termios_check_bytes, rp); ! rp += __libc_termios_check_bytes; ! __libc_termios_check_bytes = CHECKBYTES; ! __libc_termios_check_signals (); ! } ! } return count; } /************************************************************************ ******/ + /* special fsext function *****************************************************/ + + static int + __libc_termios_fsext (__FSEXT_Fnumber n, int *rv, va_list ap) + { + short devmod; + ssize_t bytes; + int handle; + + handle = va_arg (ap, int); + devmod = _get_dev_info (handle); + if (devmod == -1) + return 0; + if (!(devmod & _DEV_CDEV) || !(devmod & (_DEV_STDIN|_DEV_STDOUT))) + return 0; + + /* console only... */ + switch (n) + { + #if 0 + case __FSEXT_read: + { + void *buffer; + size_t count; + + buffer = va_arg (ap, void *); + count = va_arg (ap, size_t); + if (devmod & _DEV_RAW) + bytes = __libc_termios_read_raw_tty (handle, buffer, count); + else + bytes = __libc_termios_read_cooked_tty (handle, buffer, count); + + /* result of read */ + *rv = bytes; + return 1; + } + case __FSEXT_write: + { + const void *buffer; + size_t count; + + buffer = va_arg (ap, const void *); + count = va_arg (ap, size_t); + if (devmod & _DEV_RAW) + bytes = __libc_termios_write_raw_tty (handle, buffer, count); + else + bytes = __libc_termios_write_cooked_tty (handle, buffer, count); + + /* result of write */ + *rv = bytes; + return 1; + } + #else + case __FSEXT_write: + { + size_t count; + const void *buffer; + + buffer = va_arg (ap, const void *); + count = va_arg (ap, size_t); + bytes = __libc_termios_write_raw_tty (handle, buffer, count); + + /* result of write */ + *rv = bytes; + return 1; + } + #endif + default: + break; + } + + return 0; + } + + /************************************************************************ ******/ /* echo routines **************************************************************/ static void *************** *** 846,851 **** --- 1442,1462 ---- } static void + __libc_termios_raise_signal (unsigned char ch, int sig) + { + #if 0 + struct sigaction oldact; + + if (sigaction (sig, NULL, &oldact) == 0) + if (oldact.sa_handler == SIG_DFL) + __libc_termios_maybe_echo_ctrl (ch); + #else + __libc_termios_maybe_echo_ctrl (ch); + #endif + kill (getpid(), sig); + } + + static void __libc_termios_fill_queue (void) { unsigned char ch; *************** *** 855,866 **** /* exhaust inputs ? */ if (! __direct_keysense ()) { if (__libc_tty_p->t_lflag & ICANON) ! { ! /* wait for NL or EOT */ ! __dpmi_yield (); ! continue; ! } return; } --- 1466,1475 ---- /* exhaust inputs ? */ if (! __direct_keysense ()) { + __dpmi_yield (); + /* wait for NL or EOT ? */ if (__libc_tty_p->t_lflag & ICANON) ! continue; return; } *************** *** 881,888 **** { if (__libc_tty_p->t_iflag & BRKINT) { ! __libc_termios_maybe_echo_ctrl (ch); ! kill (getpid (), SIGINT); continue; } else --- 1490,1496 ---- { if (__libc_tty_p->t_iflag & BRKINT) { ! __libc_termios_raise_signal (ch, SIGINT); continue; } else *************** *** 893,907 **** } else if (_CC_EQU (VQUIT, ch)) { ! __libc_termios_maybe_echo_ctrl (ch); ! kill (getpid(), SIGQUIT); continue; } else if (_CC_EQU (VSUSP, ch)) { - __libc_termios_maybe_echo_ctrl (ch); #ifdef SIGTSTP ! kill (getpid(), SIGTSTP); #else /* djgpp don't have ... */ { char oldcwd[PATH_MAX]; --- 1501,1513 ---- } else if (_CC_EQU (VQUIT, ch)) { ! __libc_termios_raise_signal (ch, SIGQUIT); continue; } else if (_CC_EQU (VSUSP, ch)) { #ifdef SIGTSTP ! __libc_termios_raise_signal (ch, SIGTSTP); #else /* djgpp don't have ... */ { char oldcwd[PATH_MAX]; *************** *** 1003,1006 **** --- 1609,1655 ---- } /******************************************************************************/ + /* software signal checker ****************************************************/ + + void + __libc_termios_check_signals (void) + { + unsigned char ch; + + if (! __direct_keysense ()) + return; + /* software signals */ + if (__libc_tty_p->t_lflag & ISIG) + { + ch = __direct_keyinput (); + if (! (__libc_tty_p->t_iflag & IGNBRK) && _CC_EQU (VINTR, ch)) + { + if (__libc_tty_p->t_iflag & BRKINT) + { + __libc_termios_raise_signal (ch, SIGINT); + return; + } + } + else if (_CC_EQU (VQUIT, ch)) + { + __libc_termios_raise_signal (ch, SIGQUIT); + return; + } + + /* for compatiblity */ + if (ch == 0x13 && !(__libc_tty_p->t_iflag & IXOFF)) + { + /* CTRL+S */ + while (! __direct_keysense ()) + __dpmi_yield (); + ch = __direct_keyinput (); + return; + } + + /* push back */ + __direct_add_keystroke ((int) ch); + } + } + + /************************************************************************ ******/