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