1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * you may not use this file except in compliance with the License. 6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * You may obtain a copy of the License at 7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * See the License for the specific language governing permissions and 14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * limitations under the License. 15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define LOG_TAG "properties" 18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h> 20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h> 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h> 22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <cutils/sockets.h> 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h> 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <assert.h> 25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <cutils/properties.h> 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "loghack.h" 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef HAVE_LIBC_SYSTEM_PROPERTIES 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_ 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/_system_properties.h> 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int send_prop_msg(prop_msg *msg) 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int s; 37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int r; 38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s = socket_local_client(PROP_SERVICE_NAME, 40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ANDROID_SOCKET_NAMESPACE_RESERVED, 41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SOCK_STREAM); 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(s < 0) return -1; 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while((r = send(s, msg, sizeof(prop_msg), 0)) < 0) { 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((errno == EINTR) || (errno == EAGAIN)) continue; 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r == sizeof(prop_msg)) { 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = 0; 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = -1; 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(s); 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return r; 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint property_set(const char *key, const char *value) 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project prop_msg msg; 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned resp; 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(key == 0) return -1; 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(value == 0) value = ""; 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(strlen(key) >= PROP_NAME_MAX) return -1; 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(strlen(value) >= PROP_VALUE_MAX) return -1; 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.cmd = PROP_MSG_SETPROP; 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strcpy((char*) msg.name, key); 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strcpy((char*) msg.value, value); 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return send_prop_msg(&msg); 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint property_get(const char *key, char *value, const char *default_value) 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len; 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = __system_property_get(key, value); 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(len > 0) { 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return len; 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(default_value) { 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = strlen(default_value); 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memcpy(value, default_value, len + 1); 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return len; 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint property_list(void (*propfn)(const char *key, const char *value, void *cookie), 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project void *cookie) 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char name[PROP_NAME_MAX]; 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char value[PROP_VALUE_MAX]; 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const prop_info *pi; 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned n; 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(n = 0; (pi = __system_property_find_nth(n)); n++) { 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project __system_property_read(pi, name, value); 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project propfn(name, value, cookie); 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#elif defined(HAVE_SYSTEM_PROPERTY_SERVER) 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * The Linux simulator provides a "system property server" that uses IPC 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * to set/get/list properties. The file descriptor is shared by all 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * threads in the process, so we use a mutex to ensure that requests 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * from multiple threads don't get interleaved. 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h> 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/types.h> 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/socket.h> 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/un.h> 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <pthread.h> 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic pthread_once_t gInitOnce = PTHREAD_ONCE_INIT; 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic pthread_mutex_t gPropertyFdLock = PTHREAD_MUTEX_INITIALIZER; 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int gPropFd = -1; 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Connect to the properties server. 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Returns the socket descriptor on success. 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int connectToServer(const char* fileName) 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int sock = -1; 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int cc; 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct sockaddr_un addr; 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sock = socket(AF_UNIX, SOCK_STREAM, 0); 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (sock < 0) { 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project LOGW("UNIX domain socket create failed (errno=%d)\n", errno); 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* connect to socket; fails if file doesn't exist */ 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strcpy(addr.sun_path, fileName); // max 108 bytes 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project addr.sun_family = AF_UNIX; 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cc = connect(sock, (struct sockaddr*) &addr, SUN_LEN(&addr)); 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (cc < 0) { 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // ENOENT means socket file doesn't exist 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // ECONNREFUSED means socket exists but nobody is listening 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project //LOGW("AF_UNIX connect failed for '%s': %s\n", 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // fileName, strerror(errno)); 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(sock); 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return sock; 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Perform one-time initialization. 162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void init(void) 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project assert(gPropFd == -1); 166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project gPropFd = connectToServer(SYSTEM_PROPERTY_PIPE_NAME); 168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (gPropFd < 0) { 169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project //LOGW("not connected to system property server\n"); 170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project //LOGV("Connected to system property server\n"); 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint property_get(const char *key, char *value, const char *default_value) 176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char sendBuf[1+PROPERTY_KEY_MAX]; 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char recvBuf[1+PROPERTY_VALUE_MAX]; 179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len = -1; 180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project //LOGV("PROPERTY GET [%s]\n", key); 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pthread_once(&gInitOnce, init); 184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (gPropFd < 0) { 185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* this mimics the behavior of the device implementation */ 186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (default_value != NULL) { 187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strcpy(value, default_value); 188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = strlen(value); 189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return len; 191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (strlen(key) >= PROPERTY_KEY_MAX) return -1; 194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memset(sendBuf, 0xdd, sizeof(sendBuf)); // placate valgrind 196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sendBuf[0] = (char) kSystemPropertyGet; 198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strcpy(sendBuf+1, key); 199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pthread_mutex_lock(&gPropertyFdLock); 201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (write(gPropFd, sendBuf, sizeof(sendBuf)) != sizeof(sendBuf)) { 202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pthread_mutex_unlock(&gPropertyFdLock); 203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (read(gPropFd, recvBuf, sizeof(recvBuf)) != sizeof(recvBuf)) { 206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pthread_mutex_unlock(&gPropertyFdLock); 207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pthread_mutex_unlock(&gPropertyFdLock); 210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* first byte is 0 if value not defined, 1 if found */ 212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (recvBuf[0] == 0) { 213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (default_value != NULL) { 214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strcpy(value, default_value); 215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = strlen(value); 216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* 218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * If the value isn't defined, hand back an empty string and 219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * a zero length, rather than a failure. This seems wrong, 220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * since you can't tell the difference between "undefined" and 221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * "defined but empty", but it's what the device does. 222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project value[0] = '\0'; 224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = 0; 225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (recvBuf[0] == 1) { 227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strcpy(value, recvBuf+1); 228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = strlen(value); 229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project LOGE("Got strange response to property_get request (%d)\n", 231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project recvBuf[0]); 232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project assert(0); 233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project //LOGV("PROP [found=%d def='%s'] (%d) [%s]: [%s]\n", 236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // recvBuf[0], default_value, len, key, value); 237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return len; 239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint property_set(const char *key, const char *value) 243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char sendBuf[1+PROPERTY_KEY_MAX+PROPERTY_VALUE_MAX]; 245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char recvBuf[1]; 246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int result = -1; 247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project //LOGV("PROPERTY SET [%s]: [%s]\n", key, value); 249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pthread_once(&gInitOnce, init); 251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (gPropFd < 0) 252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (strlen(key) >= PROPERTY_KEY_MAX) return -1; 255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (strlen(value) >= PROPERTY_VALUE_MAX) return -1; 256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memset(sendBuf, 0xdd, sizeof(sendBuf)); // placate valgrind 258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sendBuf[0] = (char) kSystemPropertySet; 260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strcpy(sendBuf+1, key); 261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strcpy(sendBuf+1+PROPERTY_KEY_MAX, value); 262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pthread_mutex_lock(&gPropertyFdLock); 264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (write(gPropFd, sendBuf, sizeof(sendBuf)) != sizeof(sendBuf)) { 265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pthread_mutex_unlock(&gPropertyFdLock); 266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (read(gPropFd, recvBuf, sizeof(recvBuf)) != sizeof(recvBuf)) { 269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pthread_mutex_unlock(&gPropertyFdLock); 270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pthread_mutex_unlock(&gPropertyFdLock); 273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (recvBuf[0] != 1) 275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint property_list(void (*propfn)(const char *key, const char *value, void *cookie), 280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project void *cookie) 281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project //LOGV("PROPERTY LIST\n"); 283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pthread_once(&gInitOnce, init); 284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (gPropFd < 0) 285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* SUPER-cheesy place-holder implementation for Win32 */ 293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <cutils/threads.h> 295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic mutex_t env_lock = MUTEX_INITIALIZER; 297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint property_get(const char *key, char *value, const char *default_value) 299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char ename[PROPERTY_KEY_MAX + 6]; 301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *p; 302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len; 303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = strlen(key); 305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(len >= PROPERTY_KEY_MAX) return -1; 306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memcpy(ename, "PROP_", 5); 307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memcpy(ename + 5, key, len + 1); 308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mutex_lock(&env_lock); 310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p = getenv(ename); 312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(p == 0) p = ""; 313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = strlen(p); 314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(len >= PROPERTY_VALUE_MAX) { 315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = PROPERTY_VALUE_MAX - 1; 316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((len == 0) && default_value) { 319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = strlen(default_value); 320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memcpy(value, default_value, len + 1); 321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memcpy(value, p, len); 323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project value[len] = 0; 324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mutex_unlock(&env_lock); 327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return len; 329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint property_set(const char *key, const char *value) 333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char ename[PROPERTY_KEY_MAX + 6]; 335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *p; 336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len; 337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int r; 338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(strlen(value) >= PROPERTY_VALUE_MAX) return -1; 340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = strlen(key); 342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(len >= PROPERTY_KEY_MAX) return -1; 343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memcpy(ename, "PROP_", 5); 344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memcpy(ename + 5, key, len + 1); 345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mutex_lock(&env_lock); 347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef HAVE_MS_C_RUNTIME 348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char temp[256]; 350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project snprintf( temp, sizeof(temp), "%s=%s", ename, value); 351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project putenv(temp); 352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = 0; 353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = setenv(ename, value, 1); 356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mutex_unlock(&env_lock); 358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return r; 360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint property_list(void (*propfn)(const char *key, const char *value, void *cookie), 363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project void *cookie) 364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 369