1 /* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #define LOG_TAG "NativeHandle" 18 19 #include <errno.h> 20 #include <stdint.h> 21 #include <stdlib.h> 22 #include <string.h> 23 #include <unistd.h> 24 25 #include <android/log.h> 26 #include <cutils/native_handle.h> 27 28 static const int kMaxNativeFds = 1024; 29 static const int kMaxNativeInts = 1024; 30 31 native_handle_t* native_handle_init(char* storage, int numFds, int numInts) 32 { 33 if ((uintptr_t) storage % alignof(native_handle_t)) { 34 return NULL; 35 } 36 37 native_handle_t* handle = (native_handle_t*) storage; 38 handle->version = sizeof(native_handle_t); 39 handle->numFds = numFds; 40 handle->numInts = numInts; 41 42 return handle; 43 } 44 45 native_handle_t* native_handle_create(int numFds, int numInts) 46 { 47 if (numFds < 0 || numInts < 0 || numFds > kMaxNativeFds || numInts > kMaxNativeInts) { 48 return NULL; 49 } 50 51 size_t mallocSize = sizeof(native_handle_t) + (sizeof(int) * (numFds + numInts)); 52 native_handle_t* h = malloc(mallocSize); 53 if (h) { 54 h->version = sizeof(native_handle_t); 55 h->numFds = numFds; 56 h->numInts = numInts; 57 } 58 return h; 59 } 60 61 native_handle_t* native_handle_clone(const native_handle_t* handle) 62 { 63 native_handle_t* clone = native_handle_create(handle->numFds, handle->numInts); 64 int i; 65 66 for (i = 0; i < handle->numFds; i++) { 67 clone->data[i] = dup(handle->data[i]); 68 if (clone->data[i] < 0) { 69 clone->numFds = i; 70 native_handle_close(clone); 71 native_handle_delete(clone); 72 return NULL; 73 } 74 } 75 76 memcpy(&clone->data[handle->numFds], &handle->data[handle->numFds], 77 sizeof(int) * handle->numInts); 78 79 return clone; 80 } 81 82 int native_handle_delete(native_handle_t* h) 83 { 84 if (h) { 85 if (h->version != sizeof(native_handle_t)) 86 return -EINVAL; 87 free(h); 88 } 89 return 0; 90 } 91 92 int native_handle_close(const native_handle_t* h) 93 { 94 if (h->version != sizeof(native_handle_t)) 95 return -EINVAL; 96 97 const int numFds = h->numFds; 98 int i; 99 for (i=0 ; i<numFds ; i++) { 100 close(h->data[i]); 101 } 102 return 0; 103 } 104