ID Number: Q35297
5.10 6.00 6.00a
OS/2
Summary
In Microsoft C versions 5.1, 6.0, and 6.0a for OS/2, the C run-time
library signal() function has a more limited use than the OS/2 API
DosSetSigHandler function.
More Information:
Features of the C Run-Time Library Signal() Function in OS/2
------------------------------------------------------------
The C run-time library signal() function is for use only in
single-thread applications, and for floating-point exception handling
in dynamic-link libraries (DLLs).
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, 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 (that
is, 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 MS-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, pressing
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
terminate 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.
Additional reference words: 5.10 6.00 6.00a