Chapter Contents

Previous

Next
blkjmp

blkjmp



Intercept Nonlocal gotos

Portability: SAS/C extension


SYNOPSIS
DESCRIPTION
RETURN VALUE
CAUTION
EXAMPLE
RELATED FUNCTIONS
SEE ALSO


SYNOPSIS

#include <lcjmp.h>

int blkjmp(jmp_buf env);


DESCRIPTION

blkjmp requests interception of calls to longjmp that could terminate the calling function. When you call blkjmp , it always returns 0. If a call to longjmp is later intercepted, the call to blkjmp is resumed and it then returns the integer argument that was passed to longjmp . The env variable is modified to indicate the target of the intercepted longjmp so that it can be reissued by the intercepting routine.

After a call to longjmp is intercepted, blkjmp must be reissued if continued interception is wanted.

Because exit is implemented as a longjmp to the caller of main , you can use blkjmp to intercept program exit.

The sigsetjmp and siglongjmp functions, introduced in SAS/C Release 6.00, allow the signal mask to be saved as part of a setjmp operation, and restored as part of a longjmp operation. In the 6.00 implementation, siglongjmp restored the signal mask before searching the stack for blkjmp callers.

This meant that the old signal mask was restored before any caller of blkjmp received control to intercept the jump. Since in most cases the restored signal mask allows more signals than the old signal mask, this had the effect of allowing a signal to be discovered in a blkjmp cleanup routine, thereby causing part of the cleanup to be bypassed.

The 6.50 version of the library modifies siglongjmp so that the signal mask is changed as late as possible. If there is no interference from blkjmp callers, the signal mask is changed immediately before control is returned to the target sigsetjmp call.

As with the 6.00 library, if a call to siglongjmp is intercepted by blkjmp, the signal mask is restored immediately before control is returned to the blkjmp call.

Additionally, a new function called sigblkjmp has been defined. This function is an enhanced version of blkjmp, which stores the signal mask data associated with a siglongjmp in the buffer passed to sigblkjmp as well as the registers and other environmental information.

This means that the signal mask is not changed when control is given to a sigblkjmp cleanup routine. The mask is only changed when control passes to the original sigsetjmp call, or to a caller of the old blkjmp function.

Use of sigblkjmp rather than blkjmp is recommended in any program which uses sigsetjmp and siglongjmp.

Note:    Both blkjmp and sigblkjmp are compatible with both the setjmp and longjmp functions as well as with their sig- versions.  [cautionend]

When an application contains functions which execute in access register (AR) mode, the size of the jmp_buf used by the setjmp, longjmp, and blkjmp functions increases due to the need to save the access registers in a call to setjmp and restore them in a call to longjmp. If a function is compiled with the armode option, when the header file is included, logic within the header file generates an appropriate definition of the jmp_buf type.

Some applications may require a mixture of AR-mode and non-AR-mode functions. These programs require special care to avoid incompatible definitions. For example, a situation could occur where an external jmp_buf variable seems to be different sizes in different compilations. Also, if a function that is not compiled to run in AR mode intercepts a longjmp made by a caller in AR mode, the access register information can be lost or garbled, resulting in errors when the longjmp completes.

To prevent problems such as these, functions that use setjmp, longjmp, or blkjmp, and that may be combined with AR-mode functions, should include the header file . This header file defines the jmp_buf type and the longjmp family of functions in a way that will behave correctly whether or not the called function is compiled with AR mode. It can also be included in a program that does not use AR mode, although extra overhead will be introduced due to the need to maintain access register information.

Note:    <arjump.h> should be included only in an SPE application.   [cautionend]


RETURN VALUE

blkjmp normally returns 0; it returns a non-zero value if a call to longjmp has been intercepted (in which case, blkjmp returns the value of the second argument passed to longjmp ).


CAUTION

Variables of storage class auto and register whose values are changed between the blkjmp and longjmp calls have indeterminate values on return to blkjmp .


EXAMPLE

This example demonstrates how blkjmp can be used to enable a function to release resources, even if terminated by a call to longjmp in a function it calls:

#include <stdio.h>
#include <lcjmp.h>
#include <stdlib.h>

jmp_buf env;

static void get_resource(void), use_resource(void);

int main()
{
   int code;
   if (code = setjmp(env)) goto escape;
   get_resource();
   puts("get_resource returned normally.");
   exit(0);
      escape:
         printf("Executing escape routine for error %d\n", code);
         exit(code);
}

static void get_resource(void)
{
   int code;
   jmp_buf my_env;

      /* Allocate resource here.       */
   if (code = blkjmp(my_env)) goto release;
   puts("Resources allocated.");
      /* Free resource here.           */
   use_resource();
   puts("use_resource returned normally, "
        "get_resource is freeing resources.");
   return;
         /* Free resource here.        */
      release:
         printf("use_resource indicated error %d\n", code);
         puts("Resources now freed, proceeding with longjmp.");
         longjmp(my_env, code);
}

static void use_resource(void)
{
   puts("Entering use_resource");

      /* Attempt to use resource here. */
   puts("Error 3 detected, calling longjmp.");
   longjmp(env, 3);
   puts("This statement will not be executed.");
}


RELATED FUNCTIONS

longjmp , setjmp , siglongjmp , sigsetjmp


SEE ALSO


Chapter Contents

Previous

Next

Top of Page

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