diff --git a/libc/bionic/system_properties.cpp b/libc/bionic/system_properties.cpp index da71f09e8..5aefbafc4 100644 --- a/libc/bionic/system_properties.cpp +++ b/libc/bionic/system_properties.cpp @@ -59,10 +59,8 @@ #include "private/bionic_sdk_version.h" #include "private/libc_logging.h" -#define SERIAL_VALUE_LEN(serial) ((serial) >> 24) - static const char property_service_socket[] = "/dev/socket/" PROP_SERVICE_NAME; -static const char* kServiceVersionPropertyName = "ro.property_service.version"; + /* * Properties are stored in a hybrid trie/binary tree structure. @@ -83,7 +81,8 @@ static const char* kServiceVersionPropertyName = "ro.property_service.version"; // Represents a node in the trie. struct prop_bt { - uint32_t namelen; + uint8_t namelen; + uint8_t reserved[3]; // The property trie is updated only by the init process (single threaded) which provides // property service. And it can be read by multiple threads at the same time. @@ -108,7 +107,7 @@ struct prop_bt { char name[0]; - prop_bt(const char *name, const uint32_t name_length) { + prop_bt(const char *name, const uint8_t name_length) { this->namelen = name_length; memcpy(this->name, name, name_length); this->name[name_length] = '\0'; @@ -141,9 +140,9 @@ public: private: void *allocate_obj(const size_t size, uint_least32_t *const off); - prop_bt *new_prop_bt(const char *name, uint32_t namelen, uint_least32_t *const off); - prop_info *new_prop_info(const char *name, uint32_t namelen, - const char *value, uint32_t valuelen, + prop_bt *new_prop_bt(const char *name, uint8_t namelen, uint_least32_t *const off); + prop_info *new_prop_info(const char *name, uint8_t namelen, + const char *value, uint8_t valuelen, uint_least32_t *const off); void *to_prop_obj(uint_least32_t off); prop_bt *to_prop_bt(atomic_uint_least32_t *off_p); @@ -152,11 +151,11 @@ private: prop_bt *root_node(); prop_bt *find_prop_bt(prop_bt *const bt, const char *name, - uint32_t namelen, bool alloc_if_needed); + uint8_t namelen, bool alloc_if_needed); const prop_info *find_property(prop_bt *const trie, const char *name, - uint32_t namelen, const char *value, - uint32_t valuelen, bool alloc_if_needed); + uint8_t namelen, const char *value, + uint8_t valuelen, bool alloc_if_needed); bool foreach_property(prop_bt *const trie, void (*propfn)(const prop_info *pi, void *cookie), @@ -174,20 +173,19 @@ private: struct prop_info { atomic_uint_least32_t serial; - // we need to keep this buffer around because the property - // value can be modified whereas name is constant. char value[PROP_VALUE_MAX]; char name[0]; - prop_info(const char *name, uint32_t namelen, const char *value, uint32_t valuelen) { + prop_info(const char *name, const uint8_t namelen, const char *value, + const uint8_t valuelen) { memcpy(this->name, name, namelen); this->name[namelen] = '\0'; atomic_init(&this->serial, valuelen << 24); memcpy(this->value, value, valuelen); this->value[valuelen] = '\0'; } - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(prop_info); +private: + DISALLOW_COPY_AND_ASSIGN(prop_info); }; struct find_nth_cookie { @@ -360,7 +358,7 @@ void *prop_area::allocate_obj(const size_t size, uint_least32_t *const off) return data_ + *off; } -prop_bt *prop_area::new_prop_bt(const char *name, uint32_t namelen, uint_least32_t *const off) +prop_bt *prop_area::new_prop_bt(const char *name, uint8_t namelen, uint_least32_t *const off) { uint_least32_t new_offset; void *const p = allocate_obj(sizeof(prop_bt) + namelen + 1, &new_offset); @@ -373,8 +371,8 @@ prop_bt *prop_area::new_prop_bt(const char *name, uint32_t namelen, uint_least32 return NULL; } -prop_info *prop_area::new_prop_info(const char *name, uint32_t namelen, - const char *value, uint32_t valuelen, uint_least32_t *const off) +prop_info *prop_area::new_prop_info(const char *name, uint8_t namelen, + const char *value, uint8_t valuelen, uint_least32_t *const off) { uint_least32_t new_offset; void* const p = allocate_obj(sizeof(prop_info) + namelen + 1, &new_offset); @@ -410,8 +408,8 @@ inline prop_bt *prop_area::root_node() return reinterpret_cast(to_prop_obj(0)); } -static int cmp_prop_name(const char *one, uint32_t one_len, const char *two, - uint32_t two_len) +static int cmp_prop_name(const char *one, uint8_t one_len, const char *two, + uint8_t two_len) { if (one_len < two_len) return -1; @@ -422,7 +420,7 @@ static int cmp_prop_name(const char *one, uint32_t one_len, const char *two, } prop_bt *prop_area::find_prop_bt(prop_bt *const bt, const char *name, - uint32_t namelen, bool alloc_if_needed) + uint8_t namelen, bool alloc_if_needed) { prop_bt* current = bt; @@ -473,7 +471,7 @@ prop_bt *prop_area::find_prop_bt(prop_bt *const bt, const char *name, } const prop_info *prop_area::find_property(prop_bt *const trie, const char *name, - uint32_t namelen, const char *value, uint32_t valuelen, + uint8_t namelen, const char *value, uint8_t valuelen, bool alloc_if_needed) { if (!trie) return NULL; @@ -483,7 +481,7 @@ const prop_info *prop_area::find_property(prop_bt *const trie, const char *name, while (true) { const char *sep = strchr(remaining_name, '.'); const bool want_subtree = (sep != NULL); - const uint32_t substr_size = (want_subtree) ? + const uint8_t substr_size = (want_subtree) ? sep - remaining_name : strlen(remaining_name); if (!substr_size) { @@ -533,93 +531,28 @@ const prop_info *prop_area::find_property(prop_bt *const trie, const char *name, } } -class PropertyServiceConnection { - public: - PropertyServiceConnection() : last_error_(0) { - fd_ = socket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0); - if (fd_ == -1) { - last_error_ = errno; - return; +static int send_prop_msg(const prop_msg *msg) +{ + const int fd = socket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0); + if (fd == -1) { + return -1; } const size_t namelen = strlen(property_service_socket); + sockaddr_un addr; memset(&addr, 0, sizeof(addr)); strlcpy(addr.sun_path, property_service_socket, sizeof(addr.sun_path)); addr.sun_family = AF_LOCAL; socklen_t alen = namelen + offsetof(sockaddr_un, sun_path) + 1; - - if (TEMP_FAILURE_RETRY(connect(fd_, reinterpret_cast(&addr), alen)) == -1) { - close(fd_); - fd_ = -1; - last_error_ = errno; + if (TEMP_FAILURE_RETRY(connect(fd, reinterpret_cast(&addr), alen)) < 0) { + close(fd); + return -1; } - } - - bool IsValid() { - return fd_ != -1; - } - - int GetLastError() { - return last_error_; - } - - bool SendUint32(uint32_t value) { - int result = TEMP_FAILURE_RETRY(send(fd_, &value, sizeof(value), 0)); - return CheckSendRecvResult(result, sizeof(value)); - } - - bool SendString(const char* value) { - uint32_t valuelen = strlen(value); - if (!SendUint32(valuelen)) { - return false; - } - - int result = TEMP_FAILURE_RETRY(send(fd_, value, valuelen, 0)); - return CheckSendRecvResult(result, valuelen); - } - - bool RecvInt32(int32_t* value) { - int result = TEMP_FAILURE_RETRY(recv(fd_, value, sizeof(*value), MSG_WAITALL)); - return CheckSendRecvResult(result, sizeof(*value)); - } - - int GetFd() { - return fd_; - } - - ~PropertyServiceConnection() { - if (fd_ != -1) { - close(fd_); - } - } - private: - bool CheckSendRecvResult(int result, int expected_len) { - if (result == -1) { - last_error_ = errno; - } else if (result != expected_len) { - last_error_ = -1; - } else { - last_error_ = 0; - } - - return last_error_ == 0; - } - - int fd_; - int last_error_; -}; - -static int send_prop_msg(const prop_msg* msg) { - PropertyServiceConnection connection; - if (!connection.IsValid()) { - return connection.GetLastError(); - } - - int result = -1; - int fd = connection.GetFd(); const int num_bytes = TEMP_FAILURE_RETRY(send(fd, msg, sizeof(prop_msg), 0)); + + int result = -1; if (num_bytes == sizeof(prop_msg)) { // We successfully wrote to the property server but now we // wait for the property server to finish its work. It @@ -645,13 +578,11 @@ static int send_prop_msg(const prop_msg* msg) { // ms so callers who do read-after-write can reliably see // what they've written. Most of the time. // TODO: fix the system properties design. - __libc_format_log(ANDROID_LOG_WARN, "libc", - "Property service has timed out while trying to set \"%s\" to \"%s\"", - msg->name, msg->value); result = 0; } } + close(fd); return result; } @@ -1193,136 +1124,51 @@ int __system_property_read(const prop_info *pi, char *name, char *value) atomic_thread_fence(memory_order_acquire); if (serial == load_const_atomic(&(pi->serial), memory_order_relaxed)) { - if (name != nullptr) { - size_t namelen = strlcpy(name, pi->name, PROP_NAME_MAX); - if(namelen >= PROP_NAME_MAX) { - __libc_format_log(ANDROID_LOG_ERROR, "libc", - "The property name length for \"%s\" is >= %d;" - " please use __system_property_read_callback" - " to read this property. (the name is truncated to \"%s\")", - pi->name, PROP_NAME_MAX - 1, name); - } + if (name != 0) { + strcpy(name, pi->name); } return len; } } } -void __system_property_read_callback(const prop_info* pi, - void (*callback)(void* cookie, const char* name, const char* value), - void* cookie) { - // TODO (dimitry): do we need compat mode for this function? - if (__predict_false(compat_mode)) { - char value_buf[PROP_VALUE_MAX]; - __system_property_read_compat(pi, nullptr, value_buf); - callback(cookie, pi->name, value_buf); - return; - } - - while (true) { - uint32_t serial = __system_property_serial(pi); // acquire semantics - size_t len = SERIAL_VALUE_LEN(serial); - char value_buf[len+1]; - - memcpy(value_buf, pi->value, len); - value_buf[len] = '\0'; - - // TODO: see todo in __system_property_read function - atomic_thread_fence(memory_order_acquire); - if (serial == load_const_atomic(&(pi->serial), memory_order_relaxed)) { - callback(cookie, pi->name, value_buf); - return; - } - } -} - int __system_property_get(const char *name, char *value) { const prop_info *pi = __system_property_find(name); if (pi != 0) { - return __system_property_read(pi, nullptr, value); + return __system_property_read(pi, 0, value); } else { value[0] = 0; return 0; } } -static constexpr uint32_t kProtocolVersion1 = 1; -static constexpr uint32_t kProtocolVersion2 = 2; // current - -static atomic_uint_least32_t g_propservice_protocol_version = 0; - -static void detect_protocol_version() { - char value[PROP_VALUE_MAX]; - if (__system_property_get(kServiceVersionPropertyName, value) == 0) { - g_propservice_protocol_version = kProtocolVersion1; - __libc_format_log(ANDROID_LOG_WARN, "libc", - "Using old property service protocol (\"%s\" is not set)", - kServiceVersionPropertyName); - } else { - uint32_t version = static_cast(atoll(value)); - if (version >= kProtocolVersion2) { - g_propservice_protocol_version = kProtocolVersion2; - } else { - __libc_format_log(ANDROID_LOG_WARN, "libc", - "Using old property service protocol (\"%s\"=\"%s\")", - kServiceVersionPropertyName, value); - g_propservice_protocol_version = kProtocolVersion1; - } - } -} - -int __system_property_set(const char* key, const char* value) { - if (key == nullptr) return -1; - if (value == nullptr) value = ""; +int __system_property_set(const char *key, const char *value) +{ + if (key == 0) return -1; + if (value == 0) value = ""; + if (strlen(key) >= PROP_NAME_MAX) return -1; if (strlen(value) >= PROP_VALUE_MAX) return -1; - if (g_propservice_protocol_version == 0) { - detect_protocol_version(); + prop_msg msg; + memset(&msg, 0, sizeof msg); + msg.cmd = PROP_MSG_SETPROP; + strlcpy(msg.name, key, sizeof msg.name); + strlcpy(msg.value, value, sizeof msg.value); + + const int err = send_prop_msg(&msg); + if (err < 0) { + return err; } - int result = -1; - if (g_propservice_protocol_version == kProtocolVersion1) { - // Old protocol does not support long names - if (strlen(key) >= PROP_NAME_MAX) return -1; - - prop_msg msg; - memset(&msg, 0, sizeof msg); - msg.cmd = PROP_MSG_SETPROP; - strlcpy(msg.name, key, sizeof msg.name); - strlcpy(msg.value, value, sizeof msg.value); - - result = send_prop_msg(&msg); - } else { - // Use proper protocol - PropertyServiceConnection connection; - if (connection.IsValid() && - connection.SendUint32(PROP_MSG_SETPROP2) && - connection.SendString(key) && - connection.SendString(value) && - connection.RecvInt32(&result)) { - if (result != PROP_SUCCESS) { - __libc_format_log(ANDROID_LOG_WARN, "libc", - "Unable to set property \"%s\" to \"%s\": error code: 0x%x", - key, value, result); - } - } else { - result = connection.GetLastError(); - __libc_format_log(ANDROID_LOG_WARN, "libc", - "Unable to set property \"%s\" to \"%s\": error code: 0x%x (%s)", - key, value, result, strerror(result)); - } - } - - return result != 0 ? -1 : 0; + return 0; } int __system_property_update(prop_info *pi, const char *value, unsigned int len) { - if (len >= PROP_VALUE_MAX) { + if (len >= PROP_VALUE_MAX) return -1; - } prop_area* pa = __system_property_area__; @@ -1337,8 +1183,7 @@ int __system_property_update(prop_info *pi, const char *value, unsigned int len) // used memory_order_relaxed atomics, and use the analogous // counterintuitive fence. atomic_thread_fence(memory_order_release); - strlcpy(pi->value, value, len + 1); - + memcpy(pi->value, value, len + 1); atomic_store_explicit( &pi->serial, (len << 24) | ((serial + 1) & 0xffffff), @@ -1357,13 +1202,12 @@ int __system_property_update(prop_info *pi, const char *value, unsigned int len) int __system_property_add(const char *name, unsigned int namelen, const char *value, unsigned int valuelen) { - if (valuelen >= PROP_VALUE_MAX) { + if (namelen >= PROP_NAME_MAX) return -1; - } - - if (namelen < 1) { + if (valuelen >= PROP_VALUE_MAX) + return -1; + if (namelen < 1) return -1; - } if (!__system_property_area__) { return -1; @@ -1377,9 +1221,8 @@ int __system_property_add(const char *name, unsigned int namelen, } bool ret = pa->add(name, namelen, value, valuelen); - if (!ret) { + if (!ret) return -1; - } // There is only a single mutator, but we want to make sure that // updates are visible to a reader waiting for the update. diff --git a/libc/bionic/system_properties_compat.c b/libc/bionic/system_properties_compat.c index ba73a2c28..6aeaa0c37 100644 --- a/libc/bionic/system_properties_compat.c +++ b/libc/bionic/system_properties_compat.c @@ -43,7 +43,6 @@ #define TOC_NAME_LEN(toc) ((toc) >> 24) #define TOC_TO_INFO(area, toc) ((prop_info_compat*) (((char*) area) + ((toc) & 0xFFFFFF))) -#define SERIAL_VALUE_LEN(serial) ((serial) >> 24) struct prop_area_compat { unsigned volatile count; diff --git a/libc/include/sys/_system_properties.h b/libc/include/sys/_system_properties.h index 080280e2e..89a1608ee 100644 --- a/libc/include/sys/_system_properties.h +++ b/libc/include/sys/_system_properties.h @@ -48,6 +48,7 @@ typedef struct prop_msg prop_msg; #define PA_SIZE (128 * 1024) +#define SERIAL_VALUE_LEN(serial) ((serial) >> 24) #define SERIAL_DIRTY(serial) ((serial) & 1) __BEGIN_DECLS @@ -60,18 +61,6 @@ struct prop_msg }; #define PROP_MSG_SETPROP 1 -#define PROP_MSG_SETPROP2 0x00020001 - -#define PROP_SUCCESS 0 -#define PROP_ERROR_READ_CMD 0x0004 -#define PROP_ERROR_READ_DATA 0x0008 -#define PROP_ERROR_READ_ONLY_PROPERTY 0x000B -#define PROP_ERROR_INVALID_NAME 0x0010 -#define PROP_ERROR_INVALID_VALUE 0x0014 -#define PROP_ERROR_PERMISSION_DENIED 0x0018 -#define PROP_ERROR_INVALID_CMD 0x001B -#define PROP_ERROR_HANDLE_CONTROL_MESSAGE 0x0020 -#define PROP_ERROR_SET_FAILED 0x0024 /* ** Rules: diff --git a/libc/include/sys/system_properties.h b/libc/include/sys/system_properties.h index d80b2fee8..faed9a0bb 100644 --- a/libc/include/sys/system_properties.h +++ b/libc/include/sys/system_properties.h @@ -30,7 +30,6 @@ #define _INCLUDE_SYS_SYSTEM_PROPERTIES_H #include -#include __BEGIN_DECLS @@ -65,17 +64,13 @@ const prop_info *__system_property_find(const char *name); /* Read the value of a system property. Returns the length ** of the value. Copies the value and \0 terminator into ** the provided value pointer. Total length (including -** terminator) will be no greater that PROP_VALUE_MAX for -** __system_property_read. +** terminator) will be no greater that PROP_VALUE_MAX. ** ** If name is nonzero, up to PROP_NAME_MAX bytes will be ** copied into the provided name pointer. The name will ** be \0 terminated. */ int __system_property_read(const prop_info *pi, char *name, char *value); -void __system_property_read_callback(const prop_info *pi, - void (*)(void* cookie, const char *name, const char *value), - void* cookie) __INTRODUCED_IN_FUTURE; /* Return a prop_info for the nth system property, or NULL if ** there is no nth property. Use __system_property_read() to diff --git a/libc/libc.arm.map b/libc/libc.arm.map index 43194295e..3ff7ead5c 100644 --- a/libc/libc.arm.map +++ b/libc/libc.arm.map @@ -1265,7 +1265,6 @@ LIBC_N { # introduced-arm64=24 introduced-mips=24 introduced-mips64=24 introduce LIBC_O { global: - __system_property_read_callback; # future bsd_signal; # arm x86 mips versioned=26 catclose; # future catgets; # future diff --git a/libc/libc.arm64.map b/libc/libc.arm64.map index f88c28425..a696c41f7 100644 --- a/libc/libc.arm64.map +++ b/libc/libc.arm64.map @@ -1188,7 +1188,6 @@ LIBC_N { # introduced-arm64=24 introduced-mips=24 introduced-mips64=24 introduce LIBC_O { global: - __system_property_read_callback; # future catclose; # future catgets; # future catopen; # future diff --git a/libc/libc.map.txt b/libc/libc.map.txt index 46087e606..391c65cf2 100644 --- a/libc/libc.map.txt +++ b/libc/libc.map.txt @@ -1290,7 +1290,6 @@ LIBC_N { # introduced-arm64=24 introduced-mips=24 introduced-mips64=24 introduce LIBC_O { global: - __system_property_read_callback; # future bsd_signal; # arm x86 mips versioned=26 catclose; # future catgets; # future diff --git a/libc/libc.mips.map b/libc/libc.mips.map index 075746c56..c89b4ad55 100644 --- a/libc/libc.mips.map +++ b/libc/libc.mips.map @@ -1249,7 +1249,6 @@ LIBC_N { # introduced-arm64=24 introduced-mips=24 introduced-mips64=24 introduce LIBC_O { global: - __system_property_read_callback; # future bsd_signal; # arm x86 mips versioned=26 catclose; # future catgets; # future diff --git a/libc/libc.mips64.map b/libc/libc.mips64.map index f88c28425..a696c41f7 100644 --- a/libc/libc.mips64.map +++ b/libc/libc.mips64.map @@ -1188,7 +1188,6 @@ LIBC_N { # introduced-arm64=24 introduced-mips=24 introduced-mips64=24 introduce LIBC_O { global: - __system_property_read_callback; # future catclose; # future catgets; # future catopen; # future diff --git a/libc/libc.x86.map b/libc/libc.x86.map index 75c77578b..51b222d5a 100644 --- a/libc/libc.x86.map +++ b/libc/libc.x86.map @@ -1247,7 +1247,6 @@ LIBC_N { # introduced-arm64=24 introduced-mips=24 introduced-mips64=24 introduce LIBC_O { global: - __system_property_read_callback; # future bsd_signal; # arm x86 mips versioned=26 catclose; # future catgets; # future diff --git a/libc/libc.x86_64.map b/libc/libc.x86_64.map index f88c28425..a696c41f7 100644 --- a/libc/libc.x86_64.map +++ b/libc/libc.x86_64.map @@ -1188,7 +1188,6 @@ LIBC_N { # introduced-arm64=24 introduced-mips=24 introduced-mips64=24 introduce LIBC_O { global: - __system_property_read_callback; # future catclose; # future catgets; # future catopen; # future diff --git a/tests/Android.bp b/tests/Android.bp index 64a5c30a6..85ae26e66 100644 --- a/tests/Android.bp +++ b/tests/Android.bp @@ -132,7 +132,6 @@ cc_test_library { "sys_vfs_test.cpp", "sys_xattr_test.cpp", "system_properties_test.cpp", - "system_properties_test2.cpp", "time_test.cpp", "uchar_test.cpp", "unistd_nofortify_test.cpp", diff --git a/tests/system_properties_test.cpp b/tests/system_properties_test.cpp index 6b037d8af..70482f031 100644 --- a/tests/system_properties_test.cpp +++ b/tests/system_properties_test.cpp @@ -69,7 +69,7 @@ private: static void foreach_test_callback(const prop_info *pi, void* cookie) { size_t *count = static_cast(cookie); - ASSERT_TRUE(pi != nullptr); + ASSERT_NE((prop_info *)NULL, pi); (*count)++; } @@ -98,15 +98,16 @@ static void hierarchical_test_callback(const prop_info *pi, void *cookie) { ok[name_i][name_j][name_k] = true; } -static void* PropertyWaitHelperFn(void* arg) { - int* flag = static_cast(arg); - prop_info* pi = const_cast(__system_property_find("property")); +static void *PropertyWaitHelperFn(void *arg) { + int *flag = (int *)arg; + prop_info *pi; + pi = (prop_info *)__system_property_find("property"); usleep(100000); *flag = 1; __system_property_update(pi, "value3", 6); - return nullptr; + return NULL; } #endif // __BIONIC__ @@ -122,16 +123,6 @@ TEST(properties, add) { ASSERT_EQ(0, __system_property_add("other_property", 14, "value2", 6)); ASSERT_EQ(0, __system_property_add("property_other", 14, "value3", 6)); - // check that there is no limit on property name length - char name[PROP_NAME_MAX + 11]; - name[0] = 'p'; - for (size_t i = 1; i < sizeof(name); i++) { - name[i] = 'x'; - } - - name[sizeof(name)-1] = '\0'; - ASSERT_EQ(0, __system_property_add(name, strlen(name), "value", 5)); - ASSERT_EQ(6, __system_property_get("property", propvalue)); ASSERT_STREQ(propvalue, "value1"); @@ -140,9 +131,6 @@ TEST(properties, add) { ASSERT_EQ(6, __system_property_get("property_other", propvalue)); ASSERT_STREQ(propvalue, "value3"); - - ASSERT_EQ(5, __system_property_get(name, propvalue)); - ASSERT_STREQ(propvalue, "value"); #else // __BIONIC__ GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif // __BIONIC__ @@ -335,6 +323,7 @@ TEST(properties, errors) { ASSERT_EQ(0, __system_property_find("property1")); ASSERT_EQ(0, __system_property_get("property1", prop_value)); + ASSERT_EQ(-1, __system_property_add("name", PROP_NAME_MAX, "value", 5)); ASSERT_EQ(-1, __system_property_add("name", 4, "value", PROP_VALUE_MAX)); ASSERT_EQ(-1, __system_property_update(NULL, "value", PROP_VALUE_MAX)); #else // __BIONIC__ @@ -370,13 +359,12 @@ TEST(properties, wait) { ASSERT_EQ(0, __system_property_add("property", 8, "value1", 6)); serial = __system_property_wait_any(0); - - pi = const_cast(__system_property_find("property")); - ASSERT_TRUE(pi != nullptr); + pi = (prop_info *)__system_property_find("property"); + ASSERT_NE((prop_info *)NULL, pi); __system_property_update(pi, "value2", 6); serial = __system_property_wait_any(serial); - ASSERT_EQ(0, pthread_create(&t, nullptr, PropertyWaitHelperFn, &flag)); + ASSERT_EQ(0, pthread_create(&t, NULL, PropertyWaitHelperFn, &flag)); ASSERT_EQ(flag, 0); serial = __system_property_wait_any(serial); ASSERT_EQ(flag, 1); @@ -408,7 +396,9 @@ TEST_F(properties_DeathTest, read_only) { // This test only makes sense if we're talking to the real system property service. struct stat sb; - ASSERT_FALSE(stat(PROP_FILENAME, &sb) == -1 && errno == ENOENT); + if (stat(PROP_FILENAME, &sb) == -1 && errno == ENOENT) { + return; + } ASSERT_EXIT(__system_property_add("property", 8, "value", 5), KilledByFault(), ""); #else // __BIONIC__ diff --git a/tests/system_properties_test2.cpp b/tests/system_properties_test2.cpp deleted file mode 100644 index 858bc17ee..000000000 --- a/tests/system_properties_test2.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -#include -#include -#include -#include -#include - -#if defined(__BIONIC__) -#include - -static uint64_t NanoTime() { - timespec now; - clock_gettime(CLOCK_MONOTONIC, &now); - return static_cast(now.tv_sec) * UINT64_C(1000000000) + now.tv_nsec; -} -#endif - -// Note that this test affects global state of the system -// this tests tries to mitigate this by using utime+pid -// prefix for the property name. It is still results in -// pollution of property service since properties cannot -// be removed. -// -// Note that there is also possibility to run into "out-of-memory" -// if this test if it is executed often enough without reboot. -TEST(properties, smoke) { -#if defined(__BIONIC__) - char propvalue[PROP_VALUE_MAX]; - - std::stringstream ss; - ss << "debug.test." << getpid() << "." << NanoTime() << "."; - const std::string property_prefix = ss.str(); - const std::string property_name = property_prefix + "property1"; - - // Set brand new property - ASSERT_EQ(0, __system_property_set(property_name.c_str(), "value1")); - ASSERT_EQ(6, __system_property_get(property_name.c_str(), propvalue)); - ASSERT_STREQ("value1", propvalue); - - std::string long_value = "property-"; - for (size_t i = 0; i < PROP_VALUE_MAX; i++) { - long_value += "y"; - } - - // Make sure that attempts to set invalid property value fails and preserves - // previous value. - propvalue[0] = '\0'; - ASSERT_EQ(-1, __system_property_set(property_name.c_str(), long_value.c_str())); - ASSERT_EQ(6, __system_property_get(property_name.c_str(), propvalue)); - ASSERT_STREQ("value1", propvalue); - - // Update property - ASSERT_EQ(0, __system_property_set(property_name.c_str(), "value1-1")); - ASSERT_EQ(8, __system_property_get(property_name.c_str(), propvalue)); - ASSERT_STREQ("value1-1", propvalue); - - - // check that there is no limit on property name length - char suffix[1024]; - for (size_t i = 0; i < sizeof(suffix); i++) { - suffix[i] = 'x'; - } - - suffix[sizeof(suffix)-1] = '\0'; - const std::string long_property_name = property_prefix + suffix; - - ASSERT_EQ(0, __system_property_set(long_property_name.c_str(), "value2")); - ASSERT_EQ(6, __system_property_get(long_property_name.c_str(), propvalue)); - ASSERT_STREQ("value2", propvalue); - - // test find and read_callback - const prop_info* pi = __system_property_find(property_name.c_str()); - ASSERT_TRUE(pi != nullptr); - - std::string expected_name = property_name; - __system_property_read_callback(pi, [](void* cookie, const char *name, const char *value) { - const std::string* expected_name = static_cast(cookie); - ASSERT_EQ(*expected_name, name); - ASSERT_STREQ("value1-1", value); - }, &expected_name); - - pi = __system_property_find(long_property_name.c_str()); - ASSERT_TRUE(pi != nullptr); - - expected_name = long_property_name; - __system_property_read_callback(pi, [](void* cookie, const char *name, const char *value) { - const std::string* expected_name = static_cast(cookie); - ASSERT_EQ(*expected_name, name); - ASSERT_STREQ("value2", value); - }, &expected_name); - - // Check that read() for long names still works but returns truncated version of the name - pi = __system_property_find(property_name.c_str()); - ASSERT_TRUE(pi != nullptr); - char legacy_name[PROP_NAME_MAX]; - expected_name = std::string(property_name.c_str(), PROP_NAME_MAX-1); - ASSERT_EQ(8, __system_property_read(pi, &legacy_name[0], propvalue)); - ASSERT_EQ(expected_name, legacy_name); - ASSERT_STREQ("value1-1", propvalue); - - const prop_info* pi_long = __system_property_find(long_property_name.c_str()); - ASSERT_TRUE(pi != nullptr); - expected_name = std::string(long_property_name.c_str(), PROP_NAME_MAX-1); - ASSERT_EQ(6, __system_property_read(pi_long, &legacy_name[0], propvalue)); - ASSERT_EQ(expected_name, legacy_name); - ASSERT_STREQ("value2", propvalue); -#else // __BIONIC__ - GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif // __BIONIC__ -} -