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