1/* Copyright (C) 2008 The Android Open Source Project
2**
3** This software is licensed under the terms of the GNU General Public
4** License version 2, as published by the Free Software Foundation, and
5** may be copied, distributed, and modified under those terms.
6**
7** This program is distributed in the hope that it will be useful,
8** but WITHOUT ANY WARRANTY; without even the implied warranty of
9** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10** GNU General Public License for more details.
11*/
12#include "android/utils/system.h"
13#include "android/utils/assert.h"
14#include <stdlib.h>
15#include <stdio.h>
16#ifdef _WIN32
17#  define WIN32_LEAN_AND_MEAN
18#  include <windows.h>  /* for Sleep */
19#else
20#  include <unistd.h>  /* for usleep */
21#endif
22
23void*
24android_alloc( size_t  size )
25{
26    void*   block;
27
28    if (size == 0)
29        return NULL;
30
31    block = malloc(size);
32    if (block != NULL)
33        return block;
34
35    fprintf(stderr, "PANIC: not enough memory\n");
36    exit(1);
37    return NULL;
38}
39
40void*
41android_alloc0( size_t  size )
42{
43    void*   block;
44
45    if (size == 0)
46        return NULL;
47
48    block = calloc(1, size);
49    if (block != NULL)
50        return block;
51
52    fprintf(stderr, "PANIC: not enough memory\n");
53    exit(1);
54    return NULL;
55}
56
57void*
58android_realloc( void*  block, size_t  size )
59{
60    void*   block2;
61
62    if (size == 0) {
63        free(block);
64        return NULL;
65    }
66    block2 = realloc(block, size);
67    if (block2 != NULL)
68        return block2;
69
70    fprintf(stderr, "PANIC: not enough memory to reallocate %zu bytes\n", size);
71    exit(1);
72    return NULL;
73}
74
75void
76android_free( void*  block )
77{
78    if (block)
79        free(block);
80}
81
82void*
83_android_array_alloc( size_t  itemSize, size_t  count )
84{
85#if ACONFIG_USE_ASSERT
86    size_t  maxSize;
87
88    if (itemSize == 0)
89        AASSERT_FAIL("item size is 0\n");
90
91    maxSize = (~(size_t)0) / itemSize;
92    if (count > maxSize)
93        AASSERT_FAIL("allocation too large (%d > %d)\n", count, maxSize);
94#endif
95    return android_alloc(itemSize * count);
96}
97
98void*
99_android_array_alloc0( size_t  itemSize, size_t  count )
100{
101    void*  block = _android_array_alloc(itemSize, count);
102    memset(block, 0, itemSize*count);
103    return block;
104}
105
106void*
107_android_array_realloc( void* block, size_t  itemSize, size_t  count )
108{
109#if ACONFIG_USE_ASSERT
110    size_t  maxSize;
111
112    if (itemSize == 0)
113        AASSERT_FAIL("item size is 0\n");
114
115    maxSize = (~(size_t)0) / itemSize;
116    if (count > maxSize)
117        AASSERT_FAIL("reallocation of %d-bytes array too large (%d > %d)\n",
118                     itemSize, count, maxSize);
119#endif
120    return android_realloc(block, itemSize*count);
121}
122
123char*
124android_strdup( const char*  str )
125{
126    int    len;
127    char*  copy;
128
129    if (str == NULL)
130        return NULL;
131
132    len  = strlen(str);
133    copy = malloc(len+1);
134    memcpy(copy, str, len);
135    copy[len] = 0;
136
137    return copy;
138}
139
140#ifdef _WIN32
141char*
142win32_strsep(char**  pline, const char*  delim)
143{
144    char*  line = *pline;
145    char*  p    = line;
146
147    if (p == NULL)
148        return NULL;
149
150    for (;;) {
151        int          c = *p++;
152        const char*  q = delim;
153
154        if (c == 0) {
155            p = NULL;
156            break;
157        }
158
159        while (*q) {
160            if (*q == c) {
161                p[-1] = 0;
162                goto Exit;
163            }
164            q++;
165        }
166    }
167Exit:
168    *pline = p;
169    return line;
170}
171#endif
172
173
174void
175disable_sigalrm( signal_state_t  *state )
176{
177#ifdef _WIN32
178    (void)state;
179#else
180    sigset_t  set;
181
182    sigemptyset(&set);
183    sigaddset(&set, SIGALRM);
184    pthread_sigmask (SIG_BLOCK, &set, &state->old);
185#endif
186}
187
188void
189restore_sigalrm( signal_state_t  *state )
190{
191#ifdef _WIN32
192    (void)state;
193#else
194    pthread_sigmask (SIG_SETMASK, &state->old, NULL);
195#endif
196}
197
198void
199sleep_ms( int  timeout_ms )
200{
201#ifdef _WIN32
202    if (timeout_ms <= 0)
203        return;
204
205    Sleep( timeout_ms );
206#else
207    if (timeout_ms <= 0)
208        return;
209
210    BEGIN_NOSIGALRM
211    usleep( timeout_ms*1000 );
212    END_NOSIGALRM
213#endif
214}
215