libsysutils: Introduce 'ServiceManager', for starting/stopping init services

Signed-off-by: San Mehat <san@google.com>
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 @@
                   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;
+}