]> granicus.if.org Git - strace/blob - print_time.c
Fix omission of field names in printers of timespec structure
[strace] / print_time.c
1 /*
2  * Copyright (c) 2015 Dmitry V. Levin <ldv@altlinux.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. The name of the author may not be used to endorse or promote products
14  *    derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #include "defs.h"
29
30 #include DEF_MPERS_TYPE(time_t)
31 #include DEF_MPERS_TYPE(timespec_t)
32 #include DEF_MPERS_TYPE(timeval_t)
33
34 typedef struct timespec timespec_t;
35 typedef struct timeval timeval_t;
36
37 #include MPERS_DEFS
38
39 #ifndef UTIME_NOW
40 # define UTIME_NOW ((1l << 30) - 1l)
41 #endif
42 #ifndef UTIME_OMIT
43 # define UTIME_OMIT ((1l << 30) - 2l)
44 #endif
45
46 static const char timespec_fmt[] = "{tv_sec=%jd, tv_nsec=%jd}";
47 static const char time_fmt[] = "{%jd, %jd}";
48
49 static void
50 print_timespec_t(const timespec_t *t)
51 {
52         tprintf(timespec_fmt, (intmax_t) t->tv_sec, (intmax_t) t->tv_nsec);
53 }
54
55 static void
56 print_timespec_t_utime(const timespec_t *t)
57 {
58         switch (t->tv_nsec) {
59         case UTIME_NOW:
60                 tprints("UTIME_NOW");
61                 break;
62         case UTIME_OMIT:
63                 tprints("UTIME_OMIT");
64                 break;
65         default:
66                 print_timespec_t(t);
67                 break;
68         }
69 }
70
71 static void
72 print_timeval_t(const timeval_t *t)
73 {
74         tprintf(time_fmt, (intmax_t) t->tv_sec, (intmax_t) t->tv_usec);
75 }
76
77 MPERS_PRINTER_DECL(void, print_timespec,
78                    struct tcb *tcp, const long addr)
79 {
80         timespec_t t;
81
82         if (umove_or_printaddr(tcp, addr, &t))
83                 return;
84
85         print_timespec_t(&t);
86 }
87
88 MPERS_PRINTER_DECL(const char *, sprint_timespec,
89                    struct tcb *tcp, const long addr)
90 {
91         timespec_t t;
92         static char buf[sizeof(timespec_fmt) + 3 * sizeof(t)];
93
94         if (!addr) {
95                 strcpy(buf, "NULL");
96         } else if (!verbose(tcp) || (exiting(tcp) && syserror(tcp)) ||
97                    umove(tcp, addr, &t)) {
98                 snprintf(buf, sizeof(buf), "%#lx", addr);
99         } else {
100                 snprintf(buf, sizeof(buf), timespec_fmt,
101                          (intmax_t) t.tv_sec, (intmax_t) t.tv_nsec);
102         }
103
104         return buf;
105 }
106
107 MPERS_PRINTER_DECL(void, print_timespec_utime_pair,
108                    struct tcb *tcp, const long addr)
109 {
110         timespec_t t[2];
111
112         if (umove_or_printaddr(tcp, addr, &t))
113                 return;
114
115         tprints("[");
116         print_timespec_t_utime(&t[0]);
117         tprints(", ");
118         print_timespec_t_utime(&t[1]);
119         tprints("]");
120 }
121
122 MPERS_PRINTER_DECL(void, print_itimerspec,
123                    struct tcb *tcp, const long addr)
124 {
125         timespec_t t[2];
126
127         if (umove_or_printaddr(tcp, addr, &t))
128                 return;
129
130         tprints("{it_interval=");
131         print_timespec_t(&t[0]);
132         tprints(", it_value=");
133         print_timespec_t(&t[1]);
134         tprints("}");
135 }
136
137 MPERS_PRINTER_DECL(void, print_timeval,
138                    struct tcb *tcp, const long addr)
139 {
140         timeval_t t;
141
142         if (umove_or_printaddr(tcp, addr, &t))
143                 return;
144
145         print_timeval_t(&t);
146 }
147
148 MPERS_PRINTER_DECL(void, print_timeval_pair,
149                    struct tcb *tcp, const long addr)
150 {
151         timeval_t t[2];
152
153         if (umove_or_printaddr(tcp, addr, &t))
154                 return;
155
156         tprints("[");
157         print_timeval_t(&t[0]);
158         tprints(", ");
159         print_timeval_t(&t[1]);
160         tprints("]");
161 }
162
163 MPERS_PRINTER_DECL(const char *, sprint_timeval,
164                    struct tcb *tcp, const long addr)
165 {
166         timeval_t t;
167         static char buf[sizeof(time_fmt) + 3 * sizeof(t)];
168
169         if (!addr) {
170                 strcpy(buf, "NULL");
171         } else if (!verbose(tcp) || (exiting(tcp) && syserror(tcp)) ||
172                    umove(tcp, addr, &t)) {
173                 snprintf(buf, sizeof(buf), "%#lx", addr);
174         } else {
175                 snprintf(buf, sizeof(buf), time_fmt,
176                          (intmax_t) t.tv_sec, (intmax_t) t.tv_usec);
177         }
178
179         return buf;
180 }
181
182 MPERS_PRINTER_DECL(void, print_itimerval,
183                    struct tcb *tcp, const long addr)
184 {
185         timeval_t t[2];
186
187         if (umove_or_printaddr(tcp, addr, &t))
188                 return;
189
190         tprints("{it_interval=");
191         print_timeval_t(&t[0]);
192         tprints(", it_value=");
193         print_timeval_t(&t[1]);
194         tprints("}");
195 }
196
197 SYS_FUNC(time)
198 {
199         if (exiting(tcp)) {
200                 time_t t;
201
202                 if (!umove_or_printaddr(tcp, tcp->u_arg[0], &t))
203                         tprintf("[%jd]", (intmax_t) t);
204         }
205
206         return 0;
207 }
208
209 #ifdef ALPHA
210
211 typedef struct {
212         int tv_sec, tv_usec;
213 } timeval32_t;
214
215 static void
216 print_timeval32_t(const timeval32_t *t)
217 {
218         tprintf(time_fmt, (intmax_t) t->tv_sec, (intmax_t) t->tv_usec);
219 }
220
221 void
222 print_timeval32(struct tcb *tcp, const long addr)
223 {
224         timeval32_t t;
225
226         if (umove_or_printaddr(tcp, addr, &t))
227                 return;
228
229         print_timeval32_t(&t);
230 }
231
232 void
233 print_timeval32_pair(struct tcb *tcp, const long addr)
234 {
235         timeval32_t t[2];
236
237         if (umove_or_printaddr(tcp, addr, &t))
238                 return;
239
240         tprints("[");
241         print_timeval32_t(&t[0]);
242         tprints(", ");
243         print_timeval32_t(&t[1]);
244         tprints("]");
245 }
246
247 void
248 print_itimerval32(struct tcb *tcp, const long addr)
249 {
250         timeval32_t t[2];
251
252         if (umove_or_printaddr(tcp, addr, &t))
253                 return;
254
255         tprints("{it_interval=");
256         print_timeval32_t(&t[0]);
257         tprints(", it_value=");
258         print_timeval32_t(&t[1]);
259         tprints("}");
260 }
261
262 const char *
263 sprint_timeval32(struct tcb *tcp, const long addr)
264 {
265         timeval32_t t;
266         static char buf[sizeof(time_fmt) + 3 * sizeof(t)];
267
268         if (!addr) {
269                 strcpy(buf, "NULL");
270         } else if (!verbose(tcp) || (exiting(tcp) && syserror(tcp)) ||
271                    umove(tcp, addr, &t)) {
272                 snprintf(buf, sizeof(buf), "%#lx", addr);
273         } else {
274                 snprintf(buf, sizeof(buf), time_fmt,
275                          (intmax_t) t.tv_sec, (intmax_t) t.tv_usec);
276         }
277
278         return buf;
279 }
280
281 #endif /* ALPHA */