]> granicus.if.org Git - strace/blob - time.c
Return RVAL_STR unconditionally
[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-2017 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(itimer_which, tcp->u_arg[0], "ITIMER_???");
120                 tprints(", ");
121         } else {
122                 print_itimerval(tcp, tcp->u_arg[1]);
123         }
124         return 0;
125 }
126
127 #ifdef ALPHA
128 SYS_FUNC(osf_getitimer)
129 {
130         if (entering(tcp)) {
131                 printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
132                 tprints(", ");
133         } else {
134                 print_itimerval32(tcp, tcp->u_arg[1]);
135         }
136         return 0;
137 }
138 #endif
139
140 SYS_FUNC(setitimer)
141 {
142         if (entering(tcp)) {
143                 printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
144                 tprints(", ");
145                 print_itimerval(tcp, tcp->u_arg[1]);
146                 tprints(", ");
147         } else {
148                 print_itimerval(tcp, tcp->u_arg[2]);
149         }
150         return 0;
151 }
152
153 #ifdef ALPHA
154 SYS_FUNC(osf_setitimer)
155 {
156         if (entering(tcp)) {
157                 printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
158                 tprints(", ");
159                 print_itimerval32(tcp, tcp->u_arg[1]);
160                 tprints(", ");
161         } else {
162                 print_itimerval32(tcp, tcp->u_arg[2]);
163         }
164         return 0;
165 }
166 #endif
167
168 #include "xlat/adjtimex_state.h"
169
170 static int
171 do_adjtimex(struct tcb *const tcp, const kernel_ulong_t addr)
172 {
173         if (print_timex(tcp, addr))
174                 return 0;
175         tcp->auxstr = xlookup(adjtimex_state, (kernel_ulong_t) tcp->u_rval);
176         return RVAL_STR;
177 }
178
179 SYS_FUNC(adjtimex)
180 {
181         if (exiting(tcp))
182                 return do_adjtimex(tcp, tcp->u_arg[0]);
183         return 0;
184 }
185
186 #include "xlat/clockflags.h"
187 #include "xlat/clocknames.h"
188
189 static void
190 printclockname(int clockid)
191 {
192 #ifdef CLOCKID_TO_FD
193 # include "xlat/cpuclocknames.h"
194
195         if (clockid < 0) {
196                 if ((clockid & CLOCKFD_MASK) == CLOCKFD)
197                         tprintf("FD_TO_CLOCKID(%d)", CLOCKID_TO_FD(clockid));
198                 else {
199                         if (CPUCLOCK_PERTHREAD(clockid))
200                                 tprintf("MAKE_THREAD_CPUCLOCK(%d,", CPUCLOCK_PID(clockid));
201                         else
202                                 tprintf("MAKE_PROCESS_CPUCLOCK(%d,", CPUCLOCK_PID(clockid));
203                         printxval(cpuclocknames, clockid & CLOCKFD_MASK, "CPUCLOCK_???");
204                         tprints(")");
205                 }
206         } else
207 #endif
208                 printxval(clocknames, clockid, "CLOCK_???");
209 }
210
211 SYS_FUNC(clock_settime)
212 {
213         printclockname(tcp->u_arg[0]);
214         tprints(", ");
215         print_timespec(tcp, tcp->u_arg[1]);
216
217         return RVAL_DECODED;
218 }
219
220 SYS_FUNC(clock_gettime)
221 {
222         if (entering(tcp)) {
223                 printclockname(tcp->u_arg[0]);
224                 tprints(", ");
225         } else {
226                 print_timespec(tcp, tcp->u_arg[1]);
227         }
228         return 0;
229 }
230
231 SYS_FUNC(clock_nanosleep)
232 {
233         if (entering(tcp)) {
234                 printclockname(tcp->u_arg[0]);
235                 tprints(", ");
236                 printflags(clockflags, tcp->u_arg[1], "TIMER_???");
237                 tprints(", ");
238                 print_timespec(tcp, tcp->u_arg[2]);
239                 tprints(", ");
240         } else {
241                 /*
242                  * Second (returned) timespec is only significant
243                  * if syscall was interrupted and flags is not TIMER_ABSTIME.
244                  */
245                 if (!tcp->u_arg[1] && is_erestart(tcp)) {
246                         temporarily_clear_syserror(tcp);
247                         print_timespec(tcp, tcp->u_arg[3]);
248                         restore_cleared_syserror(tcp);
249                 } else {
250                         printaddr(tcp->u_arg[3]);
251                 }
252         }
253         return 0;
254 }
255
256 SYS_FUNC(clock_adjtime)
257 {
258         if (exiting(tcp))
259                 return do_adjtimex(tcp, tcp->u_arg[1]);
260         printclockname(tcp->u_arg[0]);
261         tprints(", ");
262         return 0;
263 }
264
265 SYS_FUNC(timer_create)
266 {
267         if (entering(tcp)) {
268                 printclockname(tcp->u_arg[0]);
269                 tprints(", ");
270                 print_sigevent(tcp, tcp->u_arg[1]);
271                 tprints(", ");
272         } else {
273                 printnum_int(tcp, tcp->u_arg[2], "%d");
274         }
275         return 0;
276 }
277
278 SYS_FUNC(timer_settime)
279 {
280         if (entering(tcp)) {
281                 tprintf("%d, ", (int) tcp->u_arg[0]);
282                 printflags(clockflags, tcp->u_arg[1], "TIMER_???");
283                 tprints(", ");
284                 print_itimerspec(tcp, tcp->u_arg[2]);
285                 tprints(", ");
286         } else {
287                 print_itimerspec(tcp, tcp->u_arg[3]);
288         }
289         return 0;
290 }
291
292 SYS_FUNC(timer_gettime)
293 {
294         if (entering(tcp)) {
295                 tprintf("%d, ", (int) tcp->u_arg[0]);
296         } else {
297                 print_itimerspec(tcp, tcp->u_arg[1]);
298         }
299         return 0;
300 }
301
302 #include "xlat/timerfdflags.h"
303
304 SYS_FUNC(timerfd_create)
305 {
306         printclockname(tcp->u_arg[0]);
307         tprints(", ");
308         printflags(timerfdflags, tcp->u_arg[1], "TFD_???");
309
310         return RVAL_DECODED | RVAL_FD;
311 }
312
313 SYS_FUNC(timerfd_settime)
314 {
315         if (entering(tcp)) {
316                 printfd(tcp, tcp->u_arg[0]);
317                 tprints(", ");
318                 printflags(timerfdflags, tcp->u_arg[1], "TFD_???");
319                 tprints(", ");
320                 print_itimerspec(tcp, tcp->u_arg[2]);
321                 tprints(", ");
322         } else {
323                 print_itimerspec(tcp, tcp->u_arg[3]);
324         }
325         return 0;
326 }
327
328 SYS_FUNC(timerfd_gettime)
329 {
330         if (entering(tcp)) {
331                 printfd(tcp, tcp->u_arg[0]);
332                 tprints(", ");
333         } else {
334                 print_itimerspec(tcp, tcp->u_arg[1]);
335         }
336         return 0;
337 }