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.

xstring.h 3.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /*
  2. * Copyright (c) 2018 Eugene Syromyatnikov <evgsyr@gmail.com>
  3. * All rights reserved.
  4. *
  5. * SPDX-License-Identifier: LGPL-2.1-or-later
  6. */
  7. #ifndef STRACE_XSTRING_H
  8. # define STRACE_XSTRING_H
  9. # include <stdarg.h>
  10. # include <stdio.h>
  11. # include "error_prints.h"
  12. # include "gcc_compat.h"
  13. /**
  14. * Print to static buffer and die on (really unexpected) errors and overflows.
  15. * Shouldn't be used directly; please refer to helper macros xsnprintf and
  16. * xsprint instead.
  17. *
  18. * @param str String buffer to print into.
  19. * @param size Size of the string buffer in bytes.
  20. * @param func Function name from which this function is called.
  21. * @param argstr Stringified arguments (including format argument).
  22. * @param format Format string.
  23. * @param ... Format arguments.
  24. * @return Number of characters printed, excluding terminating null byte
  25. * (the same as s(n)printf).
  26. */
  27. static inline int ATTRIBUTE_FORMAT((printf, 5, 6))
  28. xsnprintf_(char *str, size_t size, const char *func, const char *argstr,
  29. const char *format, ...)
  30. {
  31. int ret;
  32. va_list ap;
  33. va_start(ap, format);
  34. ret = vsnprintf(str, size, format, ap);
  35. va_end(ap);
  36. if (ret < 0 || (unsigned int) ret >= size)
  37. error_msg_and_die("%s: got unexpected return value %d for "
  38. "snprintf(buf, %zu, %s)",
  39. func, ret, size, argstr);
  40. return ret;
  41. }
  42. /**
  43. * snprintf that dies on (really unexpected) errors and overflows.
  44. *
  45. * @param str_ String buffer to print into.
  46. * @param size_ Size of the string buffer in bytes.
  47. * @param fmt_ Format string.
  48. * @param ... Format arguments.
  49. */
  50. # define xsnprintf(str_, size_, fmt_, ...) \
  51. xsnprintf_((str_), (size_), __func__, #fmt_ ", " #__VA_ARGS__, \
  52. (fmt_), __VA_ARGS__)
  53. /**
  54. * Print to a character array buffer and die on (really unexpected) errors and
  55. * overflows. Buffer size is obtained with sizeof().
  56. *
  57. * @param str_ Character array buffer to print into.
  58. * @param fmt_ Format string.
  59. * @param ... Format arguments.
  60. */
  61. # define xsprintf(str_, fmt_, ...) \
  62. xsnprintf((str_), sizeof(str_) + MUST_BE_ARRAY(str_), (fmt_), \
  63. __VA_ARGS__)
  64. static inline size_t
  65. get_pos_diff_(char *str, size_t size, char *pos, const char *func,
  66. const char *call)
  67. {
  68. if ((str + size) < str)
  69. error_msg_and_die("%s: string size overflow (%p+%zu) in %s",
  70. func, str, size, call);
  71. if (pos > (str + size))
  72. error_msg_and_die("%s: got position (%p) beyond string "
  73. "(%p+%zu) in %s",
  74. func, pos, str, size, call);
  75. if (pos < str)
  76. error_msg_and_die("%s: got position %p before string %p in %s",
  77. func, pos, str, call);
  78. return pos - str;
  79. }
  80. /**
  81. * Helper function for constructing string in a character array by appending
  82. * new formatted parts. Returns new position. Fails on error or buffer
  83. * overflow, in line with the rest of x* functions. Obtains buffer size via
  84. * sizeof(str_).
  85. *
  86. * @param str_ Character array buffer to print into.
  87. * @param pos_ Current position.
  88. * @param fmt_ Format string.
  89. * @param ... Format arguments.
  90. * @return New position.
  91. */
  92. # define xappendstr(str_, pos_, fmt_, ...) \
  93. (xsnprintf((pos_), sizeof(str_) + MUST_BE_ARRAY(str_) - \
  94. get_pos_diff_((str_), sizeof(str_), (pos_), __func__, \
  95. "xappendstr(" #str_ ", " #pos_ ", " #fmt_ ", " \
  96. #__VA_ARGS__ ")"), \
  97. (fmt_), ##__VA_ARGS__) + (pos_))
  98. #endif /* !STRACE_XSTRING_H */