1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License.
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License.
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Miscellaneous utility functions.
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "Dalvik.h"
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <stdlib.h>
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <stddef.h>
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <string.h>
2410b0b7a8a1b91556b13c9156140f6ff7061b9f8cCarl Shapiro#include <strings.h>
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <ctype.h>
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <time.h>
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <sys/time.h>
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <fcntl.h>
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Print a hex dump in this format:
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project01234567: 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff  0123456789abcdef\n
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If "mode" is kHexDumpLocal, we start at offset zero, and show a full
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 16 bytes on the first line.  If it's kHexDumpMem, we make this look
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * like a memory dump, using the actual address, outputting a partial line
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if "vaddr" isn't aligned on a 16-byte boundary.
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "priority" and "tag" determine the values passed to the log calls.
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Does not use printf() or other string-formatting calls.
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmPrintHexDumpEx(int priority, const char* tag, const void* vaddr,
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    size_t length, HexDumpMode mode)
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static const char gHexDigit[] = "0123456789abcdef";
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const unsigned char* addr = vaddr;
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    char out[77];           /* exact fit */
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    unsigned int offset;    /* offset to show while printing */
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    char* hex;
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    char* asc;
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int gap;
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    //int trickle = 0;
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (mode == kHexDumpLocal)
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        offset = 0;
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        offset = (int) addr;
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    memset(out, ' ', sizeof(out)-1);
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    out[8] = ':';
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    out[sizeof(out)-2] = '\n';
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    out[sizeof(out)-1] = '\0';
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    gap = (int) offset & 0x0f;
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    while (length) {
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        unsigned int lineOffset = offset & ~0x0f;
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int i, count;
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        hex = out;
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        asc = out + 59;
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (i = 0; i < 8; i++) {
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            *hex++ = gHexDigit[lineOffset >> 28];
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            lineOffset <<= 4;
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        hex++;
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        hex++;
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        count = ((int)length > 16-gap) ? 16-gap : (int)length; /* cap length */
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(count != 0);
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(count+gap <= 16);
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (gap) {
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /* only on first line */
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            hex += gap * 3;
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            asc += gap;
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (i = gap ; i < count+gap; i++) {
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            *hex++ = gHexDigit[*addr >> 4];
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            *hex++ = gHexDigit[*addr & 0x0f];
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            hex++;
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (*addr >= 0x20 && *addr < 0x7f /*isprint(*addr)*/)
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                *asc++ = *addr;
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            else
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                *asc++ = '.';
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            addr++;
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for ( ; i < 16; i++) {
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /* erase extra stuff; only happens on last line */
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            *hex++ = ' ';
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            *hex++ = ' ';
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            hex++;
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            *asc++ = ' ';
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOG_PRI(priority, tag, "%s", out);
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 //def HAVE_ANDROID_OS
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * We can overrun logcat easily by writing at full speed.  On the
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * other hand, we can make Eclipse time out if we're showing
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * packet dumps while debugging JDWP.
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (trickle++ == 8) {
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                trickle = 0;
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                usleep(20000);
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        gap = 0;
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        length -= count;
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        offset += count;
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Fill out a DebugOutputTarget, suitable for printing to the log.
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmCreateLogOutputTarget(DebugOutputTarget* target, int priority,
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const char* tag)
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(target != NULL);
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(tag != NULL);
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    target->which = kDebugTargetLog;
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    target->data.log.priority = priority;
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    target->data.log.tag = tag;
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Fill out a DebugOutputTarget suitable for printing to a file pointer.
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmCreateFileOutputTarget(DebugOutputTarget* target, FILE* fp)
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(target != NULL);
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(fp != NULL);
153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    target->which = kDebugTargetFile;
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    target->data.file.fp = fp;
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Free "target" and any associated data.
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmFreeOutputTarget(DebugOutputTarget* target)
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    free(target);
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Print a debug message, to either a file or the log.
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmPrintDebugMessage(const DebugOutputTarget* target, const char* format,
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ...)
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    va_list args;
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    va_start(args, format);
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    switch (target->which) {
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case kDebugTargetLog:
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOG_PRI_VA(target->data.log.priority, target->data.log.tag,
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            format, args);
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case kDebugTargetFile:
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vfprintf(target->data.file.fp, format, args);
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    default:
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("unexpected 'which' %d\n", target->which);
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    va_end(args);
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Allocate a bit vector with enough space to hold at least the specified
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * number of bits.
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectBitVector* dvmAllocBitVector(int startBits, bool expandable)
198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    BitVector* bv;
200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int count;
201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(sizeof(bv->storage[0]) == 4);        /* assuming 32-bit units */
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(startBits >= 0);
204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bv = (BitVector*) malloc(sizeof(BitVector));
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    count = (startBits + 31) >> 5;
208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bv->storageSize = count;
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bv->expandable = expandable;
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bv->storage = (u4*) malloc(count * sizeof(u4));
212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    memset(bv->storage, 0x00, count * sizeof(u4));
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return bv;
214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Free a BitVector.
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmFreeBitVector(BitVector* pBits)
220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (pBits == NULL)
222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return;
223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    free(pBits->storage);
225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    free(pBits);
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "Allocate" the first-available bit in the bitmap.
230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This is not synchronized.  The caller is expected to hold some sort of
232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * lock that prevents multiple threads from executing simultaneously in
233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * dvmAllocBit/dvmFreeBit.
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint dvmAllocBit(BitVector* pBits)
236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int word, bit;
238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectretry:
240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    for (word = 0; word < pBits->storageSize; word++) {
241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (pBits->storage[word] != 0xffffffff) {
242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * There are unallocated bits in this word.  Return the first.
244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            bit = ffs(~(pBits->storage[word])) -1;
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            assert(bit >= 0 && bit < 32);
247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            pBits->storage[word] |= 1 << bit;
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return (word << 5) | bit;
249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Ran out of space, allocate more if we're allowed to.
254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (!pBits->expandable)
256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return -1;
257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pBits->storage = realloc(pBits->storage,
259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    (pBits->storageSize + kBitVectorGrowth) * sizeof(u4));
260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    memset(&pBits->storage[pBits->storageSize], 0x00,
261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        kBitVectorGrowth * sizeof(u4));
262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pBits->storageSize += kBitVectorGrowth;
263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    goto retry;
264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Mark the specified bit as "set".
268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns "false" if the bit is outside the range of the vector and we're
270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * not allowed to expand.
271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmSetBit(BitVector* pBits, int num)
273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(num >= 0);
275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (num >= pBits->storageSize * (int)sizeof(u4) * 8) {
276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!pBits->expandable)
277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return false;
278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int newSize = (num + 31) >> 5;
280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(newSize > pBits->storageSize);
281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pBits->storage = realloc(pBits->storage, newSize * sizeof(u4));
282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        memset(&pBits->storage[pBits->storageSize], 0x00,
283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            (newSize - pBits->storageSize) * sizeof(u4));
28401651b44f6b8cff9cb390748ae1af921f253305dAndy McFadden        pBits->storageSize = newSize;
285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pBits->storage[num >> 5] |= 1 << (num & 0x1f);
288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return true;
289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Mark the specified bit as "clear".
293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmClearBit(BitVector* pBits, int num)
295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(num >= 0 && num < (int) pBits->storageSize * (int)sizeof(u4) * 8);
297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pBits->storage[num >> 5] &= ~(1 << (num & 0x1f));
299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
302e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng * Mark all bits bit as "clear".
303e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng */
304e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Chengvoid dvmClearAllBits(BitVector* pBits)
305e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng{
306e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng    int count = pBits->storageSize;
307e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng    memset(pBits->storage, 0, count * sizeof(u4));
308e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng}
309e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng
310e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng/*
311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Determine whether or not the specified bit is set.
312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmIsBitSet(const BitVector* pBits, int num)
314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(num >= 0 && num < (int) pBits->storageSize * (int)sizeof(u4) * 8);
316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int val = pBits->storage[num >> 5] & (1 << (num & 0x1f));
318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return (val != 0);
319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Count the number of bits that are set.
323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint dvmCountSetBits(const BitVector* pBits)
325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int word, bit;
327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int count = 0;
328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    for (word = 0; word < pBits->storageSize; word++) {
330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        u4 val = pBits->storage[word];
331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (val != 0) {
333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (val == 0xffffffff) {
334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                count += 32;
335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else {
336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                /* count the number of '1' bits */
337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                while (val != 0) {
338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    val &= val - 1;
339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    count++;
340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return count;
346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
3494238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng * Copy a whole vector to the other. Only do that when the both vectors have
3504238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng * the same size and attribute.
3514238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng */
3524238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Chengbool dvmCopyBitVector(BitVector *dest, const BitVector *src)
3534238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng{
3544238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng    if (dest->storageSize != src->storageSize ||
3554238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng        dest->expandable != src->expandable)
3564238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng        return false;
3574238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng    memcpy(dest->storage, src->storage, sizeof(u4) * dest->storageSize);
3584238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng    return true;
3594238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng}
3604238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng
3614238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng/*
3624238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng * Intersect two bit vectores and merge the result on top of the pre-existing
3634238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng * value in the dest vector.
3644238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng */
3654238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Chengbool dvmIntersectBitVectors(BitVector *dest, const BitVector *src1,
3664238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng                            const BitVector *src2)
3674238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng{
3684238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng    if (dest->storageSize != src1->storageSize ||
3694238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng        dest->storageSize != src2->storageSize ||
3704238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng        dest->expandable != src1->expandable ||
3714238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng        dest->expandable != src2->expandable)
3724238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng        return false;
3734238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng
3744238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng    int i;
3754238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng    for (i = 0; i < dest->storageSize; i++) {
3764238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng        dest->storage[i] |= src1->storage[i] & src2->storage[i];
3774238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng    }
3784238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng    return true;
3794238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng}
3804238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng
3814238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng/*
382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return a newly-allocated string in which all occurrences of '.' have
383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * been changed to '/'.  If we find a '/' in the original string, NULL
384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is returned to avoid ambiguity.
385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectchar* dvmDotToSlash(const char* str)
387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    char* newStr = strdup(str);
389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    char* cp = newStr;
390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
391f905853a8ae31d433032cf01fa3eeecafc8aa6c6Andy McFadden    if (newStr == NULL)
392f905853a8ae31d433032cf01fa3eeecafc8aa6c6Andy McFadden        return NULL;
393f905853a8ae31d433032cf01fa3eeecafc8aa6c6Andy McFadden
394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    while (*cp != '\0') {
395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (*cp == '/') {
396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            assert(false);
397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return NULL;
398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (*cp == '.')
400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            *cp = '/';
401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        cp++;
402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return newStr;
405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return a newly-allocated string for the "dot version" of the class
409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * name for the given type descriptor. That is, The initial "L" and
410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * final ";" (if any) have been removed and all occurrences of '/'
411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * have been changed to '.'.
412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectchar* dvmDescriptorToDot(const char* str)
414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    size_t at = strlen(str);
416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    char* newStr;
417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if ((at >= 2) && (str[0] == 'L') && (str[at - 1] == ';')) {
419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        at -= 2; /* Two fewer chars to copy. */
420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        str++; /* Skip the 'L'. */
421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    newStr = malloc(at + 1); /* Add one for the '\0'. */
424f905853a8ae31d433032cf01fa3eeecafc8aa6c6Andy McFadden    if (newStr == NULL)
425f905853a8ae31d433032cf01fa3eeecafc8aa6c6Andy McFadden        return NULL;
426f905853a8ae31d433032cf01fa3eeecafc8aa6c6Andy McFadden
427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    newStr[at] = '\0';
428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    while (at > 0) {
430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        at--;
431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        newStr[at] = (str[at] == '/') ? '.' : str[at];
432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return newStr;
435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return a newly-allocated string for the type descriptor
439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * corresponding to the "dot version" of the given class name. That
440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is, non-array names are surrounded by "L" and ";", and all
441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * occurrences of '.' are changed to '/'.
442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectchar* dvmDotToDescriptor(const char* str)
444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    size_t length = strlen(str);
446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int wrapElSemi = 0;
447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    char* newStr;
448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    char* at;
449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (str[0] != '[') {
451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        length += 2; /* for "L" and ";" */
452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        wrapElSemi = 1;
453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    newStr = at = malloc(length + 1); /* + 1 for the '\0' */
456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (newStr == NULL) {
458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return NULL;
459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (wrapElSemi) {
462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *(at++) = 'L';
463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    while (*str) {
466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        char c = *(str++);
467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (c == '.') {
468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            c = '/';
469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *(at++) = c;
471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (wrapElSemi) {
474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *(at++) = ';';
475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    *at = '\0';
478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return newStr;
479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return a newly-allocated string for the internal-form class name for
483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the given type descriptor. That is, the initial "L" and final ";" (if
484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * any) have been removed.
485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectchar* dvmDescriptorToName(const char* str)
487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (str[0] == 'L') {
489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        size_t length = strlen(str) - 1;
490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        char* newStr = malloc(length);
491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (newStr == NULL) {
493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return NULL;
494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        strlcpy(newStr, str + 1, length);
497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return newStr;
498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return strdup(str);
501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return a newly-allocated string for the type descriptor for the given
505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * internal-form class name. That is, a non-array class name will get
506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * surrounded by "L" and ";", while array names are left as-is.
507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectchar* dvmNameToDescriptor(const char* str)
509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (str[0] != '[') {
511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        size_t length = strlen(str);
512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        char* descriptor = malloc(length + 3);
513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (descriptor == NULL) {
515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return NULL;
516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        descriptor[0] = 'L';
519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        strcpy(descriptor + 1, str);
520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        descriptor[length + 1] = ';';
521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        descriptor[length + 2] = '\0';
522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return descriptor;
524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return strdup(str);
527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get a notion of the current time, in nanoseconds.  This is meant for
531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * computing durations (e.g. "operation X took 52nsec"), so the result
532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * should not be used to get the current date/time.
533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectu8 dvmGetRelativeTimeNsec(void)
535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef HAVE_POSIX_CLOCKS
537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    struct timespec now;
538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    clock_gettime(CLOCK_MONOTONIC, &now);
539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return (u8)now.tv_sec*1000000000LL + now.tv_nsec;
540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else
541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    struct timeval now;
542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    gettimeofday(&now, NULL);
543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return (u8)now.tv_sec*1000000000LL + now.tv_usec * 1000LL;
544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the per-thread CPU time, in nanoseconds.
549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Only useful for time deltas.
551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectu8 dvmGetThreadCpuTimeNsec(void)
553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef HAVE_POSIX_CLOCKS
555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    struct timespec now;
556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &now);
557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return (u8)now.tv_sec*1000000000LL + now.tv_nsec;
558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else
559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return (u8) -1;
560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the per-thread CPU time, in nanoseconds, for the specified thread.
565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectu8 dvmGetOtherThreadCpuTimeNsec(pthread_t thread)
567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 /*def HAVE_POSIX_CLOCKS*/
569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int clockId;
570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (pthread_getcpuclockid(thread, &clockId) != 0)
572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return (u8) -1;
573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    struct timespec now;
575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    clock_gettime(clockId, &now);
576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return (u8)now.tv_sec*1000000000LL + now.tv_nsec;
577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else
578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return (u8) -1;
579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Call this repeatedly, with successively higher values for "iteration",
585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to sleep for a period of time not to exceed "maxTotalSleep".
586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * For example, when called with iteration==0 we will sleep for a very
588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * brief time.  On the next call we will sleep for a longer time.  When
589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the sum total of all sleeps reaches "maxTotalSleep", this returns false.
590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The initial start time value for "relStartTime" MUST come from the
592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * dvmGetRelativeTimeUsec call.  On the device this must come from the
593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * monotonic clock source, not the wall clock.
594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This should be used wherever you might be tempted to call sched_yield()
596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in a loop.  The problem with sched_yield is that, for a high-priority
597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * thread, the kernel might not actually transfer control elsewhere.
598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns "false" if we were unable to sleep because our time was up.
600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmIterativeSleep(int iteration, int maxTotalSleep, u8 relStartTime)
602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const int minSleep = 10000;
604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u8 curTime;
605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int curDelay;
606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Get current time, and see if we've already exceeded the limit.
609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    curTime = dvmGetRelativeTimeUsec();
611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (curTime >= relStartTime + maxTotalSleep) {
612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGVV("exsl: sleep exceeded (start=%llu max=%d now=%llu)\n",
613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            relStartTime, maxTotalSleep, curTime);
614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return false;
615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Compute current delay.  We're bounded by "maxTotalSleep", so no
619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * real risk of overflow assuming "usleep" isn't returning early.
620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * (Besides, 2^30 usec is about 18 minutes by itself.)
621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * For iteration==0 we just call sched_yield(), so the first sleep
623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * at iteration==1 is actually (minSleep * 2).
624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    curDelay = minSleep;
626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    while (iteration-- > 0)
627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        curDelay *= 2;
628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(curDelay > 0);
629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (curTime + curDelay >= relStartTime + maxTotalSleep) {
631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGVV("exsl: reduced delay from %d to %d\n",
632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            curDelay, (int) ((relStartTime + maxTotalSleep) - curTime));
633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        curDelay = (int) ((relStartTime + maxTotalSleep) - curTime);
634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (iteration == 0) {
637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGVV("exsl: yield\n");
638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        sched_yield();
639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else {
640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGVV("exsl: sleep for %d\n", curDelay);
641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        usleep(curDelay);
642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return true;
644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Set the "close on exec" flag so we don't expose our file descriptors
649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to processes launched by us.
650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmSetCloseOnExec(int fd)
652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int flags;
654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * There's presently only one flag defined, so getting the previous
657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * value of the fd flags is probably unnecessary.
658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    flags = fcntl(fd, F_GETFD);
660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (flags < 0) {
661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("Unable to get fd flags for fd %d\n", fd);
662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return false;
663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0) {
665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("Unable to set close-on-exec for fd %d\n", fd);
666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return false;
667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return true;
669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if (!HAVE_STRLCPY)
672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* Implementation of strlcpy() for platforms that don't already have it. */
673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectsize_t strlcpy(char *dst, const char *src, size_t size) {
674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    size_t srcLength = strlen(src);
675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    size_t copyLength = srcLength;
676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (srcLength > (size - 1)) {
678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        copyLength = size - 1;
679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (size != 0) {
682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        strncpy(dst, src, copyLength);
683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dst[copyLength] = '\0';
684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return srcLength;
687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
689