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 35static void 36print_timezone(struct tcb *const tcp, const kernel_ulong_t addr) 37{ 38 struct timezone tz; 39 40 if (umove_or_printaddr(tcp, addr, &tz)) 41 return; 42 43 tprintf("{tz_minuteswest=%d, tz_dsttime=%d}", 44 tz.tz_minuteswest, tz.tz_dsttime); 45} 46 47SYS_FUNC(gettimeofday) 48{ 49 if (exiting(tcp)) { 50 print_timeval(tcp, tcp->u_arg[0]); 51 tprints(", "); 52 print_timezone(tcp, tcp->u_arg[1]); 53 } 54 return 0; 55} 56 57#ifdef ALPHA 58SYS_FUNC(osf_gettimeofday) 59{ 60 if (exiting(tcp)) { 61 print_timeval32(tcp, tcp->u_arg[0]); 62 tprints(", "); 63 print_timezone(tcp, tcp->u_arg[1]); 64 } 65 return 0; 66} 67#endif 68 69SYS_FUNC(settimeofday) 70{ 71 print_timeval(tcp, tcp->u_arg[0]); 72 tprints(", "); 73 print_timezone(tcp, tcp->u_arg[1]); 74 75 return RVAL_DECODED; 76} 77 78#ifdef ALPHA 79SYS_FUNC(osf_settimeofday) 80{ 81 print_timeval32(tcp, tcp->u_arg[0]); 82 tprints(", "); 83 print_timezone(tcp, tcp->u_arg[1]); 84 85 return RVAL_DECODED; 86} 87#endif 88 89SYS_FUNC(nanosleep) 90{ 91 if (entering(tcp)) { 92 print_timespec(tcp, tcp->u_arg[0]); 93 tprints(", "); 94 } else { 95 96 /* 97 * Second (returned) timespec is only significant if syscall 98 * was interrupted. On success and in case of other errors we 99 * print only its address, since kernel doesn't modify it, 100 * and printing the value may show uninitialized data. 101 */ 102 if (is_erestart(tcp)) { 103 temporarily_clear_syserror(tcp); 104 print_timespec(tcp, tcp->u_arg[1]); 105 restore_cleared_syserror(tcp); 106 } else { 107 printaddr(tcp->u_arg[1]); 108 } 109 } 110 return 0; 111} 112 113#include "xlat/itimer_which.h" 114 115SYS_FUNC(getitimer) 116{ 117 if (entering(tcp)) { 118 printxval(itimer_which, tcp->u_arg[0], "ITIMER_???"); 119 tprints(", "); 120 } else { 121 print_itimerval(tcp, tcp->u_arg[1]); 122 } 123 return 0; 124} 125 126#ifdef ALPHA 127SYS_FUNC(osf_getitimer) 128{ 129 if (entering(tcp)) { 130 printxval(itimer_which, tcp->u_arg[0], "ITIMER_???"); 131 tprints(", "); 132 } else { 133 print_itimerval32(tcp, tcp->u_arg[1]); 134 } 135 return 0; 136} 137#endif 138 139SYS_FUNC(setitimer) 140{ 141 if (entering(tcp)) { 142 printxval(itimer_which, tcp->u_arg[0], "ITIMER_???"); 143 tprints(", "); 144 print_itimerval(tcp, tcp->u_arg[1]); 145 tprints(", "); 146 } else { 147 print_itimerval(tcp, tcp->u_arg[2]); 148 } 149 return 0; 150} 151 152#ifdef ALPHA 153SYS_FUNC(osf_setitimer) 154{ 155 if (entering(tcp)) { 156 printxval(itimer_which, tcp->u_arg[0], "ITIMER_???"); 157 tprints(", "); 158 print_itimerval32(tcp, tcp->u_arg[1]); 159 tprints(", "); 160 } else { 161 print_itimerval32(tcp, tcp->u_arg[2]); 162 } 163 return 0; 164} 165#endif 166 167#include "xlat/adjtimex_state.h" 168 169static int 170do_adjtimex(struct tcb *const tcp, const kernel_ulong_t addr) 171{ 172 if (print_timex(tcp, addr)) 173 return 0; 174 tcp->auxstr = xlookup(adjtimex_state, (kernel_ulong_t) tcp->u_rval); 175 if (tcp->auxstr) 176 return RVAL_STR; 177 return 0; 178} 179 180SYS_FUNC(adjtimex) 181{ 182 if (exiting(tcp)) 183 return do_adjtimex(tcp, tcp->u_arg[0]); 184 return 0; 185} 186 187#include "xlat/clockflags.h" 188#include "xlat/clocknames.h" 189 190static void 191printclockname(int clockid) 192{ 193#ifdef CLOCKID_TO_FD 194# include "xlat/cpuclocknames.h" 195 196 if (clockid < 0) { 197 if ((clockid & CLOCKFD_MASK) == CLOCKFD) 198 tprintf("FD_TO_CLOCKID(%d)", CLOCKID_TO_FD(clockid)); 199 else { 200 if(CPUCLOCK_PERTHREAD(clockid)) 201 tprintf("MAKE_THREAD_CPUCLOCK(%d,", CPUCLOCK_PID(clockid)); 202 else 203 tprintf("MAKE_PROCESS_CPUCLOCK(%d,", CPUCLOCK_PID(clockid)); 204 printxval(cpuclocknames, clockid & CLOCKFD_MASK, "CPUCLOCK_???"); 205 tprints(")"); 206 } 207 } 208 else 209#endif 210 printxval(clocknames, clockid, "CLOCK_???"); 211} 212 213SYS_FUNC(clock_settime) 214{ 215 printclockname(tcp->u_arg[0]); 216 tprints(", "); 217 print_timespec(tcp, tcp->u_arg[1]); 218 219 return RVAL_DECODED; 220} 221 222SYS_FUNC(clock_gettime) 223{ 224 if (entering(tcp)) { 225 printclockname(tcp->u_arg[0]); 226 tprints(", "); 227 } else { 228 print_timespec(tcp, tcp->u_arg[1]); 229 } 230 return 0; 231} 232 233SYS_FUNC(clock_nanosleep) 234{ 235 if (entering(tcp)) { 236 printclockname(tcp->u_arg[0]); 237 tprints(", "); 238 printflags(clockflags, tcp->u_arg[1], "TIMER_???"); 239 tprints(", "); 240 print_timespec(tcp, tcp->u_arg[2]); 241 tprints(", "); 242 } else { 243 /* 244 * Second (returned) timespec is only significant 245 * if syscall was interrupted and flags is not TIMER_ABSTIME. 246 */ 247 if (!tcp->u_arg[1] && is_erestart(tcp)) { 248 temporarily_clear_syserror(tcp); 249 print_timespec(tcp, tcp->u_arg[3]); 250 restore_cleared_syserror(tcp); 251 } else { 252 printaddr(tcp->u_arg[3]); 253 } 254 } 255 return 0; 256} 257 258SYS_FUNC(clock_adjtime) 259{ 260 if (exiting(tcp)) 261 return do_adjtimex(tcp, tcp->u_arg[1]); 262 printclockname(tcp->u_arg[0]); 263 tprints(", "); 264 return 0; 265} 266 267SYS_FUNC(timer_create) 268{ 269 if (entering(tcp)) { 270 printclockname(tcp->u_arg[0]); 271 tprints(", "); 272 print_sigevent(tcp, tcp->u_arg[1]); 273 tprints(", "); 274 } else { 275 printnum_int(tcp, tcp->u_arg[2], "%d"); 276 } 277 return 0; 278} 279 280SYS_FUNC(timer_settime) 281{ 282 if (entering(tcp)) { 283 tprintf("%d, ", (int) tcp->u_arg[0]); 284 printflags(clockflags, tcp->u_arg[1], "TIMER_???"); 285 tprints(", "); 286 print_itimerspec(tcp, tcp->u_arg[2]); 287 tprints(", "); 288 } else { 289 print_itimerspec(tcp, tcp->u_arg[3]); 290 } 291 return 0; 292} 293 294SYS_FUNC(timer_gettime) 295{ 296 if (entering(tcp)) { 297 tprintf("%d, ", (int) tcp->u_arg[0]); 298 } else { 299 print_itimerspec(tcp, tcp->u_arg[1]); 300 } 301 return 0; 302} 303 304#include "xlat/timerfdflags.h" 305 306SYS_FUNC(timerfd_create) 307{ 308 printclockname(tcp->u_arg[0]); 309 tprints(", "); 310 printflags(timerfdflags, tcp->u_arg[1], "TFD_???"); 311 312 return RVAL_DECODED | RVAL_FD; 313} 314 315SYS_FUNC(timerfd_settime) 316{ 317 if (entering(tcp)) { 318 printfd(tcp, tcp->u_arg[0]); 319 tprints(", "); 320 printflags(timerfdflags, tcp->u_arg[1], "TFD_???"); 321 tprints(", "); 322 print_itimerspec(tcp, tcp->u_arg[2]); 323 tprints(", "); 324 } else { 325 print_itimerspec(tcp, tcp->u_arg[3]); 326 } 327 return 0; 328} 329 330SYS_FUNC(timerfd_gettime) 331{ 332 if (entering(tcp)) { 333 printfd(tcp, tcp->u_arg[0]); 334 tprints(", "); 335 } else { 336 print_itimerspec(tcp, tcp->u_arg[1]); 337 } 338 return 0; 339} 340