Chapter Contents

Previous

Next
sigdef

SAS/C Library Routines for Adding New Signals

The library provides two routines (L$CZSYN and L$CZENQ) that can communicate to the library that a user-defined signal has occurred. These routines should be called from the signal generating routine, which is normally written in assembler language. The library expects calls to these routines from assembler language and fully supports them.


Routine for Synchronous Signals: L$CZSYN

When you call L$CZSYN to inform the library of a synchronous signal, register 12 must address the CRAB, and register 13 must address the current C DSA. Register 1 addresses an argument list described by the following DSECT:

ZSYNARGS  DSECT

SIGNUM    DS F   signal number
SIGINFO   DS A   address of associated information
ABCODE    DS A   pointer to associated ABEND code (null-terminated),
                 if any
SIGNAME   DS A   pointer to five-character signal name
SIGLOC    DS A   pointer to the interrupted instruction
JUMPINT   DS A   address of a jump intercept routine, if needed

You must provide all of the information for these fields. The fields are described as follows:
SIGNUM contains the number of the signal.
SIGINFO contains a pointer to the value that will be made available to the signal handler with the siginfo function. Refer to Chapter 5, "Signal-Handling Functions," in SAS/C Library Reference, Volume 1 for more information on siginfo .

The signal-generating routine builds this information and stores the address in this field. Then the address is passed to the executive routine for the signal, if any. The executive routine may want to modify or make a copy of this information. For example, you might pass L$CZSYN the address of a system control block. The executive routine can make a copy of it to pass to the user-defined handler. This stops the user from attempting to modify the control block.

ABCODE can be 0 or it can contain the address of a string that contains an ABEND code associated with the signal. The ABEND code should be null-terminated and should begin with a 'U' if it is a user ABEND rather than a system ABEND. For example, if you define a signal associated with exceeding a CPU-time quota, you probably would define ABCODE as "322" because that is the ABEND code normally produced by this condition.
SIGNAME contains the address of the five-character string passed as the last argument in the call to sigdef . These five characters are appended to SIG to form a new name that replaces the standard name, SIGUSR1- 8 .
SIGLOC should contain the address in the C program where processing was interrupted. This address is used in tracebacks if an ABEND occurs or the debugger where command is used. If you cannot provide this information, set this field to NULL .
JUMPINT can provide a jump intercept routine. The normal use of a jump intercept routine is to inform the operating system that the interrupt has been handled. Set this field to 0 if you have not coded a jump intercept routine. Refer to the Jump Intercept Routine for more information on this routine.

L$CZSYN returns either a 0 or a 4 in register 15 unless handling of the signal is terminated by a longjmp , in which case no return occurs. If L$CZSYN returns a 4, the signal cannot be processed because one or more of the restrictions on the timing of synchronous signals is violated. Refer to Restrictions on Synchronous and Asynchronous Signals for more information. If L$CZSYN returns a 0, the signal is accepted, and a user-defined signal handler is called and returned. In either case, the signal generation routine should return to the operating system.


Routine for Asynchronous Signals: L$CZENQ

The L$CZENQ routine can be called at any time to inform the library that an asynchronous signal has occurred. Unlike L$CZSYN, L$CZENQ does not cause a handler to be immediately called. Instead, L$CZENQ adds the signal to an internal queue of pending signals. No handler is called until the signal can be discovered; discovery occurs when a function is called or returns and the signal is not blocked. L$CZENQ can be called in situations where normal C code cannot be executed, such as under an SRB or a subtask TCB in OS/390, or from a CMS interrupt handler. L$CZENQ is reliable whether or not hardware interrupts are disabled at the time it is called. Recursive interrupts and simultaneous interrupts in a multitasking or multiprocessing environment are supported.

The address of L$CZENQ is located at offset X'1F4' (decimal 500) from the start of the CRAB. Linkage to L$CZENQ should be effected using this CRAB field, not a V-type address constant. Using a V-type constant works only if the calling routine is linked with the main load module of the application program.

The following shows the use of various registers by L$CZENQ:

Register Use
1 addresses parameter list ZENQARGS
2-6 work registers; save contents before calling L$CZENQ
12 must address CRAB
13 ignored; no registers saved by L$CZENQ
14 contains return address
15 contains address of L$CZENQ

The parameter list addressed by register 1 is described by the following DSECT:

ZENQARGS  DSECT

SIGNUM    DS F   signal number
SIGINFO   DS A   address of associated information
ABCODE    DS A   pointer to associated ABEND code (null-terminated),
                 if any
SIGNAME   DS A   pointer to five-character signal name
SIGELEM   DS A   address of an interrupt element
ECBPP     DS A   address of a word in which to store an ECB address

The first four fields have the same meaning as the corresponding fields in L$CZSYN. The SIGELEM and ECBPP fields should be used as follows:
SIGELEM is required. It must address a 24-byte area of storage that can be used as an interrupt element by L$CZENQ. Under OS/390, this element must be allocated by GETMAIN from subpool 1. Under CMS, this element must be allocated through use of CMSSTOR (or DMSFREE under 370 mode CMS). The element must be accessible using a 24-bit address. The element is freed by the run-time library after processing of this signal is complete.
ECBPP can address a word of memory or can contain 0s. If ECBPP is not 0, and the program is executing pause , sigpause , sigsuspend , or sleep at the time of the call to L$CZENQ, the address of the Event Control Block (ECG) used by pause , sigpause , sigsuspend , and sleep is stored in the word addressed by ECBPP. If ECBPP is 0, the ECB address is not stored; instead, the ECB is posted using SVC 2. Therefore, if you call L$CZENQ in a situation where SVC's cannot be issued (such as from an SRB routine or I/O appendage), you must provide an ECBPP value. Note that pause , sigpause , sigsuspend , and sleep do not complete until this ECB is posted. For this reason, in such cases you would normally call a branch entry to POST to awaken the C program.

L$CZENQ does not have a return code because L$CZENQ cannot fail without causing abnormal program termination.


Chapter Contents

Previous

Next

Top of Page

Copyright © 2001 by SAS Institute Inc., Cary, NC, USA. All rights reserved.