#include <lclib.h> int atfork(void *anyData, void(*preExit)(void *), void(*parentExit)(void *), void(*childExit)(void *));
atfork
defines up to three fork exits that are called
by the library during the execution of the fork
function.
The arguments to atfork
are:
anyData
void
pointer that is passed to the three fork exits. This
pointer can be used to pass the address of a structure
that is then cast to an appropriate type within the exit functions.
preExit
fork
system call is issued. An address of 0
indicates that no function
is defined.
parentExit
fork
is complete. An address of 0
indicates
that no function
is defined.
childExit
fork
is complete. An address of 0
indicates
that no function
is defined.
anyData
, is passed to all
three exit functions. This enables the sharing of data between
the three functions, and it also enables you to pass information
from the function pointed to by preExit
to either
of the functions pointed to by parentExit
and
childExit
.
atfork
exits may be conveniently used to checkpoint and
restore data that is not preserved over the fork: for example,
names of open MVS files.
atfork
returns a 0
if successful and a -1
if unsuccessful.
vsamin
. This program would also use fork
to
create new
processes that
continue to run the same application. (That is, they do not call
exec
.)
Because VSAM files are not supported in the hierarchical file system,
when the
fork
is done the FILE
pointer referencing the
VSAM file will become
invalid in the child.
The example uses atfork
as follows:
fnm
and osddinfo
functions.
osddinfo
is necessary, since the child process will not
have the DD statement allocated.
Note:
This example must not be compiled with the posix
option.
#include <sys/types.h> #include <unistd.h> #include <lclib.h> #include <lcio.h> #include <string.h> #include <os.h> extern FILE *vsamin; static void pre_parent(void *), post_child(void *); int setup(void) { static char vsamdsn[49]; return atfork(vsamdsn, &pre_parent, 0, &post_child); } static void pre_parent(void *atfork_arg) { char *vsamdsn = atfork_arg; char *filename; int rc; if (!vsamin) return; filename = fnm(vsamin); /* Find VSAM file name. */ strcpy(vsamdsn, filename); /* Copy file name to buffer. */ strlwr(vsamdsn); if (strncmp(vsamdsn, "ddn:", 4) == 0) filename = filename+4; /* Skip ddn prefix. */ else if (strncmp(vsamdsn, "dsn:", 4) == 0 || strncmp(vsamdsn, "tso:", 4) == 0) return; /* all done if cms or tso file */ memcpy(vsamdsn, "dsn:", 4); /* Make file name dsn form. */ rc = osddinfo(filename, vsamdsn+4, NULL, NULL, NULL, NULL); /* Extract dsname. */ if (rc != 0) vsamdsn[0] = '0'; /* If dsn unavail., remove name. */ return; } static void post_child(void *atfork_arg) { char *vsamdsn = atfork_arg; if (*vsamdsn) { /* If a filename was found. */ freopen(vsamdsn, "rk", vsamin); } /* Reopen vsamin to same file, */ else { /* else close it */ if (vsamin) fclose(vsamin); vsamin = 0; /* and zero file pointer. */ } return; }
fork
Copyright (c) 1998 SAS Institute Inc. Cary, NC, USA. All rights reserved.