summaryrefslogtreecommitdiffstats
path: root/libcutils
diff options
context:
space:
mode:
Diffstat (limited to 'libcutils')
-rw-r--r--libcutils/Android.mk2
-rw-r--r--libcutils/android_reboot.c134
-rw-r--r--libcutils/atomic-android-sh.c12
-rw-r--r--libcutils/properties.c40
4 files changed, 136 insertions, 52 deletions
diff --git a/libcutils/Android.mk b/libcutils/Android.mk
index 03e6e9a..283a6bf 100644
--- a/libcutils/Android.mk
+++ b/libcutils/Android.mk
@@ -110,7 +110,7 @@ else #!sim
# ========================================================
include $(CLEAR_VARS)
LOCAL_MODULE := libcutils
-LOCAL_SRC_FILES := $(commonSources) ashmem-dev.c mq.c uevent.c qtaguid.c
+LOCAL_SRC_FILES := $(commonSources) ashmem-dev.c mq.c android_reboot.c uevent.c qtaguid.c
ifeq ($(TARGET_ARCH),arm)
LOCAL_SRC_FILES += arch-arm/memset32.S
diff --git a/libcutils/android_reboot.c b/libcutils/android_reboot.c
new file mode 100644
index 0000000..33a7358
--- /dev/null
+++ b/libcutils/android_reboot.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2011, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <unistd.h>
+#include <sys/reboot.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <cutils/android_reboot.h>
+
+/* Check to see if /proc/mounts contains any writeable filesystems
+ * backed by a block device.
+ * Return true if none found, else return false.
+ */
+static int remount_ro_done(void)
+{
+ FILE *f;
+ char mount_dev[256];
+ char mount_dir[256];
+ char mount_type[256];
+ char mount_opts[256];
+ int mount_freq;
+ int mount_passno;
+ int match;
+ int found_rw_fs = 0;
+
+ f = fopen("/proc/mounts", "r");
+ if (! f) {
+ /* If we can't read /proc/mounts, just give up */
+ return 1;
+ }
+
+ do {
+ match = fscanf(f, "%255s %255s %255s %255s %d %d\n",
+ mount_dev, mount_dir, mount_type,
+ mount_opts, &mount_freq, &mount_passno);
+ mount_dev[255] = 0;
+ mount_dir[255] = 0;
+ mount_type[255] = 0;
+ mount_opts[255] = 0;
+ if ((match == 6) && !strncmp(mount_dev, "/dev/block", 10) && strstr(mount_opts, "rw")) {
+ found_rw_fs = 1;
+ break;
+ }
+ } while (match != EOF);
+
+ fclose(f);
+
+ return !found_rw_fs;
+}
+
+/* Remounting filesystems read-only is difficult when there are files
+ * opened for writing or pending deletes on the filesystem. There is
+ * no way to force the remount with the mount(2) syscall. The magic sysrq
+ * 'u' command does an emergency remount read-only on all writable filesystems
+ * that have a block device (i.e. not tmpfs filesystems) by calling
+ * emergency_remount(), which knows how to force the remount to read-only.
+ * Unfortunately, that is asynchronous, and just schedules the work and
+ * returns. The best way to determine if it is done is to read /proc/mounts
+ * repeatedly until there are no more writable filesystems mounted on
+ * block devices.
+ */
+static void remount_ro(void)
+{
+ int fd, cnt = 0;
+
+ /* Trigger the remount of the filesystems as read-only,
+ * which also marks them clean.
+ */
+ fd = open("/proc/sysrq-trigger", O_WRONLY);
+ if (fd < 0) {
+ return;
+ }
+ write(fd, "u", 1);
+ close(fd);
+
+
+ /* Now poll /proc/mounts till it's done */
+ while (!remount_ro_done() && (cnt < 50)) {
+ usleep(100000);
+ cnt++;
+ }
+
+ return;
+}
+
+
+int android_reboot(int cmd, int flags, char *arg)
+{
+ int ret;
+
+ if (!(flags & ANDROID_RB_FLAG_NO_SYNC))
+ sync();
+
+ if (!(flags & ANDROID_RB_FLAG_NO_REMOUNT_RO))
+ remount_ro();
+
+ switch (cmd) {
+ case ANDROID_RB_RESTART:
+ ret = reboot(RB_AUTOBOOT);
+ break;
+
+ case ANDROID_RB_POWEROFF:
+ ret = reboot(RB_POWER_OFF);
+ break;
+
+ case ANDROID_RB_RESTART2:
+ ret = __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
+ LINUX_REBOOT_CMD_RESTART2, arg);
+ break;
+
+ default:
+ ret = -1;
+ }
+
+ return ret;
+}
+
diff --git a/libcutils/atomic-android-sh.c b/libcutils/atomic-android-sh.c
index f8f1f57..8bac68a 100644
--- a/libcutils/atomic-android-sh.c
+++ b/libcutils/atomic-android-sh.c
@@ -113,18 +113,6 @@ int32_t android_atomic_or(int32_t value, volatile int32_t* addr) {
return oldValue;
}
-int32_t android_atomic_acquire_swap(int32_t value, volatile int32_t* addr) {
- return android_atomic_release_swap(value, addr);
-}
-
-int32_t android_atomic_release_swap(int32_t value, volatile int32_t* addr) {
- int32_t oldValue;
- do {
- oldValue = *addr;
- } while (android_atomic_cmpxchg(oldValue, value, addr));
- return oldValue;
-}
-
int android_atomic_acquire_cmpxchg(int32_t oldvalue, int32_t newvalue,
volatile int32_t* addr) {
return android_atomic_release_cmpxchg(oldValue, newValue, addr);
diff --git a/libcutils/properties.c b/libcutils/properties.c
index 547cc6d..98f356b 100644
--- a/libcutils/properties.c
+++ b/libcutils/properties.c
@@ -31,47 +31,9 @@
#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
#include <sys/_system_properties.h>
-static int send_prop_msg(prop_msg *msg)
-{
- int s;
- int r;
-
- s = socket_local_client(PROP_SERVICE_NAME,
- ANDROID_SOCKET_NAMESPACE_RESERVED,
- SOCK_STREAM);
- if(s < 0) return -1;
-
- while((r = send(s, msg, sizeof(prop_msg), 0)) < 0) {
- if((errno == EINTR) || (errno == EAGAIN)) continue;
- break;
- }
-
- if(r == sizeof(prop_msg)) {
- r = 0;
- } else {
- r = -1;
- }
-
- close(s);
- return r;
-}
-
int property_set(const char *key, const char *value)
{
- prop_msg msg;
- unsigned resp;
-
- if(key == 0) return -1;
- if(value == 0) value = "";
-
- if(strlen(key) >= PROP_NAME_MAX) return -1;
- if(strlen(value) >= PROP_VALUE_MAX) return -1;
-
- msg.cmd = PROP_MSG_SETPROP;
- strcpy((char*) msg.name, key);
- strcpy((char*) msg.value, value);
-
- return send_prop_msg(&msg);
+ return __system_property_set(key, value);
}
int property_get(const char *key, char *value, const char *default_value)