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.6KB

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