/src/common/xmalloc.c

https://code.google.com/ · C · 153 lines · 82 code · 18 blank · 53 comment · 14 complexity · e025446b7169135f6400e6fb1c74426e MD5 · raw file

  1. /*****************************************************************************\
  2. * $Id$
  3. *****************************************************************************
  4. * Copyright (C) 2001-2006 The Regents of the University of California.
  5. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
  6. * Written by Jim Garlick <garlick@llnl.gov>.
  7. * UCRL-CODE-2003-005.
  8. *
  9. * This file is part of Pdsh, a parallel remote shell program.
  10. * For details, see <http://www.llnl.gov/linux/pdsh/>.
  11. *
  12. * Pdsh is free software; you can redistribute it and/or modify it under
  13. * the terms of the GNU General Public License as published by the Free
  14. * Software Foundation; either version 2 of the License, or (at your option)
  15. * any later version.
  16. *
  17. * Pdsh is distributed in the hope that it will be useful, but WITHOUT ANY
  18. * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  19. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  20. * details.
  21. *
  22. * You should have received a copy of the GNU General Public License along
  23. * with Pdsh; if not, write to the Free Software Foundation, Inc.,
  24. * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  25. \*****************************************************************************/
  26. #if HAVE_CONFIG_H
  27. #include "config.h"
  28. #endif
  29. #include <stdlib.h>
  30. #include <errno.h>
  31. #include <string.h>
  32. #include <stdio.h>
  33. #include <limits.h> /* for INT_MAX */
  34. #include <assert.h>
  35. #include "xmalloc.h"
  36. #if HAVE_UNSAFE_MALLOC
  37. #include <pthread.h>
  38. static pthread_mutex_t malloc_lock = PTHREAD_MUTEX_INITIALIZER;
  39. #define MALLOC_LOCK() pthread_mutex_lock(&malloc_lock)
  40. #define MALLOC_UNLOCK() pthread_mutex_unlock(&malloc_lock)
  41. #else
  42. #define MALLOC_LOCK()
  43. #define MALLOC_UNLOCK()
  44. #endif
  45. /*
  46. * "Safe" version of malloc().
  47. * size (IN) number of bytes to malloc
  48. * RETURN pointer to allocate heap space
  49. */
  50. void *Malloc(size_t size)
  51. {
  52. void *new;
  53. int *p;
  54. assert(size > 0 && size <= INT_MAX);
  55. MALLOC_LOCK();
  56. p = (int *) malloc(size + 2 * sizeof(int));
  57. MALLOC_UNLOCK();
  58. if (!p) {
  59. fprintf(stderr, "Malloc(%ld) failed\n", (long) size);
  60. exit(1);
  61. }
  62. p[0] = XMALLOC_MAGIC; /* add "secret" magic cookie */
  63. p[1] = size; /* store size in buffer */
  64. new = &p[2];
  65. memset(new, 0, size);
  66. return new;
  67. }
  68. /*
  69. * "Safe" version of realloc(). Args are different: pass in a pointer to
  70. * the object to be realloced instead of the object itself.
  71. * item (IN/OUT) double-pointer to allocated space
  72. * newsize (IN) requested size
  73. */
  74. void Realloc(void **item, size_t newsize)
  75. {
  76. int *p = (int *) *item - 2;
  77. assert(*item != NULL);
  78. assert(newsize > 0 && newsize <= INT_MAX);
  79. assert(p[0] == XMALLOC_MAGIC); /* magic cookie still there? */
  80. MALLOC_LOCK();
  81. p = (int *) realloc(p, newsize + 2 * sizeof(int));
  82. MALLOC_UNLOCK();
  83. if (!p) {
  84. fprintf(stderr, "Realloc(%ld) failed\n", (long) newsize);
  85. exit(1);
  86. }
  87. assert(p[0] == XMALLOC_MAGIC);
  88. p[1] = newsize;
  89. *item = &p[2];
  90. }
  91. /*
  92. * Duplicate a string.
  93. * str (IN) string to duplicate
  94. * RETURN copy of string
  95. */
  96. char *Strdup(const char *str)
  97. {
  98. char *result;
  99. if (str == NULL)
  100. return NULL;
  101. else
  102. result = Malloc(strlen(str) + 1);
  103. return strcpy(result, str);
  104. }
  105. /*
  106. * Return the size of a buffer.
  107. * item (IN) pointer to allocated space
  108. */
  109. int Size(void *item)
  110. {
  111. int *p = (int *) item - 2;
  112. assert(item != NULL);
  113. assert(p[0] == XMALLOC_MAGIC);
  114. return p[1];
  115. }
  116. /*
  117. * Free which takes a pointer to object to free, which it turns into a null
  118. * object.
  119. * item (IN/OUT) double-pointer to allocated space
  120. */
  121. void Free(void **item)
  122. {
  123. int *p = (int *) *item - 2;
  124. if (*item != NULL) {
  125. assert(p[0] == XMALLOC_MAGIC); /* magic cookie still there? */
  126. p[0] = 0;
  127. MALLOC_LOCK();
  128. free(p);
  129. MALLOC_UNLOCK();
  130. *item = NULL;
  131. }
  132. }
  133. /*
  134. * vi:tabstop=4 shiftwidth=4 expandtab
  135. */