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.
 
 
 
 

101 lines
1.7 KiB

  1. #include <assert.h>
  2. #include <errno.h>
  3. #include <stdarg.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <wchar.h>
  8. #include <syslog.h>
  9. #include "xmalloc.h"
  10. static NORETURN COLD void
  11. fatal_error(const char *msg, int err)
  12. {
  13. syslog(LOG_ERR, "%s: %s", msg, strerror(err));
  14. errno = err;
  15. perror(msg);
  16. abort();
  17. }
  18. static void *
  19. check_alloc(void *alloc)
  20. {
  21. if (unlikely(alloc == NULL)) {
  22. fatal_error(__func__, ENOMEM);
  23. }
  24. return alloc;
  25. }
  26. void *
  27. xmalloc(size_t size)
  28. {
  29. if (unlikely(size == 0)) {
  30. size = 1;
  31. }
  32. return check_alloc(malloc(size));
  33. }
  34. void *
  35. xcalloc(size_t nmemb, size_t size)
  36. {
  37. assert(size != 0);
  38. return check_alloc(calloc(likely(nmemb) ? nmemb : 1, size));
  39. }
  40. void *
  41. xrealloc(void *ptr, size_t size)
  42. {
  43. void *alloc = realloc(ptr, size);
  44. return unlikely(size == 0) ? alloc : check_alloc(alloc);
  45. }
  46. char *
  47. xstrdup(const char *str)
  48. {
  49. return check_alloc(strdup(str));
  50. }
  51. wchar_t *
  52. xwcsdup(const wchar_t *str)
  53. {
  54. return check_alloc(wcsdup(str));
  55. }
  56. char *
  57. xstrndup(const char *str, size_t n)
  58. {
  59. return check_alloc(strndup(str, n));
  60. }
  61. static VPRINTF(2) int
  62. xvasprintf_(char **strp, const char *format, va_list ap)
  63. {
  64. va_list ap2;
  65. va_copy(ap2, ap);
  66. int n = vsnprintf(NULL, 0, format, ap2);
  67. if (unlikely(n < 0)) {
  68. fatal_error("vsnprintf", EILSEQ);
  69. }
  70. va_end(ap2);
  71. *strp = xmalloc(n + 1);
  72. return vsnprintf(*strp, n + 1, format, ap);
  73. }
  74. static VPRINTF(1) char *
  75. xvasprintf(const char *format, va_list ap)
  76. {
  77. char *str;
  78. xvasprintf_(&str, format, ap);
  79. return str;
  80. }
  81. char *
  82. xasprintf(const char *format, ...)
  83. {
  84. va_list ap;
  85. va_start(ap, format);
  86. char *str = xvasprintf(format, ap);
  87. va_end(ap);
  88. return str;
  89. }