Home | History | Annotate | Download | only in pthread_atfork
      1 /*
      2  * Copyright (c) 2002, Intel Corporation. All rights reserved.
      3  * Created by:  rolla.n.selbak REMOVE-THIS AT intel DOT com
      4  * This file is licensed under the GPL license.  For the full content
      5  * of this license, see the COPYING file at the top level of this
      6  * source tree.
      7  *
      8  * int pthread_atfork(void (*prepare) (void), void (*parent) (void), void (*child) (void))
      9  *
     10  *  shall declare fork handlers to be called before and after a fork() command, in the context
     11  *  of the thread that called the fork().  The 'prepare' fork handler shall be called before
     12  *  fork() processing commences.  The 'parent' fork handle shall be called after fork()
     13  *  processing completes in the parent process.  The 'child' fork shall be called after
     14  *  fork() processing completes in the child process.
     15  *
     16  * STEPS:
     17  * 1. Call pthread_atfork() before a fork() call, setting all three fork handlers for
     18  *    prepare, parent and child.
     19  * 2. Call fork()
     20  * 3. Verify that all three fork handlers were called
     21  *
     22  */
     23 
     24 #include <pthread.h>
     25 #include <stdio.h>
     26 #include <stdlib.h>
     27 #include <string.h>
     28 #include <errno.h>
     29 #include <unistd.h>
     30 #include <sys/wait.h>
     31 #include <sys/types.h>
     32 #include "posixtest.h"
     33 
     34 #define HANDLER_NOTCALLED 0
     35 #define HANDLER_CALLED 1
     36 
     37 int prep_val;
     38 int parent_val;
     39 int child_val;
     40 
     41 static void prepare_handler()
     42 {
     43 	prep_val = HANDLER_CALLED;
     44 	return;
     45 }
     46 
     47 static void parent_handler()
     48 {
     49 	parent_val = HANDLER_CALLED;
     50 	return;
     51 }
     52 
     53 static void child_handler()
     54 {
     55 	child_val = HANDLER_CALLED;
     56 	return;
     57 }
     58 
     59 int main(void)
     60 {
     61 	pid_t pid;
     62 
     63 	/* Initialize values */
     64 	prep_val = HANDLER_NOTCALLED;
     65 	parent_val = HANDLER_NOTCALLED;
     66 	child_val = HANDLER_NOTCALLED;
     67 
     68 	/* Set up the fork handlers */
     69 	if (pthread_atfork(prepare_handler, parent_handler, child_handler) != 0) {
     70 		printf("Error in pthread_atfork\n");
     71 		return PTS_UNRESOLVED;
     72 	}
     73 
     74 	/* Now call fork() */
     75 	pid = fork();
     76 
     77 	if (pid < 0) {
     78 		perror("Error in fork()\n");
     79 		return PTS_UNRESOLVED;
     80 	}
     81 	if (pid == 0) {
     82 		/* Child process */
     83 		pthread_exit(0);
     84 	} else {
     85 		/* Parent process */
     86 		wait(NULL);
     87 	}
     88 
     89 	/* Check if fork handlers were called */
     90 	if (prep_val == 1) {
     91 		if (parent_val == 1) {
     92 			if (parent_val == 1) {
     93 				printf("Test PASSED\n");
     94 				return PTS_PASS;
     95 			} else {
     96 				printf
     97 				    ("Test FAILED: child handler not called\n");
     98 				return PTS_FAIL;
     99 			}
    100 		} else {
    101 			printf("Test FAILED: parent handler not called\n");
    102 			return PTS_FAIL;
    103 		}
    104 	} else {
    105 		printf("Test FAILED: prepare handler not called\n");
    106 		return PTS_FAIL;
    107 	}
    108 
    109 	/* Should not reach here */
    110 	printf("Error: control should not reach here\n");
    111 	return PTS_UNRESOLVED;
    112 }
    113