/**
 * Allocate and initialize memory. Checks the return value, aborts if no more
 * memory is available.  Don't use GNUNET_xmemdup_ directly. Use the
 * GNUNET_memdup macro.
 *
 * @param buf buffer to initialize from (must contain size bytes)
 * @param size number of bytes to allocate
 * @param filename where is this call being made (for debugging)
 * @param linenumber line where this call is being made (for debugging)
 * @return allocated memory, never NULL
 */
void *
GNUNET_xmemdup_ (const void *buf, size_t size, const char *filename,
                 int linenumber)
{
  void *ret;

  /* As a security precaution, we generally do not allow very large
   * allocations here */
  GNUNET_assert_at (size <= GNUNET_MAX_MALLOC_CHECKED, filename, linenumber);
#ifdef W32_MEM_LIMIT
  size += sizeof (size_t);
  if (mem_used + size > W32_MEM_LIMIT)
    return NULL;
#endif
  GNUNET_assert_at (size < INT_MAX, filename, linenumber);
  ret = malloc (size);
  if (ret == NULL)
  {
    LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "malloc");
    GNUNET_abort ();
  }
#ifdef W32_MEM_LIMIT
  *((size_t *) ret) = size;
  ret = &((size_t *) ret)[1];
  mem_used += size;
#endif
  memcpy (ret, buf, size);
  return ret;
}
/**
 * Grow an array.  Grows old by (*oldCount-newCount)*elementSize bytes
 * and sets *oldCount to newCount.
 *
 * @param old address of the pointer to the array
 *        *old may be NULL
 * @param elementSize the size of the elements of the array
 * @param oldCount address of the number of elements in the *old array
 * @param newCount number of elements in the new array, may be 0
 * @param filename where in the code was the call to GNUNET_array_grow
 * @param linenumber where in the code was the call to GNUNET_array_grow
 */
void
GNUNET_xgrow_ (void **old, size_t elementSize, unsigned int *oldCount,
               unsigned int newCount, const char *filename, int linenumber)
{
  void *tmp;
  size_t size;

  GNUNET_assert_at (INT_MAX / elementSize > newCount, filename, linenumber);
  size = newCount * elementSize;
  if (size == 0)
  {
    tmp = NULL;
  }
  else
  {
    tmp = GNUNET_xmalloc_ (size, filename, linenumber);
    memset (tmp, 0, size);      /* client code should not rely on this, though... */
    if (*oldCount > newCount)
      *oldCount = newCount;     /* shrink is also allowed! */
    memcpy (tmp, *old, elementSize * (*oldCount));
  }

  if (*old != NULL)
  {
    GNUNET_xfree_ (*old, filename, linenumber);
  }
  *old = tmp;
  *oldCount = newCount;
}
示例#3
0
/**
 * Grow an array.  Grows old by (*oldCount-newCount)*elementSize bytes
 * and sets *oldCount to newCount.
 *
 * @param old address of the pointer to the array
 *        *old may be NULL
 * @param elementSize the size of the elements of the array
 * @param oldCount address of the number of elements in the *old array
 * @param newCount number of elements in the new array, may be 0
 * @param filename where in the code was the call to GNUNET_array_grow()
 * @param linenumber where in the code was the call to GNUNET_array_grow()
 */
void
GNUNET_xgrow_ (void **old,
	       size_t elementSize,
	       unsigned int *oldCount,
         unsigned int newCount,
	       const char *filename,
	       int linenumber)
{
  void *tmp;
  size_t size;

  GNUNET_assert_at (INT_MAX / elementSize > newCount, filename, linenumber);
  size = newCount * elementSize;
  if (0 == size)
  {
    tmp = NULL;
  }
  else
  {
    tmp = GNUNET_xmalloc_ (size, filename, linenumber);
    if (NULL != *old)
    {
      GNUNET_memcpy (tmp, *old, elementSize * GNUNET_MIN(*oldCount, newCount));
    }
  }

  if (NULL != *old)
  {
    GNUNET_xfree_ (*old, filename, linenumber);
  }
  *old = tmp;
  *oldCount = newCount;
}
示例#4
0
/**
 * Free memory. Merely a wrapper for the case that we
 * want to keep track of allocations.
 *
 * @param ptr the pointer to free
 * @param filename where in the code was the call to GNUNET_free
 * @param linenumber where in the code was the call to GNUNET_free
 */
void
GNUNET_xfree_ (void *ptr,
	       const char *filename,
	       int linenumber)
{
  GNUNET_assert_at (NULL != ptr,
		    filename,
		    linenumber);
#ifdef W32_MEM_LIMIT
  ptr = &((size_t *) ptr)[-1];
  mem_used -= *((size_t *) ptr);
#endif
#if defined(M_SIZE)
#if ENABLE_POISONING
  {
    const uint64_t baadfood = GNUNET_ntohll (0xBAADF00DBAADF00DLL);
    uint64_t *base = ptr;
    size_t s = M_SIZE (ptr);
    size_t i;

    for (i=0;i<s/8;i++)
      base[i] = baadfood;
    GNUNET_memcpy (&base[s/8], &baadfood, s % 8);
  }
#endif
#endif
  free (ptr);
}
/**
 * Dup a string (same semantics as strdup).
 *
 * @param str the string to dup
 * @param filename where in the code was the call to GNUNET_strdup
 * @param linenumber where in the code was the call to GNUNET_strdup
 * @return strdup(str)
 */
char *
GNUNET_xstrdup_ (const char *str, const char *filename, int linenumber)
{
  char *res;

  GNUNET_assert_at (str != NULL, filename, linenumber);
  res = GNUNET_xmalloc_ (strlen (str) + 1, filename, linenumber);
  memcpy (res, str, strlen (str) + 1);
  return res;
}
/**
 * Dup partially a string (same semantics as strndup).
 *
 * @param str the string to dup
 * @param len the length of the string to dup
 * @param filename where in the code was the call to GNUNET_strndup
 * @param linenumber where in the code was the call to GNUNET_strndup
 * @return strndup(str,len)
 */
char *
GNUNET_xstrndup_ (const char *str, size_t len, const char *filename,
                  int linenumber)
{
  char *res;

  GNUNET_assert_at (str != NULL, filename, linenumber);
  len = strnlen (str, len);
  res = GNUNET_xmalloc_ (len + 1, filename, linenumber);
  memcpy (res, str, len);
  /* res[len] = '\0'; 'malloc' zeros out anyway */
  return res;
}
/**
 * Allocate memory. Checks the return value, aborts if no more
 * memory is available.
 *
 * @param size how many bytes of memory to allocate, do NOT use
 *  this function (or GNUNET_malloc) to allocate more than several MB
 *  of memory, if you are possibly needing a very large chunk use
 *  GNUNET_xmalloc_unchecked_ instead.
 * @param filename where in the code was the call to GNUNET_malloc
 * @param linenumber where in the code was the call to GNUNET_malloc
 * @return pointer to size bytes of memory
 */
void *
GNUNET_xmalloc_ (size_t size, const char *filename, int linenumber)
{
  void *ret;

  /* As a security precaution, we generally do not allow very large
   * allocations using the default 'GNUNET_malloc' macro */
  GNUNET_assert_at (size <= GNUNET_MAX_MALLOC_CHECKED, filename, linenumber);
  ret = GNUNET_xmalloc_unchecked_ (size, filename, linenumber);
  if (ret == NULL)
  {
    LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "malloc");
    GNUNET_abort ();
  }
  return ret;
}
示例#8
0
/**
 * Dup a string (same semantics as strdup).
 *
 * @param str the string to dup
 * @param filename where in the code was the call to GNUNET_strdup()
 * @param linenumber where in the code was the call to GNUNET_strdup()
 * @return `strdup(@a str)`
 */
char *
GNUNET_xstrdup_ (const char *str,
		 const char *filename,
		 int linenumber)
{
  char *res;
  size_t slen;

  GNUNET_assert_at (str != NULL,
		    filename,
		    linenumber);
  slen = strlen (str) + 1;
  res = GNUNET_xmalloc_ (slen,
			 filename,
			 linenumber);
  GNUNET_memcpy (res,
	  str,
	  slen);
  return res;
}