From 5b1ada2562c17921adf6a62ea62bcb445160983c Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Tue, 14 Aug 2012 18:47:09 -0700 Subject: Multi-user external storage support. Emulated external storage always has multi-user support using paths like "/data/media/". 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 --- cmds/installd/utils.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'cmds/installd/utils.c') diff --git a/cmds/installd/utils.c b/cmds/installd/utils.c index 79db972a6432..80247f1401d8 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; +} -- cgit v1.2.3-59-g8ed1b