Home | History | Annotate | Download | only in strace
      1 /*
      2  * Copyright (c) 2015-2016 Dmitry V. Levin <ldv (at) 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(timespec_t)
     31 
     32 typedef struct timespec timespec_t;
     33 
     34 #include MPERS_DEFS
     35 
     36 #ifndef UTIME_NOW
     37 # define UTIME_NOW ((1l << 30) - 1l)
     38 #endif
     39 #ifndef UTIME_OMIT
     40 # define UTIME_OMIT ((1l << 30) - 2l)
     41 #endif
     42 
     43 static const char timespec_fmt[] = "{tv_sec=%jd, tv_nsec=%jd}";
     44 
     45 static void
     46 print_timespec_t(const timespec_t *t)
     47 {
     48 	tprintf(timespec_fmt, (intmax_t) t->tv_sec, (intmax_t) t->tv_nsec);
     49 }
     50 
     51 static void
     52 print_timespec_t_utime(const timespec_t *t)
     53 {
     54 	switch (t->tv_nsec) {
     55 	case UTIME_NOW:
     56 		tprints("UTIME_NOW");
     57 		break;
     58 	case UTIME_OMIT:
     59 		tprints("UTIME_OMIT");
     60 		break;
     61 	default:
     62 		print_timespec_t(t);
     63 		break;
     64 	}
     65 }
     66 
     67 MPERS_PRINTER_DECL(void, print_timespec,
     68 		   struct tcb *const tcp, const kernel_ulong_t addr)
     69 {
     70 	timespec_t t;
     71 
     72 	if (umove_or_printaddr(tcp, addr, &t))
     73 		return;
     74 
     75 	print_timespec_t(&t);
     76 }
     77 
     78 MPERS_PRINTER_DECL(const char *, sprint_timespec,
     79 		   struct tcb *const tcp, const kernel_ulong_t addr)
     80 {
     81 	timespec_t t;
     82 	static char buf[sizeof(timespec_fmt) + 3 * sizeof(t)];
     83 
     84 	if (!addr) {
     85 		strcpy(buf, "NULL");
     86 	} else if (!verbose(tcp) || (exiting(tcp) && syserror(tcp)) ||
     87 		   umove(tcp, addr, &t)) {
     88 		snprintf(buf, sizeof(buf), "%#" PRI_klx, addr);
     89 	} else {
     90 		snprintf(buf, sizeof(buf), timespec_fmt,
     91 			 (intmax_t) t.tv_sec, (intmax_t) t.tv_nsec);
     92 	}
     93 
     94 	return buf;
     95 }
     96 
     97 MPERS_PRINTER_DECL(void, print_timespec_utime_pair,
     98 		   struct tcb *const tcp, const kernel_ulong_t addr)
     99 {
    100 	timespec_t t[2];
    101 
    102 	if (umove_or_printaddr(tcp, addr, &t))
    103 		return;
    104 
    105 	tprints("[");
    106 	print_timespec_t_utime(&t[0]);
    107 	tprints(", ");
    108 	print_timespec_t_utime(&t[1]);
    109 	tprints("]");
    110 }
    111 
    112 MPERS_PRINTER_DECL(void, print_itimerspec,
    113 		   struct tcb *const tcp, const kernel_ulong_t addr)
    114 {
    115 	timespec_t t[2];
    116 
    117 	if (umove_or_printaddr(tcp, addr, &t))
    118 		return;
    119 
    120 	tprints("{it_interval=");
    121 	print_timespec_t(&t[0]);
    122 	tprints(", it_value=");
    123 	print_timespec_t(&t[1]);
    124 	tprints("}");
    125 }
    126