blob: 25ff1a3ad1a55420bf215ad7d0941cef15de188b [file] [log] [blame]
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001/*
2 * Copyright (C) 2006 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 "properties"
Igor Murashkind8f2a8d2014-04-08 11:22:42 -070018// #define LOG_NDEBUG 0
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080019
Mark Salyzyn23ed4c22016-09-28 13:33:27 -070020#include <assert.h>
21#include <ctype.h>
22#include <errno.h>
23#include <inttypes.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080024#include <stdlib.h>
25#include <string.h>
26#include <unistd.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080027
28#include <cutils/properties.h>
Mark Salyzyn23ed4c22016-09-28 13:33:27 -070029#include <cutils/sockets.h>
Mark Salyzyn30f991f2017-01-10 13:19:54 -080030#include <log/log.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080031
Igor Murashkind8f2a8d2014-04-08 11:22:42 -070032int8_t property_get_bool(const char *key, int8_t default_value) {
33 if (!key) {
34 return default_value;
35 }
36
37 int8_t result = default_value;
Myles Watson22c09622016-12-20 06:47:36 -080038 char buf[PROPERTY_VALUE_MAX] = {'\0'};
Igor Murashkind8f2a8d2014-04-08 11:22:42 -070039
40 int len = property_get(key, buf, "");
41 if (len == 1) {
42 char ch = buf[0];
43 if (ch == '0' || ch == 'n') {
44 result = false;
45 } else if (ch == '1' || ch == 'y') {
46 result = true;
47 }
48 } else if (len > 1) {
Myles Watson22c09622016-12-20 06:47:36 -080049 if (!strcmp(buf, "no") || !strcmp(buf, "false") || !strcmp(buf, "off")) {
Igor Murashkind8f2a8d2014-04-08 11:22:42 -070050 result = false;
51 } else if (!strcmp(buf, "yes") || !strcmp(buf, "true") || !strcmp(buf, "on")) {
52 result = true;
53 }
54 }
55
56 return result;
57}
58
59// Convert string property to int (default if fails); return default value if out of bounds
60static intmax_t property_get_imax(const char *key, intmax_t lower_bound, intmax_t upper_bound,
Myles Watson22c09622016-12-20 06:47:36 -080061 intmax_t default_value) {
Igor Murashkind8f2a8d2014-04-08 11:22:42 -070062 if (!key) {
63 return default_value;
64 }
65
66 intmax_t result = default_value;
Myles Watson22c09622016-12-20 06:47:36 -080067 char buf[PROPERTY_VALUE_MAX] = {'\0'};
Igor Murashkind8f2a8d2014-04-08 11:22:42 -070068 char *end = NULL;
69
70 int len = property_get(key, buf, "");
71 if (len > 0) {
72 int tmp = errno;
73 errno = 0;
74
75 // Infer base automatically
Myles Watson22c09622016-12-20 06:47:36 -080076 result = strtoimax(buf, &end, /*base*/ 0);
Igor Murashkind8f2a8d2014-04-08 11:22:42 -070077 if ((result == INTMAX_MIN || result == INTMAX_MAX) && errno == ERANGE) {
78 // Over or underflow
79 result = default_value;
Igor Murashkin1f7f70a2014-04-15 18:06:39 -070080 ALOGV("%s(%s,%" PRIdMAX ") - overflow", __FUNCTION__, key, default_value);
Igor Murashkind8f2a8d2014-04-08 11:22:42 -070081 } else if (result < lower_bound || result > upper_bound) {
82 // Out of range of requested bounds
83 result = default_value;
Igor Murashkin1f7f70a2014-04-15 18:06:39 -070084 ALOGV("%s(%s,%" PRIdMAX ") - out of range", __FUNCTION__, key, default_value);
Igor Murashkind8f2a8d2014-04-08 11:22:42 -070085 } else if (end == buf) {
86 // Numeric conversion failed
87 result = default_value;
Myles Watson22c09622016-12-20 06:47:36 -080088 ALOGV("%s(%s,%" PRIdMAX ") - numeric conversion failed", __FUNCTION__, key,
89 default_value);
Igor Murashkind8f2a8d2014-04-08 11:22:42 -070090 }
91
92 errno = tmp;
93 }
94
95 return result;
96}
97
98int64_t property_get_int64(const char *key, int64_t default_value) {
99 return (int64_t)property_get_imax(key, INT64_MIN, INT64_MAX, default_value);
100}
101
102int32_t property_get_int32(const char *key, int32_t default_value) {
103 return (int32_t)property_get_imax(key, INT32_MIN, INT32_MAX, default_value);
104}
105
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800106#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
107#include <sys/_system_properties.h>
108
Myles Watson22c09622016-12-20 06:47:36 -0800109int property_set(const char *key, const char *value) {
Brad Fitzpatrickeb1f0c62011-03-07 13:52:21 -0800110 return __system_property_set(key, value);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800111}
112
Myles Watson22c09622016-12-20 06:47:36 -0800113int property_get(const char *key, char *value, const char *default_value) {
Elliott Hughes4eacd702017-01-26 17:31:40 -0800114 int len = __system_property_get(key, value);
Myles Watson22c09622016-12-20 06:47:36 -0800115 if (len > 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800116 return len;
117 }
Myles Watson22c09622016-12-20 06:47:36 -0800118 if (default_value) {
Myles Watsone67abec2016-12-22 09:05:18 -0800119 len = strnlen(default_value, PROPERTY_VALUE_MAX - 1);
Igor Murashkind8f2a8d2014-04-08 11:22:42 -0700120 memcpy(value, default_value, len);
121 value[len] = '\0';
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800122 }
123 return len;
124}
125
Elliott Hughes4eacd702017-01-26 17:31:40 -0800126struct callback_data {
127 void (*callback)(const char* name, const char* value, void* cookie);
128 void* cookie;
Greg Hackmann69679352013-02-12 14:41:59 -0800129};
130
Elliott Hughesb30769a2017-02-10 19:02:51 -0800131static void trampoline(void* raw_data, const char* name, const char* value, unsigned /*serial*/) {
Elliott Hughes4eacd702017-01-26 17:31:40 -0800132 callback_data* data = reinterpret_cast<callback_data*>(raw_data);
133 data->callback(name, value, data->cookie);
Greg Hackmann69679352013-02-12 14:41:59 -0800134}
135
Elliott Hughes4eacd702017-01-26 17:31:40 -0800136static void property_list_callback(const prop_info* pi, void* data) {
137 __system_property_read_callback(pi, trampoline, data);
138}
139
140int property_list(void (*fn)(const char* name, const char* value, void* cookie), void* cookie) {
141 callback_data data = { fn, cookie };
Greg Hackmann69679352013-02-12 14:41:59 -0800142 return __system_property_foreach(property_list_callback, &data);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800143}