strace/print_timespec.c
Dmitry V. Levin b93d52fe3d Change the license of strace to LGPL-2.1-or-later
strace is now provided under the terms of the GNU Lesser General
Public License version 2.1 or later, see COPYING for more details.

strace test suite is now provided under the terms of the GNU General
Public License version 2 or later, see tests/COPYING for more details.
2018-12-10 00:00:00 +00:00

154 lines
3.0 KiB
C

/*
* Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org>
* Copyright (c) 2016-2018 The strace developers.
* All rights reserved.
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "defs.h"
#include DEF_MPERS_TYPE(timespec_t)
typedef struct timespec timespec_t;
#include MPERS_DEFS
#include "xstring.h"
#ifndef UTIME_NOW
# define UTIME_NOW ((1l << 30) - 1l)
#endif
#ifndef UTIME_OMIT
# define UTIME_OMIT ((1l << 30) - 2l)
#endif
static const char timespec_fmt[] = "{tv_sec=%lld, tv_nsec=%llu}";
static void
print_timespec_t(const timespec_t *t)
{
tprintf(timespec_fmt, (long long) t->tv_sec,
zero_extend_signed_to_ull(t->tv_nsec));
}
static void
print_timespec_t_utime(const timespec_t *t)
{
switch (t->tv_nsec) {
case UTIME_NOW:
case UTIME_OMIT:
if (xlat_verbose(xlat_verbosity) != XLAT_STYLE_ABBREV)
print_timespec_t(t);
if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW)
break;
(xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE
? tprints_comment : tprints)(t->tv_nsec == UTIME_NOW
? "UTIME_NOW" : "UTIME_OMIT");
break;
default:
print_timespec_t(t);
tprints_comment(sprinttime_nsec(t->tv_sec,
zero_extend_signed_to_ull(t->tv_nsec)));
break;
}
}
MPERS_PRINTER_DECL(bool, print_struct_timespec_data_size,
const void *arg, const size_t size)
{
if (size < sizeof(timespec_t)) {
tprints("?");
return false;
}
print_timespec_t(arg);
return true;
}
MPERS_PRINTER_DECL(bool, print_struct_timespec_array_data_size,
const void *arg, const unsigned int nmemb,
const size_t size)
{
const timespec_t *ts = arg;
unsigned int i;
if (nmemb > size / sizeof(timespec_t)) {
tprints("?");
return false;
}
tprints("[");
for (i = 0; i < nmemb; i++) {
if (i)
tprints(", ");
print_timespec_t(&ts[i]);
}
tprints("]");
return true;
}
MPERS_PRINTER_DECL(void, print_timespec,
struct tcb *const tcp, const kernel_ulong_t addr)
{
timespec_t t;
if (umove_or_printaddr(tcp, addr, &t))
return;
print_timespec_t(&t);
}
MPERS_PRINTER_DECL(const char *, sprint_timespec,
struct tcb *const tcp, const kernel_ulong_t addr)
{
timespec_t t;
static char buf[sizeof(timespec_fmt) + 3 * sizeof(t)];
if (!addr) {
strcpy(buf, "NULL");
} else if (!verbose(tcp) || (exiting(tcp) && syserror(tcp)) ||
umove(tcp, addr, &t)) {
xsprintf(buf, "%#" PRI_klx, addr);
} else {
xsprintf(buf, timespec_fmt,
(long long) t.tv_sec,
zero_extend_signed_to_ull(t.tv_nsec));
}
return buf;
}
MPERS_PRINTER_DECL(void, print_timespec_utime_pair,
struct tcb *const tcp, const kernel_ulong_t addr)
{
timespec_t t[2];
if (umove_or_printaddr(tcp, addr, &t))
return;
tprints("[");
print_timespec_t_utime(&t[0]);
tprints(", ");
print_timespec_t_utime(&t[1]);
tprints("]");
}
MPERS_PRINTER_DECL(void, print_itimerspec,
struct tcb *const tcp, const kernel_ulong_t addr)
{
timespec_t t[2];
if (umove_or_printaddr(tcp, addr, &t))
return;
tprints("{it_interval=");
print_timespec_t(&t[0]);
tprints(", it_value=");
print_timespec_t(&t[1]);
tprints("}");
}