Chapter Contents

Previous

Next
sigblkjmp

sigblkjmp



Intercept longjmp without Changing Signal Mask

Portability: SAS/C extension


SYNOPSIS
DESCRIPTION
RETURN VALUE
CAUTION
EXAMPLE
RELATED FUNCTIONS


SYNOPSIS

#include <lcjmp.h>
int sigblkjmp(sigjmp_buf env);


DESCRIPTION

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

Note:   When a siglongjmp call is intercepted due to the use of sigblkjmp , the signal mask has not yet been changed.  [cautionend]

After a call to longjmp or siglongjmp is intercepted, sigblkjmp must be re-issued if continued interception is wanted.

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


RETURN VALUE

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


CAUTION

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


EXAMPLE

This example demonstrates how sigblkjmp can be used to enable a function to release resources even if terminated by a call to longjmp or siglongjmp in a function that sigblkjmp calls:

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

sigjmp_buf env;

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

int main()
{
  int code;
  if (code = sigsetjmp(env,1)) 
    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;
  sigjmp_buf my_env;
  sigset_t blockall, oldset;

  sigfillset(&blockall);
  /* block all signals while allocating 
     and using resource */
  sigprocmask(SIG_SETMASK, &blockall, 
              &oldset);

  /* Allocate resource here */
  if (code = sigblkjmp(my_env)) 
    goto release;

  puts("Resources allocated.");
  /* Free resource here */
  use_resource();
  puts("use_resource returned normally, "
    "get_resource is freeing resources.");
  setprocmask(SIG_SETMASK, &oldset, NULL);
  return;
 release:

  printf("use_resource indicated ", 
         "error %d\n", code);
  puts("Resources now freed, proceeding ",
       "with longjmp.");
  siglongjmp(my_env, code);
}

static void use_resource(void)
{
  puts("Entering use_resource.");
  /* Attempt to use resource here. */
  puts("Error 3 detected, ",
       "calling siglongjmp.");
  siglongjmp(env, 3);
  puts("This statement will not ",
       "be executed.");
}


RELATED FUNCTIONS

blkjmp , longjmp , setjmp , siglongjmp , sigsetjmp


Chapter Contents

Previous

Next

Top of Page

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