1 #if defined(__sun__)
2 #define __EXTENSIONS__ 1
3 #endif
4 
5 #include "declarations.h"
6 #include "timer.h"
7 
8 #include "config.mach"
9 
10 
11 
timer_init(time_t s,long u,void * t)12 int timer_init(time_t s, long u, void *t) {
13 	int f;
14 
15 	struct itimerval i;
16 	struct itimerval o;
17 	struct sigaction a;
18 
19 	(void) memset((void *) &i, 0, sizeof(i));
20 	(void) memset((void *) &o, 0, sizeof(o));
21 	(void) memset((void *) &a, 0, sizeof(a));
22 #if defined(__minix__)
23 	f = 0;
24 #else
25 	f = SA_SIGINFO | SA_RESTART;
26 #endif
27 	if(sigemptyset(&a.sa_mask) != 0) {
28 		LOGWARN(
29 			ERROR_SLIGHT, SUBSYSTEM,
30 			_("Failed to empty signal set")
31 		);
32 	}
33 
34 	a.sa_flags = f;
35 	a.sa_handler = NULL;
36 	a.sa_sigaction = (void *) t;
37 
38 	if((sigaction(SIGALRM, &a, NULL)) != 0) {
39 		LOGWARN(
40 			ERROR_SLIGHT, SUBSYSTEM,
41 			_("Failed to set signal action for timer")
42 		);
43 
44 		return(-1);
45 	}
46 
47 	i.it_value.tv_sec = s;
48 	i.it_value.tv_usec = u;
49 	i.it_interval.tv_sec = s;
50 	i.it_interval.tv_usec = u;
51 
52 	o.it_value.tv_sec = 0;
53 	o.it_value.tv_usec = 0;
54 	o.it_interval.tv_sec = 0;
55 	o.it_interval.tv_usec = 0;
56 
57 	if((setitimer(ITIMER_REAL, &i, &o)) != 0) {
58 		LOGWARN(
59 			ERROR_SLIGHT, SUBSYSTEM,
60 			_("Failed to set attributes for a timer")
61 		);
62 
63 		return(-1);
64 	}
65 
66 	return(0);
67 }
68 
timer_get_secs(void)69 time_t timer_get_secs(void) {
70 	time_t t;
71 
72 	if((t = time(NULL)) == (time_t) -1) {
73 		LOGWARN(
74 			ERROR_SLIGHT, SUBSYSTEM,
75 			_("Failed to read system time")
76 		);
77 	}
78 
79 	return(t);
80 }
81 
timer_get_date(struct tm * t)82 void timer_get_date(struct tm *t) {
83 	time_t e;
84 #if ! defined(HAVE_LOCALTIME_R)
85 	struct tm *r;
86 #endif
87 	if((e = time(NULL)) == (time_t) -1) {
88 		LOGWARN(
89 			ERROR_SLIGHT, SUBSYSTEM,
90 			_("Failed to read system time")
91 		);
92 	}
93 #if defined(HAVE_LOCALTIME_R)
94 	if(localtime_r((const time_t *) &e, t) == NULL) {
95 		LOGWARN(
96 			ERROR_SLIGHT, SUBSYSTEM,
97 			_("Failed to read system local time")
98 		);
99 	}
100 #else
101 	if((r = localtime((const time_t *) &e)) == NULL) {
102 		LOGWARN(
103 			ERROR_SLIGHT, SUBSYSTEM,
104 			_("Failed to read system local time")
105 		);
106 
107 		(void) memset((void *) t, 0, sizeof(struct tm));
108 	}
109 	else (void) memcpy((void *) t, (const void *) r, sizeof(struct tm));
110 #endif
111 }
112 
timer_get_date_by_time(struct tm * t,time_t e)113 void timer_get_date_by_time(struct tm *t, time_t e) {
114 #if ! defined(HAVE_LOCALTIME_R)
115 	struct tm *r;
116 #endif
117 #if defined(HAVE_LOCALTIME_R)
118 	if(localtime_r((const time_t *) &e, t) == NULL) {
119 		LOGWARN(
120 			ERROR_SLIGHT, SUBSYSTEM,
121 			_("Failed to read system local time")
122 		);
123 	}
124 #else
125 	if((r = localtime((const time_t *) &e)) == NULL) {
126 		LOGWARN(
127 			ERROR_SLIGHT, SUBSYSTEM,
128 			_("Failed to read system local time")
129 		);
130 
131 		(void) memset((void *) t, 0, sizeof(struct tm));
132 	}
133 	else (void) memcpy((void *) t, (const void *) r, sizeof(struct tm));
134 #endif
135 }
136 
timer_get_time(struct timeval * t)137 void timer_get_time(struct timeval *t) {
138 	t->tv_sec = 0;
139 	t->tv_usec = 0;
140 
141 	if(gettimeofday(t, NULL) == -1) {
142 		LOGWARN(
143 			ERROR_SLIGHT, SUBSYSTEM,
144 			_("Failed to read system time")
145 		);
146 	}
147 }
148 
timer_wait(time_t s,long n)149 void timer_wait(time_t s, long n) {
150 #if defined(HAVE_CLOCK_GETTIME) && defined(HAVE_CLOCK_NANOSLEEP)
151 	int e;
152 
153 	struct timespec t;
154 
155 	if(clock_gettime(CLOCK_REALTIME, &t) != 0) {
156 		LOGWARN(
157 			ERROR_SLIGHT, SUBSYSTEM,
158 			_("Failed to read system time")
159 		);
160 
161 		return;
162 	}
163 
164 	t.tv_sec += s;
165 	t.tv_nsec += n;
166 
167 	if(t.tv_nsec >= 1000000000) {
168 		t.tv_sec += (t.tv_nsec / 1000000000);
169 		t.tv_nsec %= 1000000000;
170 	}
171 
172 	while(main_stop_check_fake() != IS_YES) {
173 		(void) flush_error();
174 
175 		if((e = clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, (const struct timespec *) &t, NULL)) != 0) {
176 			if(e == EINTR || (e == -1 && errno == EINTR)) continue;
177 			else {
178 				if(errno == 0) (void) set_error(e);
179 
180 				LOGWARN(
181 					ERROR_NOERROR, SUBSYSTEM,
182 					_("Hullabaloo occurred while trying to sleep, that caused short wait")
183 				);
184 
185 				return;
186 			}
187 		}
188 		else return;
189 	}
190 #elif defined(HAVE_NANOSLEEP)
191 	struct timespec t, r;
192 
193 	t.tv_sec = s;
194 	t.tv_nsec = n;
195 
196 	if(t.tv_nsec >= 1000000000) {
197 		t.tv_sec += (t.tv_nsec / 1000000000);
198 		t.tv_nsec %= 1000000000;
199 	}
200 
201 	while(main_stop_check_fake() != IS_YES) {
202 		r.tv_sec = 0;
203 		r.tv_nsec = 0;
204 
205 		(void) flush_error();
206 
207 		if(nanosleep(&t, &r) == -1) {
208 			if(errno == EINTR) {
209 				t.tv_sec = r.tv_sec;
210 				t.tv_nsec = r.tv_nsec;
211 			}
212 			else if(errno == ENOSYS) {
213 				/* No support for nanosleep() */
214 				LOGWARN(
215 					ERROR_FATAL, SUBSYSTEM,
216 					_("Mandatory nanosleep() function call is not supported by this implementation (%s)"),
217 					CONFIG_MACH
218 				);
219 
220 				return;
221 			}
222 			else {
223 				LOGWARN(
224 					ERROR_NOERROR, SUBSYSTEM,
225 					_("Hullabaloo occurred while trying to sleep, that caused short wait")
226 				);
227 
228 				return;
229 			}
230 		}
231 		else return;
232 	}
233 #elif defined(HAVE_USLEEP)
234 	unsigned int p, r;
235 
236 	/* Convert nanoseconds to microseconds for usleep() */
237 	p = (unsigned int) s;
238 	n /= 1000;
239 
240 	if(n >= 1000000) {
241 		p += (n / 1000000);
242 		n %= 1000000;
243 	}
244 
245 	if(p > 0) {
246 		while(main_stop_check_fake() != IS_YES) {
247 			if((r = sleep(p)) == 0) break;
248 
249 			p = r;
250 		}
251 	}
252 
253 	(void) usleep((useconds_t) n);
254 #else
255 	struct timeval t;
256 
257 	/* Convert nanoseconds to microseconds for select() */
258 	n /= 1000;
259 
260 	if(n >= 1000000) {
261 		s += (n / 1000000);
262 		n %= 1000000;
263 	}
264 
265 	t.tv_sec = s;
266 	t.tv_usec = (suseconds_t) n;
267 
268 	(void) select(0, NULL, NULL, NULL, &t);
269 #endif
270 }
271