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.

xmalloc.c 2.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /*
  2. * Copyright (c) 2015 Dmitry V. Levin <ldv@altlinux.org>
  3. * Copyright (c) 2015-2018 The strace developers.
  4. * All rights reserved.
  5. *
  6. * SPDX-License-Identifier: LGPL-2.1-or-later
  7. */
  8. #ifdef HAVE_CONFIG_H
  9. # include "config.h"
  10. #endif
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include "error_prints.h"
  14. #include "macros.h"
  15. #include "xmalloc.h"
  16. static void
  17. die_out_of_memory(void)
  18. {
  19. static int recursed;
  20. if (recursed)
  21. exit(1);
  22. recursed = 1;
  23. error_msg_and_die("Out of memory");
  24. }
  25. void *
  26. xmalloc(size_t size)
  27. {
  28. void *p = malloc(size);
  29. if (!p)
  30. die_out_of_memory();
  31. return p;
  32. }
  33. void *
  34. xcalloc(size_t nmemb, size_t size)
  35. {
  36. void *p = calloc(nmemb, size);
  37. if (!p)
  38. die_out_of_memory();
  39. return p;
  40. }
  41. #define HALF_SIZE_T (((size_t) 1) << (sizeof(size_t) * 4))
  42. void *
  43. xallocarray(size_t nmemb, size_t size)
  44. {
  45. size_t bytes = nmemb * size;
  46. if ((nmemb | size) >= HALF_SIZE_T &&
  47. size && bytes / size != nmemb)
  48. die_out_of_memory();
  49. void *p = malloc(bytes);
  50. if (!p)
  51. die_out_of_memory();
  52. return p;
  53. }
  54. void *
  55. xreallocarray(void *ptr, size_t nmemb, size_t size)
  56. {
  57. size_t bytes = nmemb * size;
  58. if ((nmemb | size) >= HALF_SIZE_T &&
  59. size && bytes / size != nmemb)
  60. die_out_of_memory();
  61. void *p = realloc(ptr, bytes);
  62. if (!p)
  63. die_out_of_memory();
  64. return p;
  65. }
  66. void *
  67. xgrowarray_ex(void *const ptr, size_t *const nmemb, const size_t min_size,
  68. const size_t memb_size)
  69. {
  70. /* this is the same value as glibc DEFAULT_MXFAST */
  71. enum { DEFAULT_ALLOC_SIZE = 64 * SIZEOF_LONG / 4 };
  72. size_t grow_memb;
  73. size_t new_size;
  74. if (ptr == NULL)
  75. grow_memb = *nmemb ? 0 :
  76. (DEFAULT_ALLOC_SIZE + memb_size - 1) / memb_size;
  77. else
  78. grow_memb = (*nmemb >> 1) + 1;
  79. new_size = MAX(min_size, *nmemb + grow_memb);
  80. if (new_size < *nmemb)
  81. die_out_of_memory();
  82. *nmemb = new_size;
  83. return xreallocarray(ptr, new_size, memb_size);
  84. }
  85. char *
  86. xstrdup(const char *str)
  87. {
  88. if (!str)
  89. return NULL;
  90. char *p = strdup(str);
  91. if (!p)
  92. die_out_of_memory();
  93. return p;
  94. }
  95. char *
  96. xstrndup(const char *str, size_t n)
  97. {
  98. char *p;
  99. if (!str)
  100. return NULL;
  101. #ifdef HAVE_STRNDUP
  102. p = strndup(str, n);
  103. #else
  104. p = xmalloc(n + 1);
  105. #endif
  106. if (!p)
  107. die_out_of_memory();
  108. #ifndef HAVE_STRNDUP
  109. strncpy(p, str, n);
  110. p[n] = '\0';
  111. #endif
  112. return p;
  113. }