Loading libcutils/Android.mk +10 −0 Original line number Diff line number Diff line Loading @@ -91,6 +91,16 @@ LOCAL_STATIC_LIBRARIES := lib64log LOCAL_CFLAGS += $(hostSmpFlag) -m64 include $(BUILD_HOST_STATIC_LIBRARY) # Tests for host # ======================================================== include $(CLEAR_VARS) LOCAL_MODULE := tst_str_parms LOCAL_CFLAGS += -DTEST_STR_PARMS LOCAL_SRC_FILES := str_parms.c hashmap.c memory.c LOCAL_STATIC_LIBRARIES := liblog LOCAL_MODULE_TAGS := optional include $(BUILD_HOST_EXECUTABLE) # Shared and static library for target # ======================================================== Loading libcutils/str_parms.c +44 −13 Original line number Diff line number Diff line Loading @@ -194,23 +194,46 @@ err_create_str_parms: int str_parms_add_str(struct str_parms *str_parms, const char *key, const char *value) { void *old_val; void *tmp_key; void *tmp_val; void *tmp_key = NULL; void *tmp_val = NULL; void *old_val = NULL; // strdup and hashmapPut both set errno on failure. // Set errno to 0 so we can recognize whether anything went wrong. int saved_errno = errno; errno = 0; tmp_key = strdup(key); if (tmp_key == NULL) { goto clean_up; } tmp_val = strdup(value); if (tmp_val == NULL) { goto clean_up; } old_val = hashmapPut(str_parms->map, tmp_key, tmp_val); if (old_val == NULL) { // Did hashmapPut fail? if (errno == ENOMEM) { goto clean_up; } // For new keys, hashmap takes ownership of tmp_key and tmp_val. tmp_key = tmp_val = NULL; } else { // For existing keys, hashmap takes ownership of tmp_val. // (It also gives up ownership of old_val.) tmp_val = NULL; } if (old_val) { free(old_val); free(tmp_key); } else if (errno == ENOMEM) { clean_up: free(tmp_key); free(tmp_val); return -ENOMEM; } return 0; free(old_val); int result = -errno; errno = saved_errno; return result; } int str_parms_add_int(struct str_parms *str_parms, const char *key, int value) Loading Loading @@ -341,7 +364,6 @@ static void test_str_parms_str(const char *str) { struct str_parms *str_parms; char *out_str; int ret; str_parms = str_parms_create_str(str); str_parms_add_str(str_parms, "dude", "woah"); Loading Loading @@ -374,6 +396,15 @@ int main(void) test_str_parms_str("foo=bar;baz=bat;"); test_str_parms_str("foo=bar;baz=bat;foo=bar"); // hashmapPut reports errors by setting errno to ENOMEM. // Test that we're not confused by running in an environment where this is already true. errno = ENOMEM; test_str_parms_str("foo=bar;baz="); if (errno != ENOMEM) { abort(); } test_str_parms_str("foo=bar;baz="); return 0; } #endif Loading
libcutils/Android.mk +10 −0 Original line number Diff line number Diff line Loading @@ -91,6 +91,16 @@ LOCAL_STATIC_LIBRARIES := lib64log LOCAL_CFLAGS += $(hostSmpFlag) -m64 include $(BUILD_HOST_STATIC_LIBRARY) # Tests for host # ======================================================== include $(CLEAR_VARS) LOCAL_MODULE := tst_str_parms LOCAL_CFLAGS += -DTEST_STR_PARMS LOCAL_SRC_FILES := str_parms.c hashmap.c memory.c LOCAL_STATIC_LIBRARIES := liblog LOCAL_MODULE_TAGS := optional include $(BUILD_HOST_EXECUTABLE) # Shared and static library for target # ======================================================== Loading
libcutils/str_parms.c +44 −13 Original line number Diff line number Diff line Loading @@ -194,23 +194,46 @@ err_create_str_parms: int str_parms_add_str(struct str_parms *str_parms, const char *key, const char *value) { void *old_val; void *tmp_key; void *tmp_val; void *tmp_key = NULL; void *tmp_val = NULL; void *old_val = NULL; // strdup and hashmapPut both set errno on failure. // Set errno to 0 so we can recognize whether anything went wrong. int saved_errno = errno; errno = 0; tmp_key = strdup(key); if (tmp_key == NULL) { goto clean_up; } tmp_val = strdup(value); if (tmp_val == NULL) { goto clean_up; } old_val = hashmapPut(str_parms->map, tmp_key, tmp_val); if (old_val == NULL) { // Did hashmapPut fail? if (errno == ENOMEM) { goto clean_up; } // For new keys, hashmap takes ownership of tmp_key and tmp_val. tmp_key = tmp_val = NULL; } else { // For existing keys, hashmap takes ownership of tmp_val. // (It also gives up ownership of old_val.) tmp_val = NULL; } if (old_val) { free(old_val); free(tmp_key); } else if (errno == ENOMEM) { clean_up: free(tmp_key); free(tmp_val); return -ENOMEM; } return 0; free(old_val); int result = -errno; errno = saved_errno; return result; } int str_parms_add_int(struct str_parms *str_parms, const char *key, int value) Loading Loading @@ -341,7 +364,6 @@ static void test_str_parms_str(const char *str) { struct str_parms *str_parms; char *out_str; int ret; str_parms = str_parms_create_str(str); str_parms_add_str(str_parms, "dude", "woah"); Loading Loading @@ -374,6 +396,15 @@ int main(void) test_str_parms_str("foo=bar;baz=bat;"); test_str_parms_str("foo=bar;baz=bat;foo=bar"); // hashmapPut reports errors by setting errno to ENOMEM. // Test that we're not confused by running in an environment where this is already true. errno = ENOMEM; test_str_parms_str("foo=bar;baz="); if (errno != ENOMEM) { abort(); } test_str_parms_str("foo=bar;baz="); return 0; } #endif