Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2006-06-12 17:59:36 +0400
committerCorinna Vinschen <corinna@vinschen.de>2006-06-12 17:59:36 +0400
commite3f56b2b3defb6954b10d5e43da8d258750a0c32 (patch)
treee1f1ca61b135cef166f622b2fe6b936c289d1996 /winsup/testsuite
parent730f10974a3f760650f58e01918f0deaa6ed8e79 (diff)
* winsup.api/user_malloc.c: New file.
Diffstat (limited to 'winsup/testsuite')
-rw-r--r--winsup/testsuite/ChangeLog4
-rw-r--r--winsup/testsuite/winsup.api/user_malloc.c216
2 files changed, 220 insertions, 0 deletions
diff --git a/winsup/testsuite/ChangeLog b/winsup/testsuite/ChangeLog
index 95162a4e9..8e8cdda2c 100644
--- a/winsup/testsuite/ChangeLog
+++ b/winsup/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2006-06-12 Pierre Humblet Pierre.Humblet@ieee.org
+
+ * winsup.api/user_malloc.c: New file.
+
2006-05-30 Christopher Faylor <cgf@timesys.com>
* winsup.api/cygload.h: Increase padding to 32768.
diff --git a/winsup/testsuite/winsup.api/user_malloc.c b/winsup/testsuite/winsup.api/user_malloc.c
new file mode 100644
index 000000000..8685f86ab
--- /dev/null
+++ b/winsup/testsuite/winsup.api/user_malloc.c
@@ -0,0 +1,216 @@
+/* Test of external malloc, calloc, realloc and free capability */
+
+#if 1
+#include "test.h"
+#include "usctest.h"
+#else
+enum {TPASS, TFAIL, TBROK, TINFO};
+#define tst_resm(xxx, yyy...) printf(yyy), printf(" RES %d\n", xxx)
+#define tst_brkm(xxx, yyy, zzz...) printf(zzz), printf(" RES %d\n", xxx)
+#define tst_exit()
+int Tst_count;
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <strings.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/wait.h>
+
+const char *TCID = "malloc"; /* Test program identifier. */
+int TST_TOTAL = 2; /* Total number of test cases. */
+extern int Tst_count; /* Test Case counter for tst_* routines */
+
+/* Main test.
+ Verbose mode if argc > 0
+ Note that malloc and friends are also called by Cygwin before main,
+ and that malloc can call getenv. */
+
+int malloc_error = 0, realloc_error = 0, free_error = 0;
+int calloc_count = 0, malloc_count = 0, realloc_count = 0, free_count = 0;
+
+void
+cleanup (void)
+{
+ tst_exit();
+}
+
+int
+syncwithchild (pid_t pid, int expected_exit_status)
+{
+ int status;
+
+ if (waitpid (pid, &status, 0) != pid)
+ {
+ tst_brkm (TBROK, cleanup, "Wait for child: %s", strerror (errno));
+ return 1;
+ }
+ if (!WIFEXITED (status))
+ {
+ tst_brkm (TBROK, cleanup, "Child had abnormal exit");
+ return 1;
+ }
+ if (WEXITSTATUS (status) != expected_exit_status)
+ {
+ tst_brkm (TFAIL, cleanup, "Child had exit status %d != %d",
+ WEXITSTATUS (status), expected_exit_status);
+ return 1;
+ }
+ return 0;
+}
+
+#if 0
+void * mallocX (size_t size);
+void * callocX (size_t nmemb, size_t size);
+void * reallocX (void * ptr, size_t size);
+void freeX(void *);
+
+#define malloc mallocX
+#define calloc callocX
+#define realloc reallocX
+#define free freeX
+#endif
+
+int main (int argc, char * argv[])
+{
+ void * ptr;
+ int error = 0;
+ pid_t pid;
+
+ Tst_count = 0;
+
+ tst_resm(TINFO, "Testing if external malloc works. ppid %d", getppid());
+
+ ptr = malloc (16);
+ ptr = calloc (1, 16);
+ ptr = realloc (ptr, 24);
+ free (ptr);
+
+ error = (malloc_count == 0 || calloc_count == 0 || realloc_count == 0 || free_count == 0);
+
+ if (error || argc > 1)
+ {
+ printf ("malloc_count %d, calloc_count %d, realloc_count %d, free_count %d\n",
+ malloc_count, calloc_count, realloc_count, free_count);
+ printf ("malloc_error %d, realloc_error %d, free_error %d\n",
+ malloc_error, realloc_error, free_error);
+ }
+ tst_resm (!error ? TPASS : TFAIL, "Running in pid %d", getpid());
+
+ /* If run from Windows, run also from Cygwin */
+ if (getppid() == 1)
+ {
+ tst_resm(TINFO, "Ready to test if malloc works from Cygwin");
+
+ if ((pid = fork()) == 0)
+ {
+ tst_resm(TINFO, "Ready to exec with pid %d\n", getpid());
+ error = execl(argv[0], argv[0], argc > 1? argv[1]:NULL, NULL);
+ exit(error);
+ }
+ else if (pid < 0)
+ tst_brkm (TBROK, cleanup, "Fork failed: %s", strerror (errno));
+ else
+ {
+ error = syncwithchild (pid, 0);
+ tst_resm (!error ? TPASS : TFAIL, "Running in pid %d", pid);
+ }
+ }
+
+ tst_exit ();
+}
+
+/****************************************
+Actual malloc & friends implementation
+****************************************/
+
+typedef unsigned long long ull;
+
+#define SIZE (1024*1024ULL) /* long long */
+ull buffer[SIZE];
+ull * current = buffer;
+
+static int is_valid (void * ptr)
+{
+ unsigned int iptr = (unsigned int) ptr;
+ ull * ullptr = (ull *) ptr;
+
+ iptr = (iptr / sizeof(ull)) * sizeof(ull);
+ if (iptr != (int) ptr)
+ return 0;
+ if (--ullptr < buffer || ullptr[0] > SIZE || ullptr + ullptr[0] > current)
+ return 0;
+ return 1;
+}
+
+void * malloc (size_t size)
+{
+ ull llsize = (size + 2 * sizeof (ull) - 1) / sizeof (ull);
+ static char * envptr;
+ void * ret;
+
+ /* Make sure getenv works */
+ if (!envptr)
+ envptr = getenv ("PATH");
+
+ malloc_count++;
+ if (current + llsize >= buffer + SIZE)
+ {
+ malloc_error++;
+ errno = ENOMEM;
+ return NULL;
+ }
+ *current = llsize;
+ ret = (void *) (current + 1);
+ current += llsize;
+
+ return ret;
+}
+
+void * calloc (size_t nmemb, size_t size)
+{
+ calloc_count++;
+ void * ptr = malloc (nmemb * size);
+ malloc_count--;
+ if (ptr)
+ memset(ptr, 0, nmemb * size);
+ return ptr;
+}
+
+void * realloc (void * ptr, size_t size)
+{
+ const ull ullsize = (size + 2 * sizeof (ull) - 1) / sizeof (ull);
+ ull * const ullptr = (ull *) ptr;
+ void * newptr;
+
+ realloc_count++;
+
+ if (ptr)
+ {
+ if (!is_valid (ptr))
+ {
+ realloc_error++;
+ errno = ENOMEM;
+ return NULL;
+ }
+ if (ullptr[-1] >= ullsize)
+ return ptr;
+ }
+
+ newptr = malloc (size);
+ malloc_count--;
+
+ if (ptr && newptr)
+ memcpy (newptr, ptr, size);
+
+ return newptr;
+}
+
+void free (void * x)
+{
+ free_count++;
+ if (x && ! is_valid (x))
+ free_error++;
+}
+