www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1997/12/08/10:01:17

Date: Mon, 8 Dec 1997 16:58:42 +0200 (IST)
From: Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
To: djgpp-workers AT delorie DOT com
cc: DJ Delorie <dj AT delorie DOT com>, Charles Sandmann <sandmann AT clio DOT rice DOT edu>
Subject: Enhanced signal support (2/2)
Message-ID: <Pine.SUN.3.91.971208165731.4200s-100000@is>
MIME-Version: 1.0

(Sorry about the empty message with the same subject.)

This is the second part of the changes for SIGQUIT and user-definable
INTR and QUIT keys.

*** include/sys/exceptn.h~0	Tue Dec  5 03:39:44 1995
--- include/sys/exceptn.h	Sat Dec  6 16:56:34 1997
***************
*** 31,42 ****
  extern unsigned short __djgpp_app_DS;	/* Data selector invalidated by HW ints */
  extern unsigned short __djgpp_ds_alias;	/* Data selector always valid */
  extern unsigned short __djgpp_dos_sel;	/* Linear mem selector copy in locked mem */
! extern unsigned short __djgpp_hwint_flags; /* 1 = Disable Ctrl-C; 2 = Count Ctrl-Break (don't kill) */
  extern unsigned __djgpp_cbrk_count;	/* Count of CTRL-BREAK hits */
  extern int __djgpp_exception_inprog;	/* Nested exception count */
  
  void __djgpp_exception_toggle(void);
  int  __djgpp_set_ctrl_c(int enable);	/* On by default */
  
  #endif /* !_POSIX_SOURCE */
  #endif /* !__STRICT_ANSI__ */
--- 31,54 ----
  extern unsigned short __djgpp_app_DS;	/* Data selector invalidated by HW ints */
  extern unsigned short __djgpp_ds_alias;	/* Data selector always valid */
  extern unsigned short __djgpp_dos_sel;	/* Linear mem selector copy in locked mem */
! /* Hardware Interrupt Flags:
! 
!    1 = Disable INTR and QUIT keys (Ctrl-C and Ctrl-\);
!    2 = Count Ctrl-Break (don't kill);
!    4 = IRET from our timer interrupt handler, don't chain */
! extern unsigned short __djgpp_hwint_flags;
  extern unsigned __djgpp_cbrk_count;	/* Count of CTRL-BREAK hits */
  extern int __djgpp_exception_inprog;	/* Nested exception count */
  
+ extern unsigned short __djgpp_sigint_key;  /* key that raises SIGINT */
+ extern unsigned short __djgpp_sigquit_key; /* key that raises SIGQUIT */
+ extern unsigned short __djgpp_sigint_mask; /* kb mask for SIGINT key */
+ extern unsigned short __djgpp_sigquit_mask;/* kb mask for SIGQUIT key */
+ 
  void __djgpp_exception_toggle(void);
  int  __djgpp_set_ctrl_c(int enable);	/* On by default */
+ int  __djgpp_set_sigint_key(int new_key);  /* Set key which raises SIGINT */
+ int  __djgpp_set_sigquit_key(int new_key); /* Set key which raises SIGQUIT */
  
  #endif /* !_POSIX_SOURCE */
  #endif /* !__STRICT_ANSI__ */
*** src/libc/go32/dpmiexcp.c~0	Sun Oct  6 00:33:20 1996
--- src/libc/go32/dpmiexcp.c	Sun Dec  7 12:37:44 1997
*************** except_to_sig(int excep)
*** 82,87 ****
--- 82,89 ----
        return SIGTIMR;
      else if(excep == 0x79 || excep == 0x1b)
        return SIGINT;
+     else if(excep == 0x7a)
+       return SIGQUIT;
      else
        return SIGILL;
    }
*************** do_faulting_finish_message(void)
*** 178,184 ****
    if (signum == 0x1b)
      en = "Control-Break Pressed";
    if (signum == 0x79)
!     en = "Control-C Pressed";
    if (en == 0)
    {
      err("Exception ");
--- 180,188 ----
    if (signum == 0x1b)
      en = "Control-Break Pressed";
    if (signum == 0x79)
!     en = "INTR key Pressed";
!   if (signum == 0x7a)
!     en = "QUIT key Pressed";
    if (en == 0)
    {
      err("Exception ");
*************** __djgpp_exception_toggle(void)
*** 345,350 ****
--- 349,418 ----
    }
  }
  
+ #define RSHIFT 1
+ #define LSHIFT 2
+ #define CTRL   4
+ #define ALT    8
+ #define SHIFT  (RSHIFT | LSHIFT)
+ 
+ #define DEFAULT_SIGINT  0x042e /* Ctrl-C: scan code 2Eh, kb status 04h */
+ #define DEFAULT_SIGQUIT 0x042b /* Ctrl-\: scan code 2Bh, kb status 04h */
+ 
+ /* Make it so the key NEW_KEY will generate the signal SIG.
+    NEW_KEY must include the keyboard status byte in bits 8-15 and the
+    scan code in bits 0-7.  */
+ static int
+ set_signal_key(int sig, int new_key)
+ {
+   int old_key;
+   unsigned short *mask;
+   unsigned short *key;
+   unsigned short kb_status;
+ 
+   if (sig == SIGINT)
+   {
+     mask = &__djgpp_sigint_mask;
+     key  = &__djgpp_sigint_key;
+   }
+   else if (sig == SIGQUIT)
+   {
+     mask = &__djgpp_sigquit_mask;
+     key  = &__djgpp_sigquit_key;
+   }
+   else
+     return -1;
+ 
+   old_key = *key;
+ 
+   *key = new_key & 0xffff;
+   kb_status = *key >> 8;
+ 
+   *mask = 0x000f;	/* Alt, Ctrl and Shift bits only */
+   /* Mask off the RShift bit unless they explicitly asked for it.
+      Our keyboard handler pretends that LShift is pressed when they
+      press RShift.  */
+   if ((kb_status & RSHIFT) == 0)
+     *mask &= ~RSHIFT;
+   /* Mask off the LShift bit if any of the Ctrl or Alt are set,
+      since Shift doesn't matter when Ctrl and/or Alt are pressed.  */
+   if (kb_status & (CTRL | ALT))
+     *mask &= ~LSHIFT;
+ 
+   return old_key;
+ }
+ 
+ int
+ __djgpp_set_sigint_key(int new_key)
+ {
+   return set_signal_key(SIGINT, new_key);
+ }
+ 
+ int
+ __djgpp_set_sigquit_key(int new_key)
+ {
+   return set_signal_key(SIGQUIT, new_key);
+ }
+ 
  void
  __djgpp_exception_setup(void)
  {
*************** __djgpp_exception_setup(void)
*** 352,357 ****
--- 420,428 ----
    __dpmi_meminfo lockmem;
    int i;
  
+   __djgpp_set_sigint_key(DEFAULT_SIGINT);
+   __djgpp_set_sigquit_key(DEFAULT_SIGQUIT);
+ 
    for (i = 0; i < SIGMAX; i++)
      signal_list[i] = (SignalHandler)SIG_DFL;
  
*************** _exit(int status)
*** 417,419 ****
--- 488,520 ----
      __djgpp_exception_toggle ();
    __exit (status);
  }
+ 
+ #ifdef TEST
+ 
+ #include <string.h>
+ 
+ int
+ main(void)
+ {
+   volatile int count = 0;	/* don't let gcc optimize it away */
+ 
+   __djgpp_set_sigint_key (0x0422); /* Ctrl-G */
+ 
+   while (1)
+   {
+     char buf[30];
+ 
+     count++;
+     if (count % 10000 == 0)
+     {
+       sprintf (buf, "counted to %d\r\n", count);
+       _write(STDERR_FILENO, buf, strlen (buf));
+     }
+     if (count >= 1000000000L)
+       count = 0;
+   }
+ 
+   return 0;
+ }
+ 
+ #endif
*** src/libc/go32/dpmiexcp.t~0	Thu Sep 12 02:12:48 1996
--- src/libc/go32/dpmiexcp.txh	Sun Dec  7 13:49:46 1997
*************** void	(*signal(int sig, void (*func)(int)
*** 33,39 ****
  Signals are generated in response to some exceptional behavior of the
  program, such as division by 0.  A signal can also report some
  asynchronous event outside the program, such as someone pressing a
! Ctrl-Break key combination.
  
  Signals are numbered 0..255 for software interrupts and 256..287 for
  exceptions (exception number plus 256); other implementation-specific
--- 33,39 ----
  Signals are generated in response to some exceptional behavior of the
  program, such as division by 0.  A signal can also report some
  asynchronous event outside the program, such as someone pressing a
! @kbd{Ctrl- AT key{BREAK}} key combination.
  
  Signals are numbered 0..255 for software interrupts and 256..287 for
  exceptions (exception number plus 256); other implementation-specific
*************** given a mnemonic which you should use fo
*** 42,48 ****
  
  The default handling for all the signals is to print a traceback (a
  stack dump which describes the sequence of function calls leading to the
! generation of the signal) and abort the program.
  
  This function allows you to change the default behavior for a specific
  signal.  It registers @var{func} as a signal handler for signal number
--- 42,50 ----
  
  The default handling for all the signals is to print a traceback (a
  stack dump which describes the sequence of function calls leading to the
! generation of the signal) and abort the program.  (As an exception, the
! default handler for the signal @code{SIGINT} doesn't print the
! traceback when @kbd{Ctrl-C} is pressed.)
  
  This function allows you to change the default behavior for a specific
  signal.  It registers @var{func} as a signal handler for signal number
*************** particular signal, it will be called whe
*** 51,71 ****
  execution of the program will be suspended until the handler returns or
  calls @code{longjmp} (@pxref{longjmp}).
  
! You may pass SIG_DFL as the value of @var{func} to reset the signal
! handling for the signal @var{sig} to default (also
  @xref{__djgpp_exception_toggle}, for a quick way to restore all the
! signals' handling to default), SIG_ERR to force an error when that
! signal happens, or SIG_IGN to ignore that signal.  Signal handlers that
! you write are regular C functions, and may call any function that the
! ANSI/POSIX specs say are valid for signal handlers.  For maximum
! portability, a handler for hardware interrupts and processor exceptions
! should only make calls to @code{signal}, assign values to data objects
! of type @code{volatile sig_atomic_t} (defined as @code{int} on
! @code{<signal.h>}) and return.  Handlers for hardware interrupts need
  also be locked in memory (so that the operation of virtual memory
! mechanism won't swap them out), @xref{__dpmi_lock_linear_region, 
! locking memory regions}.  Handlers for software interrupts can also
! terminate by calling @code{abort}, @code{exit} or @code{longjmp}.
  
  The following signals are defined on @code{<signal.h>}:
  
--- 53,73 ----
  execution of the program will be suspended until the handler returns or
  calls @code{longjmp} (@pxref{longjmp}).
  
! You may pass @code{SIG_DFL} as the value of @var{func} to reset the
! signal handling for the signal @var{sig} to default (also
  @xref{__djgpp_exception_toggle}, for a quick way to restore all the
! signals' handling to default), @code{SIG_ERR} to force an error when
! that signal happens, or @code{SIG_IGN} to ignore that signal.  Signal
! handlers that you write are regular C functions, and may call any
! function that the ANSI/POSIX specs say are valid for signal handlers.
! For maximum portability, a handler for hardware interrupts and processor
! exceptions should only make calls to @code{signal}, assign values to
! data objects of type @code{volatile sig_atomic_t} (defined as @code{int}
! on @code{<signal.h>}) and return.  Handlers for hardware interrupts need
  also be locked in memory (so that the operation of virtual memory
! mechanism won't swap them out), @xref{__dpmi_lock_linear_region, locking
! memory regions}.  Handlers for software interrupts can also terminate by
! calling @code{abort}, @code{exit} or @code{longjmp}.
  
  The following signals are defined on @code{<signal.h>}:
  
*************** unknown/invalid exceptions.
*** 90,97 ****
  
  @item SIGINT
  
! The Interrupt signal.  Generated when a @kbd{Ctrl-C} or @kbd{Ctrl-Break}
! (Int 1Bh) key is hit.  Note that when you open the console in binary
  mode, or switch it to binary mode by a call to @code{setmode}
  (@pxref{setmode}), generation of @code{SIGINT} as result of @kbd{Ctrl-C}
  key is disabled.  This is so for programs (such as Emacs) which want to
--- 92,100 ----
  
  @item SIGINT
  
! The Interrupt signal.  Generated when an INTR key (@kbd{Ctrl-C} by
! default) or @kbd{Ctrl- AT key{BREAK}} (Int 1Bh) key is hit.
! Note that when you open the console in binary
  mode, or switch it to binary mode by a call to @code{setmode}
  (@pxref{setmode}), generation of @code{SIGINT} as result of @kbd{Ctrl-C}
  key is disabled.  This is so for programs (such as Emacs) which want to
*************** be able to read the @samp{^C} character 
*** 99,110 ****
  library function @code{__djgpp_set_ctrl_c} to restore @code{SIGINT}
  generation when @kbd{Ctrl-C} is hit, if you need this.
  @xref{__djgpp_set_ctrl_c}, for details on how this should be done.
! @kbd{Ctrl-Break} always generates @code{SIGINT}.
  
  DJGPP hooks the keyboard hardware interrupt (Int 09h) to be able to
  generate @code{SIGINT} in response to @kbd{Ctrl-C} key; you should be
  aware of this when you install a handler for the keyboard interrupt.
  
  @item SIGSEGV
  
  The invalid storage access (Segmentation Violation) signal.  Generated
--- 102,117 ----
  library function @code{__djgpp_set_ctrl_c} to restore @code{SIGINT}
  generation when @kbd{Ctrl-C} is hit, if you need this.
  @xref{__djgpp_set_ctrl_c}, for details on how this should be done.
! @kbd{Ctrl- AT key{BREAK}} always generates @code{SIGINT}.
  
  DJGPP hooks the keyboard hardware interrupt (Int 09h) to be able to
  generate @code{SIGINT} in response to @kbd{Ctrl-C} key; you should be
  aware of this when you install a handler for the keyboard interrupt.
  
+ Note that the key which generates @code{SIGINT} can be changed with a
+ call to @code{__djgpp_set_sigint_key} function.
+ @xref{__djgpp_set_sigint_key}.
+ 
  @item SIGSEGV
  
  The invalid storage access (Segmentation Violation) signal.  Generated
*************** The Broken Pipe signal.  Currently unuse
*** 144,150 ****
  
  @item SIGQUIT
  
! The Quit signal.  Currently unused.
  
  @item SIGUSR1
  
--- 151,160 ----
  
  @item SIGQUIT
  
! The Quit signal.  Generated when the QUIT key (@kbd{Ctrl-\} by default)
! is hit.  The key that raises the signal can be changed with a call to
! @code{__djgpp_set_sigquit_key} function.
! @xref{__djgpp_set_sigquit_key}.
  
  @item SIGUSR1
  
*************** int __djgpp_set_ctrl_c(int enable);
*** 218,239 ****
  
  @subheading Description
  
! This function sets and resets the bit which controls whether
! @code{SIGINT} (@pxref{signal, SIGINT}) will be raised when you press
! @kbd{Ctrl-C}.  By default @kbd{Ctrl-C} generates an interrupt signal
  which, if uncaught by a signal handler, will abort your program.
  However, when you call the @code{setmode} library function to switch the
  console reads to binary mode, or open the console in binary mode for
! reading, this generation of interrupt signal is turned off, because some
! programs want to get the @samp{^C} characters as any other character and
! handle them by themselves.
  
  @code{__djgpp_set_ctrl_c} lets you explicitly determine the effect of
! @kbd{Ctrl-C}.  When called with non-zero value of @var{enable}, it
! arranges for @kbd{Ctrl-C} to generate an interrupt; if you call it with
! a zero in @var{enable}, @kbd{Ctrl-C} are treated as normal characters.
  
! Note that the effect of @kbd{Ctrl-Break} key is unaffected by this
  function; use the @code{_go32_want_ctrl_break} library function to
  control it.
  
--- 228,253 ----
  
  @subheading Description
  
! This function sets and resets the bit which controls whether signals
! @code{SIGINT} and @code{SIGQUIT} (@pxref{signal}) will be raised when
! you press the INTR or QUIT keys.  By default these generate signals
  which, if uncaught by a signal handler, will abort your program.
  However, when you call the @code{setmode} library function to switch the
  console reads to binary mode, or open the console in binary mode for
! reading, this generation of signals is turned off, because some
! programs want to get the @samp{^C} and @samp{^\} characters as any other
! character and handle them by themselves.
  
  @code{__djgpp_set_ctrl_c} lets you explicitly determine the effect of
! INTR and QUIT keys.  When called with non-zero value of
! @var{enable}, it arranges for @code{SIGINT} and @code{SIGQUIT} signals
! to be generated when the appropriate key is pressed; if you call it with
! a zero in @var{enable}, these keys are treated as normal characters.
! 
! For getting similar effects via the POSIX @code{termios} functions, see
! @ref{tcsetattr}.
  
! Note that the effect of @kbd{Ctrl- AT key{BREAK}} key is unaffected by this
  function; use the @code{_go32_want_ctrl_break} library function to
  control it.
  
*************** returns.
*** 246,253 ****
  
  @subheading Return Value
  
! The previous state of the @kbd{Ctrl-C} effect: 0 if the generation of
! @code{SIGINT} by @kbd{Ctrl-C} was disabled, 1 if it was enabled.
  
  @subheading Example
  
--- 260,267 ----
  
  @subheading Return Value
  
! The previous state of @code{SIGINT} and @code{SIGQUIT} generation: 0 if
! it was disabled, 1 if it was enabled.
  
  @subheading Example
  
*************** also passed to the parent).
*** 291,295 ****
--- 305,465 ----
    __djgpp_exception_toggle();
    system("myprog");
    __djgpp_exception_toggle();
+ 
+ @end example
+ 
+ @c -------------------------------------------------------------------------
+ 
+ @node __djgpp_set_sigint_key, signal
+ @subheading Syntax
+ 
+ @example
+ 
+ #include <sys/exceptn.h>
+ 
+ void __djgpp_set_sigint_key(int new_key);
+ 
+ @end example
+ 
+ 
+ @subheading Description
+ 
+ This function changes the INTR key that generates the signal
+ @code{SIGINT}.  By default, @kbd{Ctrl-C} is set as the INTR key.  To
+ replace it with another key, put the @emph{scan code} of the new INTR
+ key into the bits 0-7 and the required keyboard status byte into bits
+ 8-15 of @var{new_key}, and call this function.  Here's how the keyboard
+ status bits are defined:
+ 
+ @example
+ 
+    Bit
+  76543210    Meaning
+ 
+  .......X    Right Shift key
+  ......X.    Left Shift key
+  .....X..    Ctrl key
+  ....X...    Alt key
+  ...X....    Scroll Lock key
+  ..X.....    Num Lock key
+  .X......    Caps Lock key
+  X.......    Insert
+ 
+ @end example
+ 
+ @noindent
+ A 1 in any of the above bits means that the corresponding key should be
+ pressed; a zero means it should be released.  Currently, all but the
+ lower 4 bits are always ignored by the DJGPP keyboard handler when
+ you set the INTR key using this function.
+ 
+ For example, the default @kbd{Ctrl-C} key should be passed as
+ @code{0x042e}, since the scan code of the @key{C} key is 2Eh, and when
+ the @key{Ctrl} key is pressed, the keyboard status byte is 04h.
+ 
+ To disable @code{SIGINT} generation, pass zero as the argument (since no
+ key has a zero scan code).
+ 
+ This function will set things up so that the left @key{Shift} key
+ doesn't affect Ctrl- and Alt-modified keys; the right @key{Shift} key
+ won't affect them either, unless its bit is explicitly set in
+ @var{new_key}.  This means that @kbd{Ctrl-C} and @kbd{Ctrl-c} will both
+ trigger @code{SIGINT} if @code{0x042e} is passed to this function.
+ 
+ The DJGPP built-in keyboard handler pretends that when the right
+ @key{Shift} key is pressed, so is the left @key{Shift} key (but not vice
+ versa).
+ 
+ For getting similar effects via the POSIX @code{termios} functions, see
+ @ref{tcsetattr}.
+ 
+ @subheading Return Value
+ 
+ The previous INTR key (scan code in bits 0-7, keyboad status in bits
+ 8-15).
+ 
+ @subheading Example
+ 
+ @example
+ 
+   __djgpp_set_sigint_key(0x0422);  /* make Ctrl-g generate SIGINT's */
+ 
+ @end example
+ 
+ @c -------------------------------------------------------------------------
+ 
+ @node __djgpp_set_sigquit_key, signal
+ @subheading Syntax
+ 
+ @example
+ 
+ #include <sys/exceptn.h>
+ 
+ void __djgpp_set_sigquit_key(int new_key);
+ 
+ @end example
+ 
+ 
+ @subheading Description
+ 
+ This function changes the QUIT key that generates the signal
+ @code{SIGQUIT}.  By default, @kbd{Ctrl-\} is set as the QUIT key.  To
+ replace it with another key, put the @emph{scan code} of the new QUIT
+ key into the bits 0-7 and the required keyboard status byte into bits
+ 8-15 of @var{new_key}, and call this function.  Here's how the keyboard
+ status bits are defined:
+ 
+ @example
+ 
+    Bit
+  76543210    Meaning
+ 
+  .......X    Right Shift key
+  ......X.    Left Shift key
+  .....X..    Ctrl key
+  ....X...    Alt key
+  ...X....    Scroll Lock key
+  ..X.....    Num Lock key
+  .X......    Caps Lock key
+  X.......    Insert
+ 
+ @end example
+ 
+ @noindent
+ A 1 in any of the above bits means that the corresponding key should be
+ pressed; a zero means it should be released.  Currently, all but the
+ lower 4 bits are always ignored by the DJGPP keyboard handler when
+ you set the QUIT key with this function.
+ 
+ For example, the default @kbd{Ctrl-\} key should be passed as
+ @code{0x042b}, since the scan code of @code{\} is 2Bh and when the
+ @key{Ctrl} key is pressed, the keyboard status byte is 04h.
+ 
+ To disable @code{SIGQUIT} generation, pass zero as the argument (since
+ no key has a zero scan code).
+ 
+ This function will set things up so that the left @key{Shift} key
+ doesn't affect Ctrl- and Alt-modified keys; the right @key{Shift} key
+ won't affect them either, unless its bit is explicitly set in
+ @var{new_key}.  This means that @kbd{Ctrl-\} and @kbd{Ctrl-|} will both
+ trigger @code{SIGQUIT} if @code{0x042b} is passed to this function.
+ 
+ The DJGPP built-in keyboard handler pretends that when the right
+ @key{Shift} key is pressed, so is the left @key{Shift} key (but not vice
+ versa).
+ 
+ For getting similar effects via the POSIX @code{termios} functions, see
+ @ref{tcsetattr}.
+ 
+ @subheading Return Value
+ 
+ The previous QUIT key (scan code in bits 0-7, keyboad status in bits
+ 8-15).
+ 
+ @subheading Example
+ 
+ @example
+ 
+   __djgpp_set_sigint_key(0);  /* disable SIGQUIT's */
  
  @end example

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019