diff mbox

[uclibc-ng-devel] Do not set *memptr to NULL for posix_memalign when fail

Message ID CA+yXCZA2WoDLbUTOZuN=jaGnLd9fqmjEDOuW5paVyJCXXp+qAg@mail.gmail.com
State Accepted
Headers show

Commit Message

Kito Cheng Feb. 23, 2017, 9:27 a.m. UTC
Hi all:

uclibc seem will set argument *memptr to NULL when posix_memalign[1]
fail, I know it's not specify in most document[1-3],
but other libc (newlib, glibc, musl) implementations are not set it to
NULL if fail and gcc testsuite have 1 test case for that[7], so how
about make uclib consistent to other libc?

the patch attached.


newlib[4]:
int
__posix_memalign (void **memptr, size_t alignment, size_t size)
{
  void *mem;

  /* Test whether the ALIGNMENT argument is valid.  It must be a power
     of two multiple of sizeof (void *).  */
  if (alignment % sizeof (void *) != 0 || (alignment & (alignment - 1)) != 0)
    return EINVAL;

  mem = __libc_memalign (alignment, size);

  if (mem != NULL) // only set when success
    {
      *memptr = mem;
      return 0;
    }

  return ENOMEM;
}


glibc [5]:
int
__posix_memalign (void **memptr, size_t alignment, size_t size)
{
  void *mem;

  /* Test whether the SIZE argument is valid.  It must be a power of
     two multiple of sizeof (void *).  */
  if (alignment % sizeof (void *) != 0
      || !powerof2 (alignment / sizeof (void *)) != 0
      || alignment == 0)
    return EINVAL;

  /* Call the hook here, so that caller is posix_memalign's caller
     and not posix_memalign itself.  */
  void *(*hook) (size_t, size_t, const void *) =
    force_reg (__memalign_hook);
  if (__builtin_expect (hook != NULL, 0))
    mem = (*hook)(alignment, size, RETURN_ADDRESS (0));
  else
    mem = __libc_memalign (alignment, size);

  if (mem != NULL) { // only set when success
    *memptr = mem;
    return 0;
  }

  return ENOMEM;
}


musl [6]:
int posix_memalign(void **res, size_t align, size_t len)
{
        if (align < sizeof(void *)) return EINVAL;
        void *mem = __memalign(align, len);
        if (!mem) return errno;
        *res = mem;  // only set when success
        return 0;
}



[1] http://man7.org/linux/man-pages/man3/posix_memalign.3.html
[2] http://pubs.opengroup.org/onlinepubs/009695399/functions/posix_memalign.html
[3] https://linux.die.net/man/3/posix_memalign
[4] https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;a=blob;f=newlib/libc/sys/linux/malloc.c;h=25007e8896a1292d6ae821aa35d7b8973ea99bad;hb=HEAD#l4938
[5] https://sourceware.org/git/?p=glibc.git;a=blob;f=malloc/malloc.c;h=488579390578e09a1a232ac5161daee086dbbd6b;hb=HEAD#l5086
[6] http://git.musl-libc.org/cgit/musl/tree/src/malloc/posix_memalign.c
[7] https://github.com/gcc-mirror/gcc/blob/master/gcc/testsuite/gcc.dg/torture/pr60092.c

Comments

Waldemar Brodkorb Feb. 26, 2017, 9:13 a.m. UTC | #1
Hi Kito,
Kito Cheng wrote,

> Hi all:
> 
> uclibc seem will set argument *memptr to NULL when posix_memalign[1]
> fail, I know it's not specify in most document[1-3],
> but other libc (newlib, glibc, musl) implementations are not set it to
> NULL if fail and gcc testsuite have 1 test case for that[7], so how
> about make uclib consistent to other libc?

Good idea, patch does run through regression testing and pushed,

Thanks
 best regards
   Waldemar
diff mbox

Patch

From a7e46cb115fae7d4de1cedddb0cbf2932b9ddf39 Mon Sep 17 00:00:00 2001
From: Kito Cheng <kito.cheng@gmail.com>
Date: Thu, 23 Feb 2017 17:16:28 +0800
Subject: [PATCH] Only set *memptr when success for posix_memalign

---
 libc/stdlib/posix_memalign.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/libc/stdlib/posix_memalign.c b/libc/stdlib/posix_memalign.c
index 523bc2c..0183107 100644
--- a/libc/stdlib/posix_memalign.c
+++ b/libc/stdlib/posix_memalign.c
@@ -34,8 +34,10 @@  int posix_memalign(void **memptr, size_t alignment, size_t size)
 	     || alignment == 0
 	     */
 		return EINVAL;
-
-	*memptr = memalign(alignment, size);
-
-	return (*memptr != NULL ? 0 : ENOMEM);
+	void *mem = memalign(alignment, size);
+	if (mem != NULL) {
+		*memptr = mem;
+		return 0;
+	} else
+		return ENOMEM;
 }
-- 
2.8.2