1 /*
2  * Copyright (c) 2002, Intel Corporation. All rights reserved.
3  * Created by:  julie.n.fleischer 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  * Test having two timers in different processes set to expire at the
9  * same time, and ensure they both expire at the same time.
10  */
11 #include <stdio.h>
12 #include <time.h>
13 #include <signal.h>
14 #include <stdlib.h>
15 #include <sys/types.h>
16 #include <sys/wait.h>
17 #include <unistd.h>
18 #include "posixtest.h"
19 
20 #define EXPIREDELTA 3
21 #define LONGTIME 5
22 
23 #define CHILDPASS 1
24 
main(int argc,char * argv[])25 int main(int argc, char *argv[])
26 {
27 	int pid;
28 	struct timespec ts;
29 
30 	if (clock_gettime(CLOCK_REALTIME, &ts) != 0) {
31 		perror("clock_gettime() did not return success\n");
32 		return PTS_UNRESOLVED;
33 	}
34 
35 	if ((pid = fork()) == 0) {
36 		/*child */
37 		struct sigevent ev;
38 		timer_t tid;
39 		struct itimerspec its;
40 		sigset_t set;
41 		int sig;
42 		int flags = 0;
43 
44 		if (sigemptyset(&set) == -1) {
45 			perror("sigemptyset() failed\n");
46 			return PTS_UNRESOLVED;
47 		}
48 
49 		if (sigaddset(&set, SIGABRT) == -1) {
50 			perror("sigaddset() failed\n");
51 			return PTS_UNRESOLVED;
52 		}
53 
54 		ev.sigev_notify = SIGEV_SIGNAL;
55 		ev.sigev_signo = SIGABRT;
56 		if (timer_create(CLOCK_REALTIME, &ev, &tid) != 0) {
57 			perror("timer_create() did not return success\n");
58 			return PTS_UNRESOLVED;
59 		}
60 
61 		its.it_value.tv_sec = ts.tv_sec + EXPIREDELTA;
62 		its.it_value.tv_nsec = ts.tv_nsec;
63 		its.it_interval.tv_sec = 0;
64 		its.it_interval.tv_nsec = 0;
65 
66 		flags |= TIMER_ABSTIME;
67 		if (timer_settime(tid, flags, &its, NULL) != 0) {
68 			perror("timer_settime() did not return success\n");
69 			return PTS_UNRESOLVED;
70 		}
71 
72 		if (sigwait(&set, &sig) == -1) {
73 			perror("sigwait() failed\n");
74 			return PTS_UNRESOLVED;
75 		}
76 		printf("Got it!  Child\n");
77 
78 		sleep(LONGTIME);
79 		return CHILDPASS;
80 	} else {
81 		/*parent */
82 		struct sigevent ev;
83 		timer_t tid;
84 		struct itimerspec its;
85 		sigset_t set;
86 		int sig;
87 		int flags = 0;
88 		int i;
89 
90 		if (sigemptyset(&set) == -1) {
91 			perror("sigemptyset() failed\n");
92 			return PTS_UNRESOLVED;
93 		}
94 
95 		if (sigaddset(&set, SIGALRM) == -1) {
96 			perror("sigaddset() failed\n");
97 			return PTS_UNRESOLVED;
98 		}
99 
100 		ev.sigev_notify = SIGEV_SIGNAL;
101 		ev.sigev_signo = SIGALRM;
102 		if (timer_create(CLOCK_REALTIME, &ev, &tid) != 0) {
103 			perror("timer_create() did not return success\n");
104 			return PTS_UNRESOLVED;
105 		}
106 
107 		its.it_value.tv_sec = ts.tv_sec + EXPIREDELTA;
108 		its.it_value.tv_nsec = ts.tv_nsec;
109 		its.it_interval.tv_sec = 0;
110 		its.it_interval.tv_nsec = 0;
111 
112 		flags |= TIMER_ABSTIME;
113 		if (timer_settime(tid, flags, &its, NULL) != 0) {
114 			perror("timer_settime() did not return success\n");
115 			return PTS_UNRESOLVED;
116 		}
117 
118 		if (sigwait(&set, &sig) == -1) {
119 			perror("sigwait() failed\n");
120 			return PTS_UNRESOLVED;
121 		}
122 		printf("Got it!  Parent\n");
123 
124 		if (wait(&i) == -1) {
125 			perror("Error waiting for child to exit\n");
126 			return PTS_UNRESOLVED;
127 		}
128 		if (WEXITSTATUS(i)) {
129 			printf("Test PASSED\n");
130 			return PTS_PASS;
131 		} else {
132 			printf("Test FAILED\n");
133 			return PTS_FAIL;
134 		}
135 	}
136 	return PTS_UNRESOLVED;
137 }
138