Home | History | Annotate | Download | only in timer_create
      1 /*
      2  * Copyright (c) 2002, Intel Corporation. All rights reserved.
      3  * Copyright (c) 2002, Jim Houston.  All rights reserved.
      4  * Created by:  julie.n.fleischer REMOVE-THIS AT intel DOT com
      5  * Patched by jim.houston REMOVE-THIS AT attbi DOT com
      6  * This file is licensed under the GPL license.  For the full content
      7  * of this license, see the COPYING file at the top level of this
      8  * source tree.
      9 
     10  * Test that timers are not inherited across a fork().
     11  * Steps:
     12  * 1.  Set up a signal handler for timer in parent.
     13  * 2.  Create timer using timer_create().
     14  * 3.  Activate timer using timer_settime().
     15  * 4.  Immediately fork a new process [Note: There is some risk here if
     16  *     the system does not fork fast enough that there could be a false
     17  *     failure.  Times will be set large enough that this risk is minimized.]
     18  * 5.  Set up a signal handler for the timer in the parent and ensure it
     19  *     is not called by ensuring the child is able to sleep uninterrupted.
     20  *     [Note:  The delay to set up this handler could also cause false
     21  *     results.]
     22  *
     23  * For this test clock CLOCK_REALTIME will be used.
     24  *
     25  * 12/17/02 - Applied Jim Houston's patch that fixed a bug.  Parent originally
     26  *            was set to return PTS_UNRESOLVED if nanosleep() was interrupted,
     27  *            even though expected behavior is that it be interrupted once
     28  *            to catch the signal.
     29  */
     30 
     31 #include <time.h>
     32 #include <signal.h>
     33 #include <stdio.h>
     34 #include <unistd.h>
     35 #include <stdlib.h>
     36 #include <sys/wait.h>
     37 #include "posixtest.h"
     38 
     39 #define TIMERSEC 2
     40 #define SLEEPDELTA 4
     41 #define ACCEPTABLEDELTA 1
     42 
     43 #define CHILDSUCCESS 1
     44 #define CHILDFAILURE 0
     45 
     46 void parenthandler(int signo)
     47 {
     48 	printf("Expected - Caught signal\n");
     49 }
     50 
     51 void handler(int signo)
     52 {
     53 	printf("Not expected - Caught signal\n");
     54 }
     55 
     56 int main(void)
     57 {
     58 	timer_t tid;
     59 	struct sigaction actp;
     60 	struct itimerspec its;
     61 	int pid;
     62 
     63 	actp.sa_handler = parenthandler;
     64 	actp.sa_flags = 0;
     65 
     66 	its.it_interval.tv_sec = 0;
     67 	its.it_interval.tv_nsec = 0;
     68 	its.it_value.tv_sec = TIMERSEC;
     69 	its.it_value.tv_nsec = 0;
     70 
     71 	if (sigemptyset(&actp.sa_mask) == -1) {
     72 		perror("Error calling sigemptyset\n");
     73 		return PTS_UNRESOLVED;
     74 	}
     75 	if (sigaction(SIGALRM, &actp, 0) == -1) {
     76 		perror("Error calling sigaction\n");
     77 		return PTS_UNRESOLVED;
     78 	}
     79 
     80 	if (timer_create(CLOCK_REALTIME, NULL, &tid) != 0) {
     81 		perror("timer_create() did not return success\n");
     82 		return PTS_UNRESOLVED;
     83 	}
     84 
     85 	if (timer_settime(tid, 0, &its, NULL) != 0) {
     86 		perror("timer_settime() did not return success\n");
     87 		return PTS_UNRESOLVED;
     88 	}
     89 
     90 	if ((pid = fork()) == 0) {
     91 		/* child here */
     92 		struct sigaction act;
     93 		struct timespec ts, tsleft;
     94 		act.sa_handler = handler;
     95 		act.sa_flags = 0;
     96 
     97 		if (sigemptyset(&act.sa_mask) == -1) {
     98 			perror("Error calling sigemptyset\n");
     99 			return CHILDFAILURE;
    100 		}
    101 		if (sigaction(SIGALRM, &act, 0) == -1) {
    102 			perror("Error calling sigaction\n");
    103 			return CHILDFAILURE;
    104 		}
    105 
    106 		ts.tv_sec = TIMERSEC + SLEEPDELTA;
    107 		ts.tv_nsec = 0;
    108 
    109 		if (nanosleep(&ts, &tsleft) == -1) {
    110 			printf("child nanosleep() interrupted\n");
    111 			return CHILDFAILURE;
    112 		}
    113 		//nanosleep() not interrupted
    114 		return CHILDSUCCESS;
    115 
    116 	} else {
    117 		/* parent here */
    118 		int i;
    119 		struct timespec tsp, rem;
    120 
    121 		/*
    122 		 * parent also sleeps to allow timer to expire
    123 		 */
    124 		tsp.tv_sec = TIMERSEC;
    125 		tsp.tv_nsec = 0;
    126 		if (nanosleep(&tsp, &rem) == -1) {
    127 			tsp = rem;
    128 			if (nanosleep(&tsp, &rem) == -1) {
    129 				printf("parent nanosleep() interrupted\n");
    130 				return PTS_UNRESOLVED;
    131 			}
    132 		}
    133 
    134 		if (wait(&i) == -1) {
    135 			perror("Error waiting for child to exit\n");
    136 			return PTS_UNRESOLVED;
    137 		}
    138 		if (WIFEXITED(i) && WEXITSTATUS(i)) {
    139 			printf("Test PASSED\n");
    140 			return PTS_PASS;
    141 		} else {
    142 			printf("Child did not exit normally.\n");
    143 			printf("Test FAILED\n");
    144 			return PTS_FAIL;
    145 		}
    146 
    147 	}
    148 
    149 	return PTS_UNRESOLVED;
    150 }
    151