wrapper.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /*
  2. * Various trivial helper wrappers around standard functions
  3. */
  4. #include "cache.h"
  5. /*
  6. * There's no pack memory to release - but stay close to the Git
  7. * version so wrap this away:
  8. */
  9. static inline void release_pack_memory(size_t size __used, int flag __used)
  10. {
  11. }
  12. char *xstrdup(const char *str)
  13. {
  14. char *ret = strdup(str);
  15. if (!ret) {
  16. release_pack_memory(strlen(str) + 1, -1);
  17. ret = strdup(str);
  18. if (!ret)
  19. die("Out of memory, strdup failed");
  20. }
  21. return ret;
  22. }
  23. void *xmalloc(size_t size)
  24. {
  25. void *ret = malloc(size);
  26. if (!ret && !size)
  27. ret = malloc(1);
  28. if (!ret) {
  29. release_pack_memory(size, -1);
  30. ret = malloc(size);
  31. if (!ret && !size)
  32. ret = malloc(1);
  33. if (!ret)
  34. die("Out of memory, malloc failed");
  35. }
  36. #ifdef XMALLOC_POISON
  37. memset(ret, 0xA5, size);
  38. #endif
  39. return ret;
  40. }
  41. /*
  42. * xmemdupz() allocates (len + 1) bytes of memory, duplicates "len" bytes of
  43. * "data" to the allocated memory, zero terminates the allocated memory,
  44. * and returns a pointer to the allocated memory. If the allocation fails,
  45. * the program dies.
  46. */
  47. void *xmemdupz(const void *data, size_t len)
  48. {
  49. char *p = xmalloc(len + 1);
  50. memcpy(p, data, len);
  51. p[len] = '\0';
  52. return p;
  53. }
  54. char *xstrndup(const char *str, size_t len)
  55. {
  56. char *p = memchr(str, '\0', len);
  57. return xmemdupz(str, p ? (size_t)(p - str) : len);
  58. }
  59. void *xrealloc(void *ptr, size_t size)
  60. {
  61. void *ret = realloc(ptr, size);
  62. if (!ret && !size)
  63. ret = realloc(ptr, 1);
  64. if (!ret) {
  65. release_pack_memory(size, -1);
  66. ret = realloc(ptr, size);
  67. if (!ret && !size)
  68. ret = realloc(ptr, 1);
  69. if (!ret)
  70. die("Out of memory, realloc failed");
  71. }
  72. return ret;
  73. }
  74. /*
  75. * xread() is the same a read(), but it automatically restarts read()
  76. * operations with a recoverable error (EAGAIN and EINTR). xread()
  77. * DOES NOT GUARANTEE that "len" bytes is read even if the data is available.
  78. */
  79. static ssize_t xread(int fd, void *buf, size_t len)
  80. {
  81. ssize_t nr;
  82. while (1) {
  83. nr = read(fd, buf, len);
  84. if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
  85. continue;
  86. return nr;
  87. }
  88. }
  89. /*
  90. * xwrite() is the same a write(), but it automatically restarts write()
  91. * operations with a recoverable error (EAGAIN and EINTR). xwrite() DOES NOT
  92. * GUARANTEE that "len" bytes is written even if the operation is successful.
  93. */
  94. static ssize_t xwrite(int fd, const void *buf, size_t len)
  95. {
  96. ssize_t nr;
  97. while (1) {
  98. nr = write(fd, buf, len);
  99. if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
  100. continue;
  101. return nr;
  102. }
  103. }
  104. ssize_t read_in_full(int fd, void *buf, size_t count)
  105. {
  106. char *p = buf;
  107. ssize_t total = 0;
  108. while (count > 0) {
  109. ssize_t loaded = xread(fd, p, count);
  110. if (loaded <= 0)
  111. return total ? total : loaded;
  112. count -= loaded;
  113. p += loaded;
  114. total += loaded;
  115. }
  116. return total;
  117. }
  118. ssize_t write_in_full(int fd, const void *buf, size_t count)
  119. {
  120. const char *p = buf;
  121. ssize_t total = 0;
  122. while (count > 0) {
  123. ssize_t written = xwrite(fd, p, count);
  124. if (written < 0)
  125. return -1;
  126. if (!written) {
  127. errno = ENOSPC;
  128. return -1;
  129. }
  130. count -= written;
  131. p += written;
  132. total += written;
  133. }
  134. return total;
  135. }