Mirror of strace – the linux syscall tracer
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

print_timespec.h 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /*
  2. * Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org>
  3. * Copyright (c) 2016-2019 The strace developers.
  4. * All rights reserved.
  5. *
  6. * SPDX-License-Identifier: LGPL-2.1-or-later
  7. */
  8. #include "xstring.h"
  9. #ifndef UTIME_NOW
  10. # define UTIME_NOW ((1l << 30) - 1l)
  11. #endif
  12. #ifndef UTIME_OMIT
  13. # define UTIME_OMIT ((1l << 30) - 2l)
  14. #endif
  15. #define TIMESPEC_TO_SEC_NSEC(t_) \
  16. ((long long) (t_)->tv_sec), zero_extend_signed_to_ull((t_)->tv_nsec)
  17. static const char timespec_fmt[] = "{tv_sec=%lld, tv_nsec=%llu}";
  18. static void
  19. print_sec_nsec(long long sec, unsigned long long nsec)
  20. {
  21. tprintf(timespec_fmt, sec, nsec);
  22. }
  23. static void
  24. print_timespec_t(const TIMESPEC_T *t)
  25. {
  26. print_sec_nsec(TIMESPEC_TO_SEC_NSEC(t));
  27. }
  28. #ifdef PRINT_TIMESPEC_DATA_SIZE
  29. bool
  30. PRINT_TIMESPEC_DATA_SIZE(const void *arg, const size_t size)
  31. {
  32. if (size < sizeof(TIMESPEC_T)) {
  33. tprints("?");
  34. return false;
  35. }
  36. print_timespec_t(arg);
  37. return true;
  38. }
  39. #endif /* PRINT_TIMESPEC_DATA_SIZE */
  40. #ifdef PRINT_TIMESPEC_ARRAY_DATA_SIZE
  41. bool
  42. PRINT_TIMESPEC_ARRAY_DATA_SIZE(const void *arg, const unsigned int nmemb,
  43. const size_t size)
  44. {
  45. const TIMESPEC_T *ts = arg;
  46. unsigned int i;
  47. if (nmemb > size / sizeof(TIMESPEC_T)) {
  48. tprints("?");
  49. return false;
  50. }
  51. tprints("[");
  52. for (i = 0; i < nmemb; i++) {
  53. if (i)
  54. tprints(", ");
  55. print_timespec_t(&ts[i]);
  56. }
  57. tprints("]");
  58. return true;
  59. }
  60. #endif /* PRINT_TIMESPEC_ARRAY_DATA_SIZE */
  61. #ifdef PRINT_TIMESPEC
  62. int
  63. PRINT_TIMESPEC(struct tcb *const tcp, const kernel_ulong_t addr)
  64. {
  65. TIMESPEC_T t;
  66. if (umove_or_printaddr(tcp, addr, &t))
  67. return -1;
  68. print_timespec_t(&t);
  69. return 0;
  70. }
  71. #endif /* PRINT_TIMESPEC */
  72. #ifdef SPRINT_TIMESPEC
  73. const char *
  74. SPRINT_TIMESPEC(struct tcb *const tcp, const kernel_ulong_t addr)
  75. {
  76. TIMESPEC_T t;
  77. static char buf[sizeof(timespec_fmt) + 3 * sizeof(t)];
  78. if (!addr) {
  79. strcpy(buf, "NULL");
  80. } else if (!verbose(tcp) || (exiting(tcp) && syserror(tcp)) ||
  81. umove(tcp, addr, &t)) {
  82. xsprintf(buf, "%#" PRI_klx, addr);
  83. } else {
  84. xsprintf(buf, timespec_fmt, TIMESPEC_TO_SEC_NSEC(&t));
  85. }
  86. return buf;
  87. }
  88. #endif /* SPRINT_TIMESPEC */
  89. #ifdef PRINT_TIMESPEC_UTIME_PAIR
  90. static void
  91. print_timespec_t_utime(const TIMESPEC_T *t)
  92. {
  93. switch (t->tv_nsec) {
  94. case UTIME_NOW:
  95. case UTIME_OMIT:
  96. if (xlat_verbose(xlat_verbosity) != XLAT_STYLE_ABBREV)
  97. print_timespec_t(t);
  98. if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW)
  99. break;
  100. (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE
  101. ? tprints_comment : tprints)(t->tv_nsec == UTIME_NOW
  102. ? "UTIME_NOW" : "UTIME_OMIT");
  103. break;
  104. default:
  105. print_timespec_t(t);
  106. tprints_comment(sprinttime_nsec(TIMESPEC_TO_SEC_NSEC(t)));
  107. break;
  108. }
  109. }
  110. int
  111. PRINT_TIMESPEC_UTIME_PAIR(struct tcb *const tcp, const kernel_ulong_t addr)
  112. {
  113. TIMESPEC_T t[2];
  114. if (umove_or_printaddr(tcp, addr, &t))
  115. return -1;
  116. tprints("[");
  117. print_timespec_t_utime(&t[0]);
  118. tprints(", ");
  119. print_timespec_t_utime(&t[1]);
  120. tprints("]");
  121. return 0;
  122. }
  123. #endif /* PRINT_TIMESPEC_UTIME_PAIR */
  124. #ifdef PRINT_ITIMERSPEC
  125. int
  126. PRINT_ITIMERSPEC(struct tcb *const tcp, const kernel_ulong_t addr)
  127. {
  128. TIMESPEC_T t[2];
  129. if (umove_or_printaddr(tcp, addr, &t))
  130. return -1;
  131. tprints("{it_interval=");
  132. print_timespec_t(&t[0]);
  133. tprints(", it_value=");
  134. print_timespec_t(&t[1]);
  135. tprints("}");
  136. return 0;
  137. }
  138. #endif /* PRINT_ITIMERSPEC */