1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 #include "SystemProperty.h"
8
9 #include <dlfcn.h>
10 #include <string.h>
11
12 #include "nsDebug.h"
13 #include "prinit.h"
14
15 namespace mozilla {
16 namespace system {
17
18 namespace {
19
20 typedef int (*PropertyGet)(const char*, char*, const char*);
21 typedef int (*PropertySet)(const char*, const char*);
22
23 static void *sLibcUtils;
24 static PRCallOnceType sInitLibcUtils;
25
26 static int
FakePropertyGet(const char * key,char * value,const char * default_value)27 FakePropertyGet(const char* key, char* value, const char* default_value)
28 {
29 if(!default_value) {
30 value[0] = '\0';
31 return 0;
32 }
33
34 int len = strlen(default_value);
35 if (len >= Property::VALUE_MAX_LENGTH) {
36 len = Property::VALUE_MAX_LENGTH - 1;
37 }
38 memcpy(value, default_value, len);
39 value[len] = '\0';
40
41 return len;
42 }
43
44 static int
FakePropertySet(const char * key,const char * value)45 FakePropertySet(const char* key, const char* value)
46 {
47 return 0;
48 }
49
50 static PRStatus
InitLibcUtils()51 InitLibcUtils()
52 {
53 sLibcUtils = dlopen("/system/lib/libcutils.so", RTLD_LAZY);
54 // We will fallback to the fake getter/setter when sLibcUtils is not valid.
55 return PR_SUCCESS;
56 }
57
58 static void*
GetLibcUtils()59 GetLibcUtils()
60 {
61 PR_CallOnce(&sInitLibcUtils, InitLibcUtils);
62 return sLibcUtils;
63 }
64
65 } // anonymous namespace
66
67 /*static*/ int
Get(const char * key,char * value,const char * default_value)68 Property::Get(const char* key, char* value, const char* default_value)
69 {
70 void *libcutils = GetLibcUtils();
71 if (libcutils) {
72 PropertyGet getter = (PropertyGet) dlsym(libcutils, "property_get");
73 if (getter) {
74 return getter(key, value, default_value);
75 }
76 NS_WARNING("Failed to get property_get() from libcutils!");
77 }
78 NS_WARNING("Fallback to the FakePropertyGet()");
79 return FakePropertyGet(key, value, default_value);
80 }
81
82 /*static*/ int
Set(const char * key,const char * value)83 Property::Set(const char* key, const char* value)
84 {
85 void *libcutils = GetLibcUtils();
86 if (libcutils) {
87 PropertySet setter = (PropertySet) dlsym(libcutils, "property_set");
88 if (setter) {
89 return setter(key, value);
90 }
91 NS_WARNING("Failed to get property_set() from libcutils!");
92 }
93 NS_WARNING("Fallback to the FakePropertySet()");
94 return FakePropertySet(key, value);
95 }
96
97 } // namespace system
98 } // namespace mozilla
99