KnowledgeBase Archive

An Archive of Early Microsoft KnowledgeBase Articles

View on GitHub

Q35297: Differences between C signal() Function and DosSetSigHandler

Article: Q35297
Product(s): See article
Version(s): 5.10
Operating System(s): OS/2
Keyword(s): ENDUSER | | mspl13_c
Last Modified: 12-OCT-1988

Question:

I have some questions concerning signal handling in OS/2, and
differences between the C run-time library signal() function and the
OS/2 API routine DosSetSigHandler. What are the differences; what are
the results of using these routines?

Response:

Under OS/2, the C run-time library signal() function has fewer options
and different behavior than the OS/2 API DosSetSigHandler function.
The signal() function is described in the next few paragraphs, then
the features of DosSetSigHandler are explained.

Features of the C Run-Time Library Signal() Function in OS/2

The C run-time library signal() function only is for use in
single-thread applications, and for floating-point exception handling
in Dynamic Link Libraries.

Using strictly C run-time functions, such as signal() and spawnlp(),
signal handling in OS/2 is accomplished (or not, by default) by thread
1 of each process. This behavior occurs whether the process was invoked
from the operating system or was spawned by another process.

As a result, while this process is running, a child process is
unaffected by how its parent handles signals; if a signal is generated
during the execution of the child, the child either handles it with
its own signal handler, or if it was spawned with P_WAIT or P_NOWAIT,
control returns to the parent process. (However, no control returns to
the parent process's signal handler, which is unlike the
DosSetSigHandler's effect.) Once the parent resumes execution, its
signal handler once again will be in effect for any newly generated
signals.

For example, say a parent process sets up a signal handler, then
spawns MAKE. While running MAKE, if a CTRL+C signal occurs, either the
process spawned by MAKE such as the CL driver, or MAKE itself will be
interrupted. If CL is interrupted by CTRL+C, it returns an error to
MAKE and MAKE terminates. If MAKE itself is interrupted, it
terminates. In either case, control will be returned to the parent
process after the point where it spawned MAKE, and the parent resumes
execution. The parent's signal handler will handle signals generated
after it starts executing again, but none of the signals generated by
the child are kept by the system and returned to the parent.

If both the parent and child have no signal handler, if the child is
spawned with P_WAIT or P_NOWAIT and it is terminated without hanging
the system, then control goes back to the parent. The parent continues
executing until it is terminated.

Features of OS/2's DosSetSigHandler

The OS/2 API routine DosSetSigHandler has more options than the C
run-time library signal() function. A child process will inherit
(i.e., use) the parent's signal handler, or the closest ancestor's
defined signal handler if its immediate parent didn't create one.

If the parent called DosSetSigHandler to handle CTRL+C with Action = 0
(install the system default action, in this case to terminate the
process), a CTRL+C issued in the parent or child will use the parent's
handler. If the CTRL+C occurred in the child, the child will be
terminated (by default) when the parent's signal handler is called.
The parent will resume execution after its signal handler function is
completed in a similar manner to DOS. However, the child may install
its own signal handler rather than using the parent's.

If you use Action = 2 (install the specified signal handler
for the given signal) for handling CTRL+C in the parent process,
hitting CTRL+C in its child causes the child to pause while the
handler is executed; however, the child won't terminate. For Action =
1 (ignore signal) in a DosSetSigHandler call by the parent for CTRL+C,
CTRL+C is ignored in the child as well as the parent.

If neither parent nor child sets up a signal handler, CTRL+C will kill
them all regardless of which process gets the CTRL+C. This action
occurs because signal handlers are being inherited, and signals are
either handled in the current process if it has a handler, or
effectively passed back up the process subtree (from child to parent)
until a process is reached that has a CTRL+C signal handler.

Because the default action for CTRL+C is to terminate the process, a
process without a CTRL+C handler gets terminated, and the CTRL+C
signal effectively gets passed up to its parent. If the parent doesn't
have a CTRL+C handler, it terminates and passes control to its parent.
If no one set up a signal handler, the original parent at the root of
the process subtree handles the signal, and the default action is to
return to the system.

Some precautions for signal handling are recommended. After setting up
a signal handler, avoid making system calls from thread 1, especially
time-consuming calls such as waiting for keyboard input or some other
event. If OS/2 is executing code for a system call at Ring 0, it
cannot run a signal handler at Ring 3. Instead, executing the system
code is completed, or aborted if it is a time-consuming call (which
could result in incomplete I/O), and then the signal is handled.

Another particularly bad scenario is if thread 1 blocks a critical
section of code with a RAM semaphore, is interrupted and handles a
signal, and then the signal handler resumes execution elsewhere so
that the RAM semaphore is not cleared and the critical section remains
blocked. If thread 1 must run critical sections of code, it should
call DosHoldSignal to disable the signal prior to entering the
critical section.

THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Copyright Microsoft Corporation 1986-2002.