1 /* 2 * Copyright (c) 2015-2016 Dmitry V. Levin <ldv (at) altlinux.org> 3 * Copyright (c) 2016-2018 The strace developers. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include "defs.h" 30 31 #include DEF_MPERS_TYPE(timespec_t) 32 33 typedef struct timespec timespec_t; 34 35 #include MPERS_DEFS 36 37 #include "xstring.h" 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=%lld, tv_nsec=%llu}"; 47 48 static void 49 print_timespec_t(const timespec_t *t) 50 { 51 tprintf(timespec_fmt, (long long) t->tv_sec, 52 zero_extend_signed_to_ull(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 tprints_comment(sprinttime_nsec(t->tv_sec, 68 zero_extend_signed_to_ull(t->tv_nsec))); 69 break; 70 } 71 } 72 73 MPERS_PRINTER_DECL(bool, print_struct_timespec_data_size, 74 const void *arg, const size_t size) 75 { 76 if (size < sizeof(timespec_t)) { 77 tprints("?"); 78 return false; 79 } 80 81 print_timespec_t(arg); 82 return true; 83 } 84 85 MPERS_PRINTER_DECL(bool, print_struct_timespec_array_data_size, 86 const void *arg, const unsigned int nmemb, 87 const size_t size) 88 { 89 const timespec_t *ts = arg; 90 unsigned int i; 91 92 if (nmemb > size / sizeof(timespec_t)) { 93 tprints("?"); 94 return false; 95 } 96 97 tprints("["); 98 99 for (i = 0; i < nmemb; i++) { 100 if (i) 101 tprints(", "); 102 print_timespec_t(&ts[i]); 103 } 104 105 tprints("]"); 106 return true; 107 } 108 109 MPERS_PRINTER_DECL(void, print_timespec, 110 struct tcb *const tcp, const kernel_ulong_t addr) 111 { 112 timespec_t t; 113 114 if (umove_or_printaddr(tcp, addr, &t)) 115 return; 116 117 print_timespec_t(&t); 118 } 119 120 MPERS_PRINTER_DECL(const char *, sprint_timespec, 121 struct tcb *const tcp, const kernel_ulong_t addr) 122 { 123 timespec_t t; 124 static char buf[sizeof(timespec_fmt) + 3 * sizeof(t)]; 125 126 if (!addr) { 127 strcpy(buf, "NULL"); 128 } else if (!verbose(tcp) || (exiting(tcp) && syserror(tcp)) || 129 umove(tcp, addr, &t)) { 130 xsprintf(buf, "%#" PRI_klx, addr); 131 } else { 132 xsprintf(buf, timespec_fmt, 133 (long long) t.tv_sec, 134 zero_extend_signed_to_ull(t.tv_nsec)); 135 } 136 137 return buf; 138 } 139 140 MPERS_PRINTER_DECL(void, print_timespec_utime_pair, 141 struct tcb *const tcp, const kernel_ulong_t addr) 142 { 143 timespec_t t[2]; 144 145 if (umove_or_printaddr(tcp, addr, &t)) 146 return; 147 148 tprints("["); 149 print_timespec_t_utime(&t[0]); 150 tprints(", "); 151 print_timespec_t_utime(&t[1]); 152 tprints("]"); 153 } 154 155 MPERS_PRINTER_DECL(void, print_itimerspec, 156 struct tcb *const tcp, const kernel_ulong_t addr) 157 { 158 timespec_t t[2]; 159 160 if (umove_or_printaddr(tcp, addr, &t)) 161 return; 162 163 tprints("{it_interval="); 164 print_timespec_t(&t[0]); 165 tprints(", it_value="); 166 print_timespec_t(&t[1]); 167 tprints("}"); 168 } 169