1 /*
2  * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3  * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4  * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include "defs.h"
31 #include <fcntl.h>
32 #include <signal.h>
33 #include <sys/timex.h>
34 
35 static void
print_timezone(struct tcb * tcp,const long addr)36 print_timezone(struct tcb *tcp, const long addr)
37 {
38 	struct timezone tz;
39 
40 	if (umove_or_printaddr(tcp, addr, &tz))
41 		return;
42 
43 	tprintf("{tz_minuteswest=%d, tz_dsttime=%d}",
44 		tz.tz_minuteswest, tz.tz_dsttime);
45 }
46 
SYS_FUNC(gettimeofday)47 SYS_FUNC(gettimeofday)
48 {
49 	if (exiting(tcp)) {
50 		print_timeval(tcp, tcp->u_arg[0]);
51 		tprints(", ");
52 		print_timezone(tcp, tcp->u_arg[1]);
53 	}
54 	return 0;
55 }
56 
57 #ifdef ALPHA
SYS_FUNC(osf_gettimeofday)58 SYS_FUNC(osf_gettimeofday)
59 {
60 	if (exiting(tcp)) {
61 		print_timeval32(tcp, tcp->u_arg[0]);
62 		tprints(", ");
63 		print_timezone(tcp, tcp->u_arg[1]);
64 	}
65 	return 0;
66 }
67 #endif
68 
SYS_FUNC(settimeofday)69 SYS_FUNC(settimeofday)
70 {
71 	print_timeval(tcp, tcp->u_arg[0]);
72 	tprints(", ");
73 	print_timezone(tcp, tcp->u_arg[1]);
74 
75 	return RVAL_DECODED;
76 }
77 
78 #ifdef ALPHA
SYS_FUNC(osf_settimeofday)79 SYS_FUNC(osf_settimeofday)
80 {
81 	print_timeval32(tcp, tcp->u_arg[0]);
82 	tprints(", ");
83 	print_timezone(tcp, tcp->u_arg[1]);
84 
85 	return RVAL_DECODED;
86 }
87 #endif
88 
SYS_FUNC(nanosleep)89 SYS_FUNC(nanosleep)
90 {
91 	if (entering(tcp)) {
92 		print_timespec(tcp, tcp->u_arg[0]);
93 		tprints(", ");
94 	} else {
95 
96 		/*
97 		 * Second (returned) timespec is only significant if syscall
98 		 * was interrupted.  On success and in case of other errors we
99 		 * print only its address, since kernel doesn't modify it,
100 		 * and printing the value may show uninitialized data.
101 		 */
102 		if (is_erestart(tcp)) {
103 			temporarily_clear_syserror(tcp);
104 			print_timespec(tcp, tcp->u_arg[1]);
105 			restore_cleared_syserror(tcp);
106 		} else {
107 			printaddr(tcp->u_arg[1]);
108 		}
109 	}
110 	return 0;
111 }
112 
113 #include "xlat/itimer_which.h"
114 
SYS_FUNC(getitimer)115 SYS_FUNC(getitimer)
116 {
117 	if (entering(tcp)) {
118 		printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
119 		tprints(", ");
120 	} else {
121 		print_itimerval(tcp, tcp->u_arg[1]);
122 	}
123 	return 0;
124 }
125 
126 #ifdef ALPHA
SYS_FUNC(osf_getitimer)127 SYS_FUNC(osf_getitimer)
128 {
129 	if (entering(tcp)) {
130 		printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
131 		tprints(", ");
132 	} else {
133 		print_itimerval32(tcp, tcp->u_arg[1]);
134 	}
135 	return 0;
136 }
137 #endif
138 
SYS_FUNC(setitimer)139 SYS_FUNC(setitimer)
140 {
141 	if (entering(tcp)) {
142 		printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
143 		tprints(", ");
144 		print_itimerval(tcp, tcp->u_arg[1]);
145 		tprints(", ");
146 	} else {
147 		print_itimerval(tcp, tcp->u_arg[2]);
148 	}
149 	return 0;
150 }
151 
152 #ifdef ALPHA
SYS_FUNC(osf_setitimer)153 SYS_FUNC(osf_setitimer)
154 {
155 	if (entering(tcp)) {
156 		printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
157 		tprints(", ");
158 		print_itimerval32(tcp, tcp->u_arg[1]);
159 		tprints(", ");
160 	} else {
161 		print_itimerval32(tcp, tcp->u_arg[2]);
162 	}
163 	return 0;
164 }
165 #endif
166 
167 #include "xlat/adjtimex_state.h"
168 
169 static int
do_adjtimex(struct tcb * tcp,long addr)170 do_adjtimex(struct tcb *tcp, long addr)
171 {
172 	if (print_timex(tcp, addr))
173 		return 0;
174 	tcp->auxstr = xlookup(adjtimex_state, tcp->u_rval);
175 	if (tcp->auxstr)
176 		return RVAL_STR;
177 	return 0;
178 }
179 
SYS_FUNC(adjtimex)180 SYS_FUNC(adjtimex)
181 {
182 	if (exiting(tcp))
183 		return do_adjtimex(tcp, tcp->u_arg[0]);
184 	return 0;
185 }
186 
187 #include "xlat/clockflags.h"
188 #include "xlat/clocknames.h"
189 
190 static void
printclockname(int clockid)191 printclockname(int clockid)
192 {
193 #ifdef CLOCKID_TO_FD
194 # include "xlat/cpuclocknames.h"
195 
196 	if (clockid < 0) {
197 		if ((clockid & CLOCKFD_MASK) == CLOCKFD)
198 			tprintf("FD_TO_CLOCKID(%d)", CLOCKID_TO_FD(clockid));
199 		else {
200 			if(CPUCLOCK_PERTHREAD(clockid))
201 				tprintf("MAKE_THREAD_CPUCLOCK(%d,", CPUCLOCK_PID(clockid));
202 			else
203 				tprintf("MAKE_PROCESS_CPUCLOCK(%d,", CPUCLOCK_PID(clockid));
204 			printxval(cpuclocknames, clockid & CLOCKFD_MASK, "CPUCLOCK_???");
205 			tprints(")");
206 		}
207 	}
208 	else
209 #endif
210 		printxval(clocknames, clockid, "CLOCK_???");
211 }
212 
SYS_FUNC(clock_settime)213 SYS_FUNC(clock_settime)
214 {
215 	printclockname(tcp->u_arg[0]);
216 	tprints(", ");
217 	print_timespec(tcp, tcp->u_arg[1]);
218 
219 	return RVAL_DECODED;
220 }
221 
SYS_FUNC(clock_gettime)222 SYS_FUNC(clock_gettime)
223 {
224 	if (entering(tcp)) {
225 		printclockname(tcp->u_arg[0]);
226 		tprints(", ");
227 	} else {
228 		print_timespec(tcp, tcp->u_arg[1]);
229 	}
230 	return 0;
231 }
232 
SYS_FUNC(clock_nanosleep)233 SYS_FUNC(clock_nanosleep)
234 {
235 	if (entering(tcp)) {
236 		printclockname(tcp->u_arg[0]);
237 		tprints(", ");
238 		printflags(clockflags, tcp->u_arg[1], "TIMER_???");
239 		tprints(", ");
240 		print_timespec(tcp, tcp->u_arg[2]);
241 		tprints(", ");
242 	} else {
243 		/*
244 		 * Second (returned) timespec is only significant
245 		 * if syscall was interrupted and flags is not TIMER_ABSTIME.
246 		 */
247 		if (!tcp->u_arg[1] && is_erestart(tcp)) {
248 			temporarily_clear_syserror(tcp);
249 			print_timespec(tcp, tcp->u_arg[3]);
250 			restore_cleared_syserror(tcp);
251 		} else {
252 			printaddr(tcp->u_arg[3]);
253 		}
254 	}
255 	return 0;
256 }
257 
SYS_FUNC(clock_adjtime)258 SYS_FUNC(clock_adjtime)
259 {
260 	if (exiting(tcp))
261 		return do_adjtimex(tcp, tcp->u_arg[1]);
262 	printclockname(tcp->u_arg[0]);
263 	tprints(", ");
264 	return 0;
265 }
266 
SYS_FUNC(timer_create)267 SYS_FUNC(timer_create)
268 {
269 	if (entering(tcp)) {
270 		printclockname(tcp->u_arg[0]);
271 		tprints(", ");
272 		print_sigevent(tcp, tcp->u_arg[1]);
273 		tprints(", ");
274 	} else {
275 		printnum_int(tcp, tcp->u_arg[2], "%d");
276 	}
277 	return 0;
278 }
279 
SYS_FUNC(timer_settime)280 SYS_FUNC(timer_settime)
281 {
282 	if (entering(tcp)) {
283 		tprintf("%d, ", (int) tcp->u_arg[0]);
284 		printflags(clockflags, tcp->u_arg[1], "TIMER_???");
285 		tprints(", ");
286 		print_itimerspec(tcp, tcp->u_arg[2]);
287 		tprints(", ");
288 	} else {
289 		print_itimerspec(tcp, tcp->u_arg[3]);
290 	}
291 	return 0;
292 }
293 
SYS_FUNC(timer_gettime)294 SYS_FUNC(timer_gettime)
295 {
296 	if (entering(tcp)) {
297 		tprintf("%d, ", (int) tcp->u_arg[0]);
298 	} else {
299 		print_itimerspec(tcp, tcp->u_arg[1]);
300 	}
301 	return 0;
302 }
303 
304 #include "xlat/timerfdflags.h"
305 
SYS_FUNC(timerfd)306 SYS_FUNC(timerfd)
307 {
308 	tprintf("%ld, ", tcp->u_arg[0]);
309 	printclockname(tcp->u_arg[0]);
310 	tprints(", ");
311 	printflags(timerfdflags, tcp->u_arg[2], "TFD_???");
312 	tprints(", ");
313 	print_itimerspec(tcp, tcp->u_arg[3]);
314 
315 	return RVAL_DECODED | RVAL_FD;
316 }
317 
SYS_FUNC(timerfd_create)318 SYS_FUNC(timerfd_create)
319 {
320 	printclockname(tcp->u_arg[0]);
321 	tprints(", ");
322 	printflags(timerfdflags, tcp->u_arg[1], "TFD_???");
323 
324 	return RVAL_DECODED | RVAL_FD;
325 }
326 
SYS_FUNC(timerfd_settime)327 SYS_FUNC(timerfd_settime)
328 {
329 	printfd(tcp, tcp->u_arg[0]);
330 	tprints(", ");
331 	printflags(timerfdflags, tcp->u_arg[1], "TFD_???");
332 	tprints(", ");
333 	print_itimerspec(tcp, tcp->u_arg[2]);
334 	tprints(", ");
335 	print_itimerspec(tcp, tcp->u_arg[3]);
336 
337 	return RVAL_DECODED;
338 }
339 
SYS_FUNC(timerfd_gettime)340 SYS_FUNC(timerfd_gettime)
341 {
342 	if (entering(tcp)) {
343 		printfd(tcp, tcp->u_arg[0]);
344 		tprints(", ");
345 	} else {
346 		print_itimerspec(tcp, tcp->u_arg[1]);
347 	}
348 	return 0;
349 }
350