1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in 12 * the documentation and/or other materials provided with the 13 * distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 #include <stdio.h> 29 #include <stdlib.h> 30 #include <unistd.h> 31 #include <stddef.h> 32 #include <errno.h> 33 34 #include <sys/mman.h> 35 36 #include <sys/socket.h> 37 #include <sys/un.h> 38 #include <sys/select.h> 39 #include <sys/types.h> 40 #include <netinet/in.h> 41 42 #define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_ 43 #include <sys/_system_properties.h> 44 45 #include <sys/atomics.h> 46 47 static const char property_service_name[] = PROP_SERVICE_NAME; 48 49 static unsigned dummy_props = 0; 50 51 prop_area *__system_property_area__ = (void*) &dummy_props; 52 53 int __system_properties_init(void) 54 { 55 prop_area *pa; 56 int s, fd; 57 unsigned sz; 58 char *env; 59 60 if(__system_property_area__ != ((void*) &dummy_props)) { 61 return 0; 62 } 63 64 env = getenv("ANDROID_PROPERTY_WORKSPACE"); 65 if (!env) { 66 return -1; 67 } 68 fd = atoi(env); 69 env = strchr(env, ','); 70 if (!env) { 71 return -1; 72 } 73 sz = atoi(env + 1); 74 75 pa = mmap(0, sz, PROT_READ, MAP_SHARED, fd, 0); 76 77 if(pa == MAP_FAILED) { 78 return -1; 79 } 80 81 if((pa->magic != PROP_AREA_MAGIC) || (pa->version != PROP_AREA_VERSION)) { 82 munmap(pa, sz); 83 return -1; 84 } 85 86 __system_property_area__ = pa; 87 return 0; 88 } 89 90 const prop_info *__system_property_find_nth(unsigned n) 91 { 92 prop_area *pa = __system_property_area__; 93 94 if(n >= pa->count) { 95 return 0; 96 } else { 97 return TOC_TO_INFO(pa, pa->toc[n]); 98 } 99 } 100 101 const prop_info *__system_property_find(const char *name) 102 { 103 prop_area *pa = __system_property_area__; 104 unsigned count = pa->count; 105 unsigned *toc = pa->toc; 106 unsigned len = strlen(name); 107 prop_info *pi; 108 109 while(count--) { 110 unsigned entry = *toc++; 111 if(TOC_NAME_LEN(entry) != len) continue; 112 113 pi = TOC_TO_INFO(pa, entry); 114 if(memcmp(name, pi->name, len)) continue; 115 116 return pi; 117 } 118 119 return 0; 120 } 121 122 int __system_property_read(const prop_info *pi, char *name, char *value) 123 { 124 unsigned serial, len; 125 126 for(;;) { 127 serial = pi->serial; 128 while(SERIAL_DIRTY(serial)) { 129 __futex_wait((volatile void *)&pi->serial, serial, 0); 130 serial = pi->serial; 131 } 132 len = SERIAL_VALUE_LEN(serial); 133 memcpy(value, pi->value, len + 1); 134 if(serial == pi->serial) { 135 if(name != 0) { 136 strcpy(name, pi->name); 137 } 138 return len; 139 } 140 } 141 } 142 143 int __system_property_get(const char *name, char *value) 144 { 145 const prop_info *pi = __system_property_find(name); 146 147 if(pi != 0) { 148 return __system_property_read(pi, 0, value); 149 } else { 150 value[0] = 0; 151 return 0; 152 } 153 } 154 155 int __system_property_wait(const prop_info *pi) 156 { 157 unsigned n; 158 if(pi == 0) { 159 prop_area *pa = __system_property_area__; 160 n = pa->serial; 161 do { 162 __futex_wait(&pa->serial, n, 0); 163 } while(n == pa->serial); 164 } else { 165 n = pi->serial; 166 do { 167 __futex_wait((volatile void *)&pi->serial, n, 0); 168 } while(n == pi->serial); 169 } 170 return 0; 171 } 172