summaryrefslogtreecommitdiffstats
path: root/libsysutils
diff options
context:
space:
mode:
authorSan Mehat <san@google.com>2009-05-14 14:58:45 -0700
committerSan Mehat <san@google.com>2009-05-15 10:40:23 -0700
commitc41d1c8074ed02acc9d1e749d81e0aafb5efbbfa (patch)
tree23133380d778a55675186b160e90e7ff73670bc2 /libsysutils
parentc83cd879d45e667fbb4763f18c908928ee9d67d8 (diff)
downloadsystem_core-c41d1c8074ed02acc9d1e749d81e0aafb5efbbfa.zip
system_core-c41d1c8074ed02acc9d1e749d81e0aafb5efbbfa.tar.gz
system_core-c41d1c8074ed02acc9d1e749d81e0aafb5efbbfa.tar.bz2
libsysutils: Introduce 'ServiceManager', for starting/stopping init services
Signed-off-by: San Mehat <san@google.com>
Diffstat (limited to 'libsysutils')
-rw-r--r--libsysutils/Android.mk1
-rw-r--r--libsysutils/src/ServiceManager.cpp73
2 files changed, 74 insertions, 0 deletions
diff --git a/libsysutils/Android.mk b/libsysutils/Android.mk
index 2f3e106..dd2b32d 100644
--- a/libsysutils/Android.mk
+++ b/libsysutils/Android.mk
@@ -16,6 +16,7 @@ LOCAL_SRC_FILES:= \
src/NetlinkEvent.cpp \
src/FrameworkCommand.cpp \
src/SocketClient.cpp \
+ src/ServiceManager.cpp \
LOCAL_MODULE:= libsysutils
diff --git a/libsysutils/src/ServiceManager.cpp b/libsysutils/src/ServiceManager.cpp
new file mode 100644
index 0000000..700ac91
--- /dev/null
+++ b/libsysutils/src/ServiceManager.cpp
@@ -0,0 +1,73 @@
+#include <errno.h>
+
+#include <sysutils/ServiceManager.h>
+
+#define LOG_TAG "Service"
+#include <cutils/log.h>
+#include <cutils/properties.h>
+
+ServiceManager::ServiceManager() {
+}
+
+int ServiceManager::start(const char *name) {
+ if (isRunning(name)) {
+ LOGW("Service '%s' is already running", name);
+ return 0;
+ }
+
+ LOGD("Starting service '%s'", name);
+ property_set("ctl.start", name);
+
+ int count = 200;
+ while(count--) {
+ sched_yield();
+ if (isRunning(name))
+ break;
+ }
+ if (!count) {
+ LOGW("Timed out waiting for service '%s' to start", name);
+ errno = ETIMEDOUT;
+ return -1;
+ }
+ LOGD("Sucessfully started '%s'", name);
+ return 0;
+}
+
+int ServiceManager::stop(const char *name) {
+ if (!isRunning(name)) {
+ LOGW("Service '%s' is already stopped", name);
+ return 0;
+ }
+
+ LOGD("Stopping service '%s'", name);
+ property_set("ctl.stop", name);
+
+ int count = 200;
+ while(count--) {
+ sched_yield();
+ if (!isRunning(name))
+ break;
+ }
+
+ if (!count) {
+ LOGW("Timed out waiting for service '%s' to stop", name);
+ errno = ETIMEDOUT;
+ return -1;
+ }
+ LOGD("Sucessfully stopped '%s'", name);
+ return 0;
+}
+
+bool ServiceManager::isRunning(const char *name) {
+ char propVal[PROPERTY_VALUE_MAX];
+ char propName[255];
+
+ snprintf(propName, sizeof(propVal), "init.svc.%s", name);
+
+
+ if (property_get(propName, propVal, NULL)) {
+ if (!strcmp(propVal, "running"))
+ return true;
+ }
+ return false;
+}