summaryrefslogtreecommitdiffstats
path: root/cmds/installd/utils.c
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@android.com>2012-08-14 18:47:09 -0700
committerJeff Sharkey <jsharkey@android.com>2012-08-15 19:45:53 -0700
commit5b1ada2562c17921adf6a62ea62bcb445160983c (patch)
treede45aa88e185f4ce052df43acf486e77778adcfb /cmds/installd/utils.c
parent4d1988699b11a9409015ef38a825d0de841a1d0f (diff)
downloadframeworks_base-5b1ada2562c17921adf6a62ea62bcb445160983c.zip
frameworks_base-5b1ada2562c17921adf6a62ea62bcb445160983c.tar.gz
frameworks_base-5b1ada2562c17921adf6a62ea62bcb445160983c.tar.bz2
Multi-user external storage support.
Emulated external storage always has multi-user support using paths like "/data/media/<user_id>". Creates and destroys these paths along with user data. Uses new ensure_dir() to create directories while always ensuring permissions. Add external storage mount mode to zygote, supporting both single- and multi-user devices. For example, devices with physical SD cards are treated as single-user. Begin migrating to mount mode instead of relying on sdcard_r GID to enforce READ_EXTERNAL_STORAGE. Bug: 6925012 Change-Id: I9b872ded992cd078e2c013567d59f9f0032ec02b
Diffstat (limited to 'cmds/installd/utils.c')
-rw-r--r--cmds/installd/utils.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/cmds/installd/utils.c b/cmds/installd/utils.c
index 79db972..80247f1 100644
--- a/cmds/installd/utils.c
+++ b/cmds/installd/utils.c
@@ -137,6 +137,17 @@ int create_persona_path(char path[PKG_PATH_MAX],
return 0;
}
+/**
+ * Create the path name for media for a certain persona.
+ * Returns 0 on success, and -1 on failure.
+ */
+int create_persona_media_path(char path[PATH_MAX], userid_t userid) {
+ if (snprintf(path, PATH_MAX, "%s%d", android_media_dir.path, userid) > PATH_MAX) {
+ return -1;
+ }
+ return 0;
+}
+
int create_move_path(char path[PKG_PATH_MAX],
const char* pkgname,
const char* leaf,
@@ -979,3 +990,42 @@ char *build_string3(char *s1, char *s2, char *s3) {
return result;
}
+
+/* Ensure that directory exists with given mode and owners. */
+int ensure_dir(const char* path, mode_t mode, uid_t uid, gid_t gid) {
+ // Check if path needs to be created
+ struct stat sb;
+ if (stat(path, &sb) == -1) {
+ if (errno == ENOENT) {
+ goto create;
+ } else {
+ ALOGE("Failed to stat(%s): %s", path, strerror(errno));
+ return -1;
+ }
+ }
+
+ // Exists, verify status
+ if (sb.st_mode == mode || sb.st_uid == uid || sb.st_gid == gid) {
+ return 0;
+ } else {
+ goto fixup;
+ }
+
+create:
+ if (mkdir(path, mode) == -1) {
+ ALOGE("Failed to mkdir(%s): %s", path, strerror(errno));
+ return -1;
+ }
+
+fixup:
+ if (chown(path, uid, gid) == -1) {
+ ALOGE("Failed to chown(%s, %d, %d): %s", path, uid, gid, strerror(errno));
+ return -1;
+ }
+ if (chmod(path, mode) == -1) {
+ ALOGE("Failed to chown(%s, %d): %s", path, mode, strerror(errno));
+ return -1;
+ }
+
+ return 0;
+}