334 lines
9.6 KiB
HTML
334 lines
9.6 KiB
HTML
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||
|
<html>
|
||
|
<head>
|
||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||
|
<meta name="Copyright" content="Copyright (c) 2006 by IBM Corporation">
|
||
|
<title>siglongjmp()--Perform Nonlocal Goto with Signal Handling</title>
|
||
|
<!-- All rights reserved. Licensed Materials Property of IBM -->
|
||
|
<!-- US Government Users Restricted Rights -->
|
||
|
<!-- Use, duplication or disclosure restricted by -->
|
||
|
<!-- GSA ADP Schedule Contract with IBM Corp. -->
|
||
|
<!-- Begin Header Records ========================================== -->
|
||
|
<!-- UNIX5 SCRIPT J converted by B2H R4.1 (346) (CMS) by V2KEA304 -->
|
||
|
<!-- at RCHVMW2 on 17 Feb 1999 at 11:05:09 -->
|
||
|
<!-- Edited by Kersten Feb 02 -->
|
||
|
<!--End Header Records -->
|
||
|
<link rel="stylesheet" type="text/css" href="../rzahg/ic.css">
|
||
|
</head>
|
||
|
<body>
|
||
|
<a name="Top_Of_Page"></a>
|
||
|
<!-- Java sync-link -->
|
||
|
<script type="text/javascript" language="Javascript" src="../rzahg/synch.js">
|
||
|
</script>
|
||
|
|
||
|
<h2>siglongjmp()--Perform Nonlocal Goto with Signal Handling</h2>
|
||
|
|
||
|
<div class="box" style="width: 60%;">
|
||
|
<br>
|
||
|
Syntax<br>
|
||
|
<pre>
|
||
|
#include <setjmp.h>
|
||
|
|
||
|
void siglongjmp( sigjmp_buf <em>env</em>, int <em>val</em> );
|
||
|
</pre>
|
||
|
|
||
|
<br>
|
||
|
Service Program Name: QPOSSRV1<br>
|
||
|
<!-- iddvc RMBR -->
|
||
|
<br>
|
||
|
Default Public Authority: *USE<br>
|
||
|
<!-- iddvc RMBR -->
|
||
|
<br>
|
||
|
Threadsafe: Yes<br>
|
||
|
<!-- iddvc RMBR -->
|
||
|
<br>
|
||
|
</div>
|
||
|
|
||
|
<p>The <strong>siglongjmp()</strong> function restores the stack environment
|
||
|
previously saved in <em>env</em> by <strong>sigsetjmp()</strong>.
|
||
|
<strong>siglongjmp()</strong> also provides the option to restore the signal
|
||
|
mask, depending on whether the signal mask was saved by
|
||
|
<strong>sigsetjmp()</strong>.</p>
|
||
|
|
||
|
<p><strong>siglongjmp()</strong> is similar to <strong>longjmp()</strong>,
|
||
|
except for the optional capability of restoring the signal mask.</p>
|
||
|
|
||
|
<p>The <strong>sigsetjmp()</strong> and <strong>siglongjmp()</strong> functions
|
||
|
provide a way to perform a nonlocal "goto."</p>
|
||
|
|
||
|
<p>A call to <strong>sigsetjmp()</strong> causes the current stack environment
|
||
|
(including, optionally, the signal mask) to be saved in <em>env</em>. A
|
||
|
subsequent call to <strong>siglongjmp()</strong> does the following:</p>
|
||
|
|
||
|
<ul>
|
||
|
<li>Restores the saved environment and signal mask (if saved by
|
||
|
<strong>sigsetjmp()</strong>).<br>
|
||
|
<br>
|
||
|
</li>
|
||
|
|
||
|
<li>Returns control to a point in the program corresponding to the
|
||
|
<strong>sigsetjmp()</strong> call.</li>
|
||
|
</ul>
|
||
|
|
||
|
<p>Processing resumes as if the <strong>sigsetjmp()</strong> call had just
|
||
|
returned the given <em>val</em>. All variables, (except register variables)
|
||
|
that are accessible to the function that receives control contain the values
|
||
|
they had when <strong>siglongjmp()</strong> was called. The values of register
|
||
|
variables are unpredictable. Nonvolatile auto variables that are changed
|
||
|
between calls to <strong>sigsetjmp()</strong> and <strong>siglongjmp()</strong>
|
||
|
are also unpredictable.</p>
|
||
|
|
||
|
<p><strong>Note:</strong> When using <strong>siglongjmp()</strong>, the
|
||
|
function in which the corresponding call to <strong>sigsetjmp()</strong> was
|
||
|
made must not have returned first. Unpredictable program behavior occurs if
|
||
|
<strong>siglongjmp()</strong> is called after the function calling
|
||
|
<strong>sigsetjmp()</strong> has returned.</p>
|
||
|
|
||
|
<p>The <em>val</em> argument passed to <strong>siglongjmp()</strong> must be
|
||
|
nonzero. If the <em>val</em> argument is equal to zero,
|
||
|
<strong>siglongjmp()</strong> substitutes a <samp>1</samp> in its place.</p>
|
||
|
|
||
|
<p><strong>siglongjmp()</strong> does not use the normal function call and
|
||
|
return mechanisms. <strong>siglongjmp()</strong> restores the saved signal mask
|
||
|
only if the <em>env</em> parameter was initialized by a call to
|
||
|
<strong>sigsetjmp()</strong> with a nonzero <em>savemask</em> argument.</p>
|
||
|
|
||
|
<br>
|
||
|
<!-- Please NOTE: DO NOT DELETE THIS SECTION if this API has no authorities and locks. -->
|
||
|
<!-- Instead, use the commented out coding below to indicate NONE. -->
|
||
|
<h3>Authorities and Locks</h3>
|
||
|
|
||
|
<!-- Use this if there are no authorities and locks. -->
|
||
|
<p>None.</p>
|
||
|
|
||
|
<br>
|
||
|
<h3>Parameters</h3>
|
||
|
|
||
|
<dl>
|
||
|
<dt><strong><em>env</em></strong></dt>
|
||
|
|
||
|
<dd>(Input) An array type that holds the information needed to restore a
|
||
|
calling environment.<br>
|
||
|
<br>
|
||
|
</dd>
|
||
|
|
||
|
<dt><strong><em>val</em></strong></dt>
|
||
|
|
||
|
<dd>(Input) The return value.</dd>
|
||
|
</dl>
|
||
|
|
||
|
<br>
|
||
|
<h3>Return Value</h3>
|
||
|
|
||
|
<p>None.</p>
|
||
|
|
||
|
<br>
|
||
|
<h3>Error Conditions</h3>
|
||
|
|
||
|
<p>The <strong>siglongjmp()</strong> function does not return an error.</p>
|
||
|
|
||
|
<br>
|
||
|
<h3>Usage Notes</h3>
|
||
|
|
||
|
<p>The <strong>sigsetjmp()</strong>-<strong>siglongjmp()</strong> pair and the
|
||
|
<strong>setjmp()</strong>-<strong>longjmp()</strong> pair cannot be intermixed.
|
||
|
A stack environment and signal mask saved by <strong>sigsetjmp()</strong> can
|
||
|
be restored only by <strong>siglongjmp()</strong>.</p>
|
||
|
|
||
|
<br>
|
||
|
<h3>Related Information</h3>
|
||
|
|
||
|
<ul>
|
||
|
<li>The <<strong>setjmp.h</strong>> file (see <a href="unix13.htm">Header
|
||
|
Files for UNIX-Type Functions</a>)<br>
|
||
|
<br>
|
||
|
</li>
|
||
|
|
||
|
<li><a href="sigactn.htm">sigaction()</a>--Examine and Change Signal Action<br>
|
||
|
<br>
|
||
|
</li>
|
||
|
|
||
|
<li><a href="sigpmsk.htm">sigprocmask()</a>--Examine and Change Blocked
|
||
|
Signals<br>
|
||
|
<br>
|
||
|
</li>
|
||
|
|
||
|
<li><a href="sigsetj.htm">sigsetjmp()</a>--Set Jump Point for Nonlocal Goto<br>
|
||
|
<br>
|
||
|
</li>
|
||
|
|
||
|
<li><a href="sigsusp.htm">sigsuspend()</a>--Wait for Signal<br>
|
||
|
<br>
|
||
|
</li>
|
||
|
|
||
|
<li><a href="sigsleep.htm">sleep()</a>--Suspend Processing for Interval of
|
||
|
Time</li>
|
||
|
</ul>
|
||
|
|
||
|
<br>
|
||
|
<h3>Example</h3>
|
||
|
|
||
|
<p>See <a href="../apiref/aboutapis.htm#codedisclaimer">Code disclaimer information</a>
|
||
|
for information pertaining to code examples.</p>
|
||
|
|
||
|
<p>This example saves the stack environment and signal mask at the following
|
||
|
statement:</p>
|
||
|
|
||
|
<pre>
|
||
|
if( sigsetjmp(mark,1) != 0 ) { ...
|
||
|
</pre>
|
||
|
|
||
|
<p>When the system first performs the <samp>if</samp> statement, it saves the
|
||
|
environment and signal mask in <em>mark</em> and sets the condition to false
|
||
|
because <strong>sigsetjmp()</strong> returns a <samp>0</samp> when it saves the
|
||
|
environment. The program prints the following message:</p>
|
||
|
|
||
|
<pre>
|
||
|
sigsetjmp() has been called
|
||
|
</pre>
|
||
|
|
||
|
<p>The subsequent call to function <strong>p()</strong> tests for a local error
|
||
|
condition, which can cause it to perform <strong>siglongjmp()</strong> (in this
|
||
|
example as a result of calling a signal catching function). Control is returned
|
||
|
to the original <strong>sigsetjmp()</strong> function using the environment
|
||
|
saved in <em>mark</em> and the restored signal mask. This time, the condition
|
||
|
is true because -<samp>1</samp> is the return value from
|
||
|
<strong>siglongjmp()</strong>. The program then performs the statements in the
|
||
|
block and prints the following:</p>
|
||
|
|
||
|
<pre>
|
||
|
siglongjmp() function was called
|
||
|
</pre>
|
||
|
|
||
|
<p>Then the program performs the <strong>recover()</strong> function and
|
||
|
exits.</p>
|
||
|
|
||
|
<p>Here is the program:</p>
|
||
|
|
||
|
<pre>
|
||
|
#include <signal.h>
|
||
|
#include <setjmp.h>
|
||
|
#include <unistd.h>
|
||
|
#include <stdio.h>
|
||
|
|
||
|
sigset_t sigset;
|
||
|
sigjmp_buf mark;
|
||
|
|
||
|
void catcher( int );
|
||
|
void p( void );
|
||
|
void recover( void );
|
||
|
|
||
|
int main( int argc, char *argv[] ) {
|
||
|
|
||
|
int result;
|
||
|
|
||
|
/*
|
||
|
* Block the SIGUSR1 and SIGUSR2 signals. This set of
|
||
|
* signals will be saved as part of the environment
|
||
|
* by the sigsetjmp() function.
|
||
|
*/
|
||
|
|
||
|
sigemptyset( &sigset );
|
||
|
sigaddset( &sigset, SIGUSR1 );
|
||
|
sigaddset( &sigset, SIGUSR2 );
|
||
|
sigprocmask( SIG_SETMASK, &sigset, NULL );
|
||
|
|
||
|
if( sigsetjmp( mark, 1 ) != 0 ) {
|
||
|
printf( "siglongjmp() function was called\n" );
|
||
|
recover();
|
||
|
result=0;
|
||
|
}
|
||
|
else {
|
||
|
printf( "sigsetjmp() has been called\n" );
|
||
|
p();
|
||
|
sigprocmask( SIG_SETMASK, NULL, &sigset );
|
||
|
if( sigismember( &sigset, SIGUSR2 ) )
|
||
|
printf( "siglongjmp() was not called\n" );
|
||
|
result=-1;
|
||
|
}
|
||
|
|
||
|
printf( "return to main with result %d\n", result );
|
||
|
|
||
|
return( result );
|
||
|
}
|
||
|
|
||
|
void p( void ) {
|
||
|
|
||
|
struct sigaction sigact;
|
||
|
int error=0;
|
||
|
|
||
|
printf( "performing function p()\n" );
|
||
|
|
||
|
/* Send signal handler in case error condition is detected */
|
||
|
|
||
|
sigemptyset( &sigact.sa_mask );
|
||
|
sigact.sa_flags = 0;
|
||
|
sigact.sa_handler = catcher;
|
||
|
sigaction( SIGUSR2, &sigact, NULL );
|
||
|
|
||
|
sigdelset( &sigset, SIGUSR2 );
|
||
|
sigprocmask( SIG_SETMASK, &sigset, NULL );
|
||
|
|
||
|
/* After some processing an error condition is detected */
|
||
|
|
||
|
error=-1;
|
||
|
|
||
|
/* Call catcher() function if error is detected */
|
||
|
|
||
|
if( error != 0 ) {
|
||
|
printf( "error condition detected, send SIGUSR2 signal\n" );
|
||
|
kill( getpid(), SIGUSR2 );
|
||
|
}
|
||
|
printf( "return from catcher() function is an error\n" );
|
||
|
}
|
||
|
|
||
|
void recover( void ) {
|
||
|
|
||
|
printf( "taking recovery action\n" );
|
||
|
|
||
|
sigprocmask( SIG_SETMASK, NULL, &sigset );
|
||
|
if( sigismember( &sigset, SIGUSR2 ) )
|
||
|
printf( "signal mask was restored after siglongjmp()\n" );
|
||
|
}
|
||
|
|
||
|
void catcher( int signo ) {
|
||
|
|
||
|
printf( "in catcher() before siglongjmp()\n" );
|
||
|
|
||
|
siglongjmp( mark, -1 );
|
||
|
|
||
|
printf( "in catcher() after siglongjmp() is an error\n" );
|
||
|
|
||
|
}
|
||
|
|
||
|
</pre>
|
||
|
|
||
|
<br>
|
||
|
<h3>Output</h3>
|
||
|
|
||
|
<pre>
|
||
|
sigsetjmp() has been called
|
||
|
performing function p()
|
||
|
error condition detected, send SIGUSR2 signal
|
||
|
in catcher() before siglongjmp()
|
||
|
siglongjmp() function was called
|
||
|
taking recovery action
|
||
|
signal mask was restored after siglongjmp()
|
||
|
return to main with result 0
|
||
|
</pre>
|
||
|
|
||
|
<br>
|
||
|
<hr>
|
||
|
API introduced: V3R6
|
||
|
|
||
|
<hr>
|
||
|
<center><table cellpadding="2" cellspacing="2">
|
||
|
<tr align="center">
|
||
|
<td valign="middle" align="center"><a href="#Top_Of_Page">Top</a> | <a href=
|
||
|
"unix.htm">UNIX-Type APIs</a> | <a href="aplist.htm">APIs by category</a> </td>
|
||
|
</tr>
|
||
|
</table>
|
||
|
</center></body>
|
||
|
</html>
|
||
|
|