18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Copyright (C) 2008 The Android Open Source Project
28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project**
38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This software is licensed under the terms of the GNU General Public
48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** License version 2, as published by the Free Software Foundation, and
58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** may be copied, distributed, and modified under those terms.
68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project**
78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This program is distributed in the hope that it will be useful,
88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** but WITHOUT ANY WARRANTY; without even the implied warranty of
98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** GNU General Public License for more details.
118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/
128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/system.h"
134c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner#include "android/utils/assert.h"
148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdlib.h>
158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdio.h>
168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32
178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  define WIN32_LEAN_AND_MEAN
188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  include <windows.h>  /* for Sleep */
198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  include <unistd.h>  /* for usleep */
218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid*
248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectandroid_alloc( size_t  size )
258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    void*   block;
278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (size == 0)
298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return NULL;
308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    block = malloc(size);
328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (block != NULL)
338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return block;
348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    fprintf(stderr, "PANIC: not enough memory\n");
368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    exit(1);
378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return NULL;
388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid*
418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectandroid_alloc0( size_t  size )
428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    void*   block;
448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (size == 0)
468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return NULL;
478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    block = calloc(1, size);
498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (block != NULL)
508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return block;
518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    fprintf(stderr, "PANIC: not enough memory\n");
538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    exit(1);
548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return NULL;
558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid*
588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectandroid_realloc( void*  block, size_t  size )
598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    void*   block2;
618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (size == 0) {
638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        free(block);
648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return NULL;
658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    block2 = realloc(block, size);
678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (block2 != NULL)
688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return block2;
698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
70c7389bd69e570a2c8432b37399aff1976b021f0fAndrew Hsieh    fprintf(stderr, "PANIC: not enough memory to reallocate %zu bytes\n", size);
718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    exit(1);
728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return NULL;
738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectandroid_free( void*  block )
778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (block)
798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        free(block);
808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
824c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turnervoid*
834c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner_android_array_alloc( size_t  itemSize, size_t  count )
844c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner{
854c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner#if ACONFIG_USE_ASSERT
864c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner    size_t  maxSize;
874c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner
884c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner    if (itemSize == 0)
894c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner        AASSERT_FAIL("item size is 0\n");
904c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner
914c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner    maxSize = (~(size_t)0) / itemSize;
924c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner    if (count > maxSize)
934c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner        AASSERT_FAIL("allocation too large (%d > %d)\n", count, maxSize);
944c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner#endif
954c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner    return android_alloc(itemSize * count);
964c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner}
974c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner
984c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turnervoid*
994c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner_android_array_alloc0( size_t  itemSize, size_t  count )
1004c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner{
1014c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner    void*  block = _android_array_alloc(itemSize, count);
1024c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner    memset(block, 0, itemSize*count);
1034c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner    return block;
1044c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner}
1054c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner
1064c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turnervoid*
1074c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner_android_array_realloc( void* block, size_t  itemSize, size_t  count )
1084c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner{
1094c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner#if ACONFIG_USE_ASSERT
1104c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner    size_t  maxSize;
1114c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner
1124c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner    if (itemSize == 0)
1134c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner        AASSERT_FAIL("item size is 0\n");
1144c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner
1154c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner    maxSize = (~(size_t)0) / itemSize;
1164c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner    if (count > maxSize)
1174c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner        AASSERT_FAIL("reallocation of %d-bytes array too large (%d > %d)\n",
1184c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner                     itemSize, count, maxSize);
1194c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner#endif
1204c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner    return android_realloc(block, itemSize*count);
1214c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner}
1224c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner
1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectchar*
1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectandroid_strdup( const char*  str )
1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int    len;
1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char*  copy;
1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (str == NULL)
1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return NULL;
1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    len  = strlen(str);
1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    copy = malloc(len+1);
1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    memcpy(copy, str, len);
1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    copy[len] = 0;
1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return copy;
1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32
1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectchar*
1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectwin32_strsep(char**  pline, const char*  delim)
1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char*  line = *pline;
1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char*  p    = line;
1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (p == NULL)
1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return NULL;
1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (;;) {
1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int          c = *p++;
1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        const char*  q = delim;
1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (c == 0) {
1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p = NULL;
1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        while (*q) {
1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (*q == c) {
1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                p[-1] = 0;
1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                goto Exit;
1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            q++;
1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
16718fe86e8245878f3b7a2813bd59b8cfcf636e15cDavid 'Digit' TurnerExit:
1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *pline = p;
1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return line;
1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdisable_sigalrm( signal_state_t  *state )
1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32
1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    (void)state;
1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sigset_t  set;
1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sigemptyset(&set);
1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sigaddset(&set, SIGALRM);
1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    pthread_sigmask (SIG_BLOCK, &set, &state->old);
1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectrestore_sigalrm( signal_state_t  *state )
1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32
1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    (void)state;
1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    pthread_sigmask (SIG_SETMASK, &state->old, NULL);
1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsleep_ms( int  timeout_ms )
2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32
2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (timeout_ms <= 0)
2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    Sleep( timeout_ms );
2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (timeout_ms <= 0)
2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    BEGIN_NOSIGALRM
2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    usleep( timeout_ms*1000 );
2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    END_NOSIGALRM
2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
215