
#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.