auto import from //branches/cupcake/...@132276
diff --git a/vold/misc.c b/vold/misc.c
index 951414c..b8e5957 100644
--- a/vold/misc.c
+++ b/vold/misc.c
@@ -49,8 +49,11 @@
/* slurp it into our buffer */
ret = read(fd, buffer, size);
- if (ret != size)
+ if (ret != size) {
+ free(buffer);
+ buffer = NULL;
goto bail;
+ }
/* let the caller know how big it is */
*_size = size;
@@ -59,33 +62,90 @@
close(fd);
return buffer;
}
-char *truncate_sysfs_path(char *path, int num_elements_to_remove, char *buffer)
+
+char *truncate_sysfs_path(char *path, int count, char *buffer, size_t bufflen)
{
- int i;
+ char* p;
- strcpy(buffer, path);
+ strlcpy(buffer, path, bufflen);
+ p = buffer + strlen(buffer);
- for (i = 0; i < num_elements_to_remove; i++) {
- char *p = &buffer[strlen(buffer)-1];
+ for ( ; count > 0; count-- ) {
+ while (p > buffer && p[-1] != '/') {
+ p--;
+ }
+ if (p == buffer)
+ break;
- for (p = &buffer[strlen(buffer) -1]; *p != '/'; p--);
- *p = '\0';
+ p -= 1;
}
+ p[0] = '\0';
return buffer;
}
-char *read_sysfs_var(char *buffer, size_t maxlen, char *devpath, char *var)
+/* used to read the first line of a /sys file into a heap-allocated buffer
+ * this assumes that reading the file returns a list of zero-terminated strings,
+ * each could also have a terminating \n before the 0
+ *
+ * returns NULL on error, of a new string on success, which must be freed by the
+ * caller.
+ */
+char *read_first_line_of(const char* filepath)
{
- char filename[255];
- char *p;
+ char *p, *q, *line;
+ size_t len;
ssize_t sz;
- sprintf(filename, "/sys%s/%s", devpath, var);
- p = read_file(filename, &sz);
- p[(strlen(p) - 1)] = '\0';
- strncpy(buffer, p, maxlen);
+ p = read_file((char*)filepath, &sz);
+ if (p == NULL)
+ goto FAIL;
+
+ /* search end of first line */
+ q = memchr(p, sz, '\0');
+ if (q == NULL)
+ q = p + sz; /* let's be flexible */
+
+ len = (size_t)(q - p); /* compute line length */
+ if (len == 0)
+ goto FAIL;
+
+ if (p[len-1] == '\n') { /* strip trailing \n */
+ len -= 1;
+ if (len == 0)
+ goto FAIL;
+ }
+
+ line = malloc(len+1);
+ if (line == NULL)
+ goto FAIL;
+
+ memcpy(line, p, len);
+ line[len] = 0;
free(p);
+
+ return line;
+
+FAIL:
+ if (p != NULL)
+ free(p);
+
+ return NULL;
+}
+
+char *read_sysfs_var(char *buffer, size_t maxlen, char *devpath, char *var)
+{
+ char filename[255], *line;
+
+ snprintf(filename, sizeof filename, "/sys%s/%s", devpath, var);
+
+ line = read_first_line_of(filename);
+ if (line == NULL)
+ return NULL;
+
+ snprintf(buffer, maxlen, "%s", line);
+ free(line);
+
return buffer;
}
diff --git a/vold/uevent.c b/vold/uevent.c
index 3b7e53b..b1a6944 100644
--- a/vold/uevent.c
+++ b/vold/uevent.c
@@ -72,7 +72,7 @@
};
static boolean low_batt = false;
-static boolean door_open = false;
+static boolean door_open = true;
int process_uevent_message(int socket)
{
diff --git a/vold/volmgr.c b/vold/volmgr.c
index 0cec825..c3ce8d1 100644
--- a/vold/volmgr.c
+++ b/vold/volmgr.c
@@ -356,6 +356,7 @@
LOG_VOL("Volmgr notified of %d:%d eject", dev->major, dev->minor);
volume_t *v;
+ int rc;
// XXX: Partitioning support is going to need us to stop *all*
// devices in this volume
@@ -371,9 +372,38 @@
if (v->state == volstate_mounted ||
v->state == volstate_ums ||
- v->state == volstate_checking)
+ v->state == volstate_checking) {
+
volume_setstate(v, volstate_badremoval);
- else if (v->state == volstate_formatting) {
+
+ /*
+ * Stop any devmapper volumes which
+ * are using us as a source
+ * XXX: We may need to enforce stricter
+ * order here
+ */
+ volume_t *dmvol = vol_root;
+ while (dmvol) {
+ if ((dmvol->media_type == media_devmapper) &&
+ (dmvol->dm->src_type == dmsrc_loopback) &&
+ (!strncmp(dmvol->dm->type_data.loop.loop_src,
+ v->mount_point, strlen(v->mount_point)))) {
+
+ pthread_mutex_lock(&dmvol->lock);
+ if (dmvol->state != volstate_nomedia) {
+ rc = volmgr_shutdown_volume(dmvol, _cb_volstopped_for_devmapper_teardown, false);
+ if (rc != -EINPROGRESS) {
+ if (rc)
+ LOGE("unable to shutdown volume '%s'", v->mount_point);
+ pthread_mutex_unlock(&dmvol->lock);
+ }
+ } else
+ pthread_mutex_unlock(&dmvol->lock);
+ }
+ dmvol = dmvol->next;
+ }
+
+ } else if (v->state == volstate_formatting) {
/*
* The device is being ejected due to
* kernel disk revalidation.
@@ -409,7 +439,8 @@
LOG_VOL("Volume %s has been stopped for eject", v->mount_point);
#endif
- eject_cb(v->dev);
+ if (eject_cb)
+ eject_cb(v->dev);
v->dev = NULL; // Clear dev because its being ejected
}