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