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