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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  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. #ifdef PRINT_TIMESPEC_DATA_SIZE
  34. bool
  35. PRINT_TIMESPEC_DATA_SIZE(const void *arg, const size_t size)
  36. {
  37. if (size < sizeof(TIMESPEC_T)) {
  38. tprints("?");
  39. return false;
  40. }
  41. print_timespec_t(arg);
  42. return true;
  43. }
  44. #endif /* PRINT_TIMESPEC_DATA_SIZE */
  45. #ifdef PRINT_TIMESPEC_ARRAY_DATA_SIZE
  46. bool
  47. PRINT_TIMESPEC_ARRAY_DATA_SIZE(const void *arg, const unsigned int nmemb,
  48. const size_t size)
  49. {
  50. const TIMESPEC_T *ts = arg;
  51. unsigned int i;
  52. if (nmemb > size / sizeof(TIMESPEC_T)) {
  53. tprints("?");
  54. return false;
  55. }
  56. tprints("[");
  57. for (i = 0; i < nmemb; i++) {
  58. if (i)
  59. tprints(", ");
  60. print_timespec_t(&ts[i]);
  61. }
  62. tprints("]");
  63. return true;
  64. }
  65. #endif /* PRINT_TIMESPEC_ARRAY_DATA_SIZE */
  66. #ifdef PRINT_TIMESPEC
  67. int
  68. PRINT_TIMESPEC(struct tcb *const tcp, const kernel_ulong_t addr)
  69. {
  70. TIMESPEC_T t;
  71. if (umove_or_printaddr(tcp, addr, &t))
  72. return -1;
  73. print_timespec_t(&t);
  74. return 0;
  75. }
  76. #endif /* PRINT_TIMESPEC */
  77. #ifdef SPRINT_TIMESPEC
  78. const char *
  79. SPRINT_TIMESPEC(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. if (!addr) {
  84. strcpy(buf, "NULL");
  85. } else if (!verbose(tcp) || (exiting(tcp) && syserror(tcp)) ||
  86. umove(tcp, addr, &t)) {
  87. xsprintf(buf, "%#" PRI_klx, addr);
  88. } else {
  89. xsprintf(buf, timespec_fmt, TIMESPEC_TO_SEC_NSEC(&t));
  90. }
  91. return buf;
  92. }
  93. #endif /* SPRINT_TIMESPEC */
  94. #ifdef PRINT_TIMESPEC_UTIME_PAIR
  95. static void
  96. print_timespec_t_utime(const TIMESPEC_T *t)
  97. {
  98. switch (t->TIMESPEC_NSEC) {
  99. case UTIME_NOW:
  100. case UTIME_OMIT:
  101. if (xlat_verbose(xlat_verbosity) != XLAT_STYLE_ABBREV)
  102. print_timespec_t(t);
  103. if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW)
  104. break;
  105. (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE
  106. ? tprints_comment : tprints)(t->TIMESPEC_NSEC == UTIME_NOW
  107. ? "UTIME_NOW" : "UTIME_OMIT");
  108. break;
  109. default:
  110. print_timespec_t(t);
  111. tprints_comment(sprinttime_nsec(TIMESPEC_TO_SEC_NSEC(t)));
  112. break;
  113. }
  114. }
  115. int
  116. PRINT_TIMESPEC_UTIME_PAIR(struct tcb *const tcp, const kernel_ulong_t addr)
  117. {
  118. TIMESPEC_T t[2];
  119. if (umove_or_printaddr(tcp, addr, &t))
  120. return -1;
  121. tprints("[");
  122. print_timespec_t_utime(&t[0]);
  123. tprints(", ");
  124. print_timespec_t_utime(&t[1]);
  125. tprints("]");
  126. return 0;
  127. }
  128. #endif /* PRINT_TIMESPEC_UTIME_PAIR */
  129. #ifdef PRINT_ITIMERSPEC
  130. int
  131. PRINT_ITIMERSPEC(struct tcb *const tcp, const kernel_ulong_t addr)
  132. {
  133. TIMESPEC_T t[2];
  134. if (umove_or_printaddr(tcp, addr, &t))
  135. return -1;
  136. tprints("{it_interval=");
  137. print_timespec_t(&t[0]);
  138. tprints(", it_value=");
  139. print_timespec_t(&t[1]);
  140. tprints("}");
  141. return 0;
  142. }
  143. #endif /* PRINT_ITIMERSPEC */