Skip to main content
Previous sectionNext section

Special Considerations for UNIX® and Related Operating Systems

Some system calls may fail if the process receives a signal, the most common being: open, read, write, close, ioctl, and pause.

If the function uses any of these system calls, you have to code carefully to be able to distinguish among real errors, a Ctrl-C, and a call that should be restarted. A small set of functions was created to allow you to check for asynchronous events and to set a new alarm handler in $ZF.

Additional Call-Out Signal Processing

The function declarations are included in cdzf.h:

  • int sigrtclr(); — Clears retry flag. Should be called once before using sigrtchk().

  • int dzfalarm(); — Establishes new SIGALRM handler.

    On entry to $ZF, the previous handler is automatically saved. On exit, it is restored automatically. A user program should not alter the handling of any other signal.

  • int sigrtchk(); — Checks for asynchronous events. Should be called whenever one of the following system calls fails: open, close, read, write, ioctl, pause, or any call that fails when the process receives a signal. It returns a code indicating the action that the user should take:

    • -1 — Not a signal. Check for I/O error. See contents of errno variable.

    • 0 — Other signal. Restart operation from point at which it was interrupted.

    • 1 — SIGINT/SIGTERM. Exit from $ZF with a SIGTERM "return 0". These signals are trapped appropriately.

A typical $ZF function used to control some device would use logic similar to the following pseudo-code:

if ((fd = open(DEV_NAME, DEV_MODE)) < 0) {
    Set some flags
    Call zferror
    return 0;
}
Copy code to clipboard

The open system call may fail if the process receives a signal. Usually this situation is not an error and the operation should be restarted. Depending on the signal, however, you might take other actions. So, in order to take account of all the possibilities, consider using the following code:

sigrtclr();
while (TRUE) {
    if (sigrtchk() == 1) return 1 or 0;
    if ((fd = open(DEV_NAME, DEV_MODE)) < 0) {
        switch (sigrtchk()) {
             case -1:
                /* This is probably a real device error */
                Set some flags
                Call zferror
                return 0;
            case 0:
                /* A innocuous signal was received. Restart. */
                continue;
            case 1:
                /* Someone is trying to terminate the job. */
                Do cleanup work
                return 1 or 0;
        }
    }
    else break;
}
/*
Code to handle the normal situation:
open() system call succeeded
*/
Copy code to clipboard

Remember you must not set any signal handler except via dzfalarm.