atfork -- Define Fork Exits

SYNOPSIS

 #include <lclib.h>

 int atfork(void *anyData, void(*preExit)(void *),
            void(*parentExit)(void *), void(*childExit)(void *));
 

DESCRIPTION

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
is a 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
is a pointer to an exit function that is called before the fork system call is issued. An address of 0 indicates that no function is defined.
parentExit
is a pointer to an exit function that is called in the parent process after the fork is complete. An address of 0 indicates that no function is defined.
childExit
is a pointer to an exit function that is called in the child process after the fork is complete. An address of 0 indicates that no function is defined.
Notice that the same pointer, 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.

RETURN VALUE

atfork returns a 0 if successful and a -1 if unsuccessful.

EXAMPLE

This example is intended for use in a program that opens a VSAM file named 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:

  1. In the parent, to determine the name of the VSAM file using the fnm and osddinfo functions.
  2. In the child, to reopen the file using the name obtained by step 1.
Notice that if the original file name is a DDname, the use of 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;
  }

 

RELATED FUNCTIONS

fork


Copyright (c) 1998 SAS Institute Inc. Cary, NC, USA. All rights reserved.