2018년 2월 5일 월요일

(안드로이드에서 ro 프로퍼티 값 처리) about android ro property

안드로이드에서 property를 사용해봤다면 ro. 가 붙어 있는 값을 보셨을 겁니다.
ro 값이 붙어있는 property 는 쓰기 전용이라고 알고 있을 텐데요.
엄밀하게 말하자면 쓰기 전용이 아니라 1회만 쓰기가 가능한 property입니다.


1. 값이 없을때 누군가 먼저쓰면 임자란 의미입니다.


2. roxx 이런식으로 해도 동일한 효과가 나올까요? 결론부터 말하자면 아닙니다.


일단 구현이 어디에 되어 있는지 살펴보면,

안드로이드 소스코드는 opengrok ( http://androidxref.com/ )에서 쉽게 살펴 볼 수 있습니다.

android shell에서 setprop 명령을 내리면 init프로세서가 처리합니다. 물론 android에서 setprop를 명령내려도 결국 init에서 처리하게 됩니다.

init의 내장 명령에 대한 처리는 아래 함수 포인터 배열로 관리하고 있습니다.

/system/core/init/builtins.cpp

1024        {"rm",                      {1,     1,    do_rm}},
1025        {"rmdir",                   {1,     1,    do_rmdir}},
1026        {"setprop",                 {2,     2,    do_setprop}},

648static int do_setprop(const std::vector<std::string>& args) {
649    const char* name = args[1].c_str();
650    const char* value = args[2].c_str();
651    property_set(name, value);
652    return 0;
653}


/system/core/init/property_service.cpp

224int property_set(const char* name, const char* value) {
225    int rc = property_set_impl(name, value);
226    if (rc == -1) {
227        ERROR("property_set(\"%s\", \"%s\") failed\n", name, value);
228    }
229    return rc;
230}


171static int property_set_impl(const char* name, const char* value) {
172    size_t namelen = strlen(name);
173    size_t valuelen = strlen(value);
174
175    if (!is_legal_property_name(name, namelen)) return -1;
176    if (valuelen >= PROP_VALUE_MAX) return -1;
177
178    if (strcmp("selinux.reload_policy", name) == 0 && strcmp("1", value) == 0) {
179        if (selinux_reload_policy() != 0) {
180            ERROR("Failed to reload policy\n");
181        }
182    } else if (strcmp("selinux.restorecon_recursive", name) == 0 && valuelen > 0) {
183        if (restorecon_recursive(value) != 0) {
184            ERROR("Failed to restorecon_recursive %s\n", value);
185        }
186    }
187
188    prop_info* pi = (prop_info*) __system_property_find(name);
189
190    if(pi != 0) {
191        /* ro.* properties may NEVER be modified once set */
192        if(!strncmp(name, "ro.", 3)) return -1;
193
194        __system_property_update(pi, value, valuelen);
195    } else {
196        int rc = __system_property_add(name, namelen, value, valuelen);
197        if (rc < 0) {
198            return rc;
199        }
200    }
...
188 line 기존에 존재하는 property가 있는지 얻어오는 함수 입니다.
190 line 만약 값이 있는 경우 "ro." 문자열과 비교하게 되는데 값이 있다면 return -1이 되면서 써지지 않게됩니다.


xref: /bionic/libc/bionic/system_properties.cpp

1078const prop_info *__system_property_find(const char *name)
1079{
1080    if (!__system_property_area__) {
1081        return nullptr;
1082    }
1083
1084    if (__predict_false(compat_mode)) {
1085        return __system_property_find_compat(name);
1086    }
1087
1088    prop_area* pa = get_prop_area_for_name(name);
1089    if (!pa) {
1090        __libc_format_log(ANDROID_LOG_ERROR, "libc", "Access denied finding property \"%s\"", name);
1091        return nullptr;
1092    }
1093
1094    return pa->find(name);
1095}














댓글 없음:

댓글 쓰기