INF:Differences Between signal() and DosSetSigHandler() in OS2

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