]> granicus.if.org Git - strace/blob - time.c
Remove unused parser of adjtime syscall
[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  * 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 #ifndef UTIME_NOW
36 #define UTIME_NOW ((1l << 30) - 1l)
37 #endif
38 #ifndef UTIME_OMIT
39 #define UTIME_OMIT ((1l << 30) - 2l)
40 #endif
41
42 #if SUPPORTED_PERSONALITIES > 1
43 # if defined X86_64 || defined X32
44 #  define current_time_t_is_compat (current_personality == 1)
45 # else
46 #  define current_time_t_is_compat (current_wordsize == 4)
47 # endif
48 #else
49 # define current_time_t_is_compat 0
50 #endif
51
52 struct timeval32
53 {
54         u_int32_t tv_sec, tv_usec;
55 };
56
57 void
58 printtv_bitness(struct tcb *tcp, long addr, enum bitness_t bitness, int special)
59 {
60         char buf[TIMEVAL_TEXT_BUFSIZE];
61         sprinttv(buf, tcp, addr, bitness, special);
62         tprints(buf);
63 }
64
65 static char *
66 do_sprinttv(char *buf, const uintmax_t sec, const uintmax_t usec,
67             const int special)
68 {
69         if (special) {
70                 switch (usec) {
71                         case UTIME_NOW:
72                                 return stpcpy(buf, "UTIME_NOW");
73                         case UTIME_OMIT:
74                                 return stpcpy(buf, "UTIME_OMIT");
75                 }
76         }
77         return buf + sprintf(buf, "{%ju, %ju}", sec, usec);
78 }
79
80 char *
81 sprinttv(char *buf, struct tcb *tcp, long addr, enum bitness_t bitness, int special)
82 {
83         if (addr == 0)
84                 return stpcpy(buf, "NULL");
85
86         if (!verbose(tcp) || (exiting(tcp) && syserror(tcp)))
87                 return buf + sprintf(buf, "%#lx", addr);
88
89         if (bitness == BITNESS_32 || current_time_t_is_compat)
90         {
91                 struct timeval32 tv;
92
93                 if (umove(tcp, addr, &tv) >= 0)
94                         return do_sprinttv(buf, tv.tv_sec, tv.tv_usec, special);
95         } else {
96                 struct timeval tv;
97
98                 if (umove(tcp, addr, &tv) >= 0)
99                         return do_sprinttv(buf, tv.tv_sec, tv.tv_usec, special);
100         }
101
102         return buf + sprintf(buf, "%#lx", addr);
103 }
104
105 void
106 print_timespec(struct tcb *tcp, long addr)
107 {
108         char buf[TIMESPEC_TEXT_BUFSIZE];
109         sprint_timespec(buf, tcp, addr);
110         tprints(buf);
111 }
112
113 void
114 sprint_timespec(char *buf, struct tcb *tcp, long addr)
115 {
116         if (addr == 0)
117                 strcpy(buf, "NULL");
118         else if (!verbose(tcp))
119                 sprintf(buf, "%#lx", addr);
120         else {
121                 int rc;
122
123 #if SUPPORTED_PERSONALITIES > 1
124                 if (current_time_t_is_compat) {
125                         struct timeval32 tv;
126
127                         rc = umove(tcp, addr, &tv);
128                         if (rc >= 0)
129                                 sprintf(buf, "{%u, %u}",
130                                         tv.tv_sec, tv.tv_usec);
131                 } else
132 #endif
133                 {
134                         struct timespec ts;
135
136                         rc = umove(tcp, addr, &ts);
137                         if (rc >= 0)
138                                 sprintf(buf, "{%ju, %ju}",
139                                         (uintmax_t) ts.tv_sec,
140                                         (uintmax_t) ts.tv_nsec);
141                 }
142                 if (rc < 0)
143                         strcpy(buf, "{...}");
144         }
145 }
146
147 SYS_FUNC(gettimeofday)
148 {
149         if (exiting(tcp)) {
150                 printtv(tcp, tcp->u_arg[0]);
151                 tprints(", ");
152                 printtv(tcp, tcp->u_arg[1]);
153         }
154         return 0;
155 }
156
157 #ifdef ALPHA
158 SYS_FUNC(osf_gettimeofday)
159 {
160         if (exiting(tcp)) {
161                 printtv_bitness(tcp, tcp->u_arg[0], BITNESS_32, 0);
162                 tprints(", ");
163                 printtv_bitness(tcp, tcp->u_arg[1], BITNESS_32, 0);
164         }
165         return 0;
166 }
167 #endif
168
169 SYS_FUNC(settimeofday)
170 {
171         printtv(tcp, tcp->u_arg[0]);
172         tprints(", ");
173         printtv(tcp, tcp->u_arg[1]);
174
175         return RVAL_DECODED;
176 }
177
178 #ifdef ALPHA
179 SYS_FUNC(osf_settimeofday)
180 {
181         printtv_bitness(tcp, tcp->u_arg[0], BITNESS_32, 0);
182         tprints(", ");
183         printtv_bitness(tcp, tcp->u_arg[1], BITNESS_32, 0);
184
185         return RVAL_DECODED;
186 }
187 #endif
188
189 SYS_FUNC(nanosleep)
190 {
191         if (entering(tcp)) {
192                 print_timespec(tcp, tcp->u_arg[0]);
193                 tprints(", ");
194         } else {
195
196                 /*
197                  * Second (returned) timespec is only significant if syscall
198                  * was interrupted.  On success and in case of other errors we
199                  * print only its address, since kernel doesn't modify it,
200                  * and printing the value may show uninitialized data.
201                  */
202                 if (is_erestart(tcp)) {
203                         temporarily_clear_syserror(tcp);
204                         print_timespec(tcp, tcp->u_arg[1]);
205                         restore_cleared_syserror(tcp);
206                 } else {
207                         printaddr(tcp->u_arg[1]);
208                 }
209         }
210         return 0;
211 }
212
213 #include "xlat/itimer_which.h"
214
215 SYS_FUNC(getitimer)
216 {
217         if (entering(tcp)) {
218                 printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
219                 tprints(", ");
220         } else {
221                 print_itimerval(tcp, tcp->u_arg[1]);
222         }
223         return 0;
224 }
225
226 #ifdef ALPHA
227 SYS_FUNC(osf_getitimer)
228 {
229         if (entering(tcp)) {
230                 printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
231                 tprints(", ");
232         } else {
233                 print_itimerval32(tcp, tcp->u_arg[1]);
234         }
235         return 0;
236 }
237 #endif
238
239 SYS_FUNC(setitimer)
240 {
241         if (entering(tcp)) {
242                 printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
243                 tprints(", ");
244                 print_itimerval(tcp, tcp->u_arg[1]);
245                 tprints(", ");
246         } else {
247                 print_itimerval(tcp, tcp->u_arg[2]);
248         }
249         return 0;
250 }
251
252 #ifdef ALPHA
253 SYS_FUNC(osf_setitimer)
254 {
255         if (entering(tcp)) {
256                 printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
257                 tprints(", ");
258                 print_itimerval32(tcp, tcp->u_arg[1]);
259                 tprints(", ");
260         } else {
261                 print_itimerval32(tcp, tcp->u_arg[2]);
262         }
263         return 0;
264 }
265 #endif
266
267 #include "xlat/adjtimex_state.h"
268
269 static int
270 do_adjtimex(struct tcb *tcp, long addr)
271 {
272         if (print_timex(tcp, addr))
273                 return 0;
274         tcp->auxstr = xlookup(adjtimex_state, tcp->u_rval);
275         if (tcp->auxstr)
276                 return RVAL_STR;
277         return 0;
278 }
279
280 SYS_FUNC(adjtimex)
281 {
282         if (exiting(tcp))
283                 return do_adjtimex(tcp, tcp->u_arg[0]);
284         return 0;
285 }
286
287 #include "xlat/clockflags.h"
288 #include "xlat/clocknames.h"
289
290 static void
291 printclockname(int clockid)
292 {
293 #ifdef CLOCKID_TO_FD
294 # include "xlat/cpuclocknames.h"
295
296         if (clockid < 0) {
297                 if ((clockid & CLOCKFD_MASK) == CLOCKFD)
298                         tprintf("FD_TO_CLOCKID(%d)", CLOCKID_TO_FD(clockid));
299                 else {
300                         if(CPUCLOCK_PERTHREAD(clockid))
301                                 tprintf("MAKE_THREAD_CPUCLOCK(%d,", CPUCLOCK_PID(clockid));
302                         else
303                                 tprintf("MAKE_PROCESS_CPUCLOCK(%d,", CPUCLOCK_PID(clockid));
304                         printxval(cpuclocknames, clockid & CLOCKFD_MASK, "CPUCLOCK_???");
305                         tprints(")");
306                 }
307         }
308         else
309 #endif
310                 printxval(clocknames, clockid, "CLOCK_???");
311 }
312
313 SYS_FUNC(clock_settime)
314 {
315         printclockname(tcp->u_arg[0]);
316         tprints(", ");
317         printtv(tcp, tcp->u_arg[1]);
318
319         return RVAL_DECODED;
320 }
321
322 SYS_FUNC(clock_gettime)
323 {
324         if (entering(tcp)) {
325                 printclockname(tcp->u_arg[0]);
326                 tprints(", ");
327         } else {
328                 printtv(tcp, tcp->u_arg[1]);
329         }
330         return 0;
331 }
332
333 SYS_FUNC(clock_nanosleep)
334 {
335         if (entering(tcp)) {
336                 printclockname(tcp->u_arg[0]);
337                 tprints(", ");
338                 printflags(clockflags, tcp->u_arg[1], "TIMER_???");
339                 tprints(", ");
340                 printtv(tcp, tcp->u_arg[2]);
341                 tprints(", ");
342         } else {
343                 /*
344                  * Second (returned) timespec is only significant
345                  * if syscall was interrupted and flags is not TIMER_ABSTIME.
346                  */
347                 if (!tcp->u_arg[1] && is_erestart(tcp)) {
348                         temporarily_clear_syserror(tcp);
349                         printtv(tcp, tcp->u_arg[3]);
350                         restore_cleared_syserror(tcp);
351                 } else {
352                         printaddr(tcp->u_arg[3]);
353                 }
354         }
355         return 0;
356 }
357
358 SYS_FUNC(clock_adjtime)
359 {
360         if (exiting(tcp))
361                 return do_adjtimex(tcp, tcp->u_arg[1]);
362         printclockname(tcp->u_arg[0]);
363         tprints(", ");
364         return 0;
365 }
366
367 SYS_FUNC(timer_create)
368 {
369         if (entering(tcp)) {
370                 printclockname(tcp->u_arg[0]);
371                 tprints(", ");
372                 print_sigevent(tcp, tcp->u_arg[1]);
373                 tprints(", ");
374         } else {
375                 printnum_int(tcp, tcp->u_arg[2], "%d");
376         }
377         return 0;
378 }
379
380 SYS_FUNC(timer_settime)
381 {
382         if (entering(tcp)) {
383                 tprintf("%d, ", (int) tcp->u_arg[0]);
384                 printflags(clockflags, tcp->u_arg[1], "TIMER_???");
385                 tprints(", ");
386                 print_itimerspec(tcp, tcp->u_arg[2]);
387                 tprints(", ");
388         } else {
389                 print_itimerspec(tcp, tcp->u_arg[3]);
390         }
391         return 0;
392 }
393
394 SYS_FUNC(timer_gettime)
395 {
396         if (entering(tcp)) {
397                 tprintf("%d, ", (int) tcp->u_arg[0]);
398         } else {
399                 print_itimerspec(tcp, tcp->u_arg[1]);
400         }
401         return 0;
402 }
403
404 #include "xlat/timerfdflags.h"
405
406 SYS_FUNC(timerfd)
407 {
408         tprintf("%ld, ", tcp->u_arg[0]);
409         printclockname(tcp->u_arg[0]);
410         tprints(", ");
411         printflags(timerfdflags, tcp->u_arg[2], "TFD_???");
412         tprints(", ");
413         print_itimerspec(tcp, tcp->u_arg[3]);
414
415         return RVAL_DECODED | RVAL_FD;
416 }
417
418 SYS_FUNC(timerfd_create)
419 {
420         printclockname(tcp->u_arg[0]);
421         tprints(", ");
422         printflags(timerfdflags, tcp->u_arg[1], "TFD_???");
423
424         return RVAL_DECODED | RVAL_FD;
425 }
426
427 SYS_FUNC(timerfd_settime)
428 {
429         printfd(tcp, tcp->u_arg[0]);
430         tprints(", ");
431         printflags(timerfdflags, tcp->u_arg[1], "TFD_???");
432         tprints(", ");
433         print_itimerspec(tcp, tcp->u_arg[2]);
434         tprints(", ");
435         print_itimerspec(tcp, tcp->u_arg[3]);
436
437         return RVAL_DECODED;
438 }
439
440 SYS_FUNC(timerfd_gettime)
441 {
442         if (entering(tcp)) {
443                 printfd(tcp, tcp->u_arg[0]);
444                 tprints(", ");
445         } else {
446                 print_itimerspec(tcp, tcp->u_arg[1]);
447         }
448         return 0;
449 }