summaryrefslogtreecommitdiffstats
path: root/cmds
diff options
context:
space:
mode:
authorKenny Root <kroot@google.com>2010-10-07 16:46:10 -0700
committerKenny Root <kroot@google.com>2010-10-07 17:20:26 -0700
commit6a6b007c77e5cab7ee435506a4f65824f52028b6 (patch)
tree09daacd02a3582c26d72411e5ef0129812d0c8d6 /cmds
parentb74941e32e068ec03f90b9a53670328cd17ff4b4 (diff)
downloadframeworks_base-6a6b007c77e5cab7ee435506a4f65824f52028b6.zip
frameworks_base-6a6b007c77e5cab7ee435506a4f65824f52028b6.tar.gz
frameworks_base-6a6b007c77e5cab7ee435506a4f65824f52028b6.tar.bz2
Symlink application lib directory when on SD card
This will help legacy games that use dlopen() to directly access the /data/data/<app>/lib directory before the ApplicationInfo.nativeLibraryDir was part of the API. Change-Id: Ie9f3e7239b6334708b5d086ffafe66a507f6d9da
Diffstat (limited to 'cmds')
-rw-r--r--cmds/installd/commands.c154
-rw-r--r--cmds/installd/installd.c12
-rw-r--r--cmds/installd/installd.h2
3 files changed, 168 insertions, 0 deletions
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c
index f6f80d1..a5b3e0e 100644
--- a/cmds/installd/commands.c
+++ b/cmds/installd/commands.c
@@ -936,3 +936,157 @@ int movefiles()
done:
return 0;
}
+
+int linklib(const char* dataDir, const char* asecLibDir)
+{
+ char libdir[PKG_PATH_MAX];
+ struct stat s, libStat;
+ int rc = 0;
+
+ const size_t libdirLen = strlen(dataDir) + strlen(PKG_LIB_POSTFIX);
+ if (libdirLen >= PKG_PATH_MAX) {
+ LOGE("library dir len too large");
+ rc = -1;
+ goto out;
+ }
+
+ if (snprintf(libdir, sizeof(libdir), "%s%s", dataDir, PKG_LIB_POSTFIX) != (ssize_t)libdirLen) {
+ LOGE("library dir not written successfully: %s\n", strerror(errno));
+ rc = -1;
+ goto out;
+ }
+
+ if (stat(dataDir, &s) < 0) return -1;
+
+ if (chown(dataDir, 0, 0) < 0) {
+ LOGE("failed to chown '%s': %s\n", dataDir, strerror(errno));
+ return -1;
+ }
+
+ if (chmod(dataDir, 0700) < 0) {
+ LOGE("failed to chmod '%s': %s\n", dataDir, strerror(errno));
+ rc = -1;
+ goto out;
+ }
+
+ if (lstat(libdir, &libStat) < 0) {
+ LOGE("couldn't stat lib dir: %s\n", strerror(errno));
+ rc = -1;
+ goto out;
+ }
+
+ if (S_ISDIR(libStat.st_mode)) {
+ if (delete_dir_contents(libdir, 1, 0) < 0) {
+ rc = -1;
+ goto out;
+ }
+ } else if (S_ISLNK(libStat.st_mode)) {
+ if (unlink(libdir) < 0) {
+ rc = -1;
+ goto out;
+ }
+ }
+
+ if (symlink(asecLibDir, libdir) < 0) {
+ LOGE("couldn't symlink directory '%s' -> '%s': %s\n", libdir, asecLibDir, strerror(errno));
+ rc = -errno;
+ goto out;
+ }
+
+ if (lchown(libdir, AID_SYSTEM, AID_SYSTEM) < 0) {
+ LOGE("cannot chown dir '%s': %s\n", libdir, strerror(errno));
+ unlink(libdir);
+ rc = -errno;
+ goto out;
+ }
+
+out:
+ if (chmod(dataDir, s.st_mode) < 0) {
+ LOGE("failed to chmod '%s': %s\n", dataDir, strerror(errno));
+ return -errno;
+ }
+
+ if (chown(dataDir, s.st_uid, s.st_gid) < 0) {
+ LOGE("failed to chown '%s' : %s\n", dataDir, strerror(errno));
+ return -errno;
+ }
+
+ return rc;
+}
+
+int unlinklib(const char* dataDir)
+{
+ char libdir[PKG_PATH_MAX];
+ struct stat s, libStat;
+ int rc = 0;
+
+ const size_t libdirLen = strlen(dataDir) + strlen(PKG_LIB_POSTFIX);
+ if (libdirLen >= PKG_PATH_MAX) {
+ return -1;
+ }
+
+ if (snprintf(libdir, sizeof(libdir), "%s%s", dataDir, PKG_LIB_POSTFIX) != (ssize_t)libdirLen) {
+ LOGE("library dir not written successfully: %s\n", strerror(errno));
+ return -1;
+ }
+
+ if (stat(dataDir, &s) < 0) {
+ LOGE("couldn't state data dir");
+ return -1;
+ }
+
+ if (chown(dataDir, 0, 0) < 0) {
+ LOGE("failed to chown '%s': %s\n", dataDir, strerror(errno));
+ return -1;
+ }
+
+ if (chmod(dataDir, 0700) < 0) {
+ LOGE("failed to chmod '%s': %s\n", dataDir, strerror(errno));
+ rc = -1;
+ goto out;
+ }
+
+ if (lstat(libdir, &libStat) < 0) {
+ LOGE("couldn't stat lib dir: %s\n", strerror(errno));
+ rc = -1;
+ goto out;
+ }
+
+ if (S_ISDIR(libStat.st_mode)) {
+ if (delete_dir_contents(libdir, 1, 0) < 0) {
+ rc = -1;
+ goto out;
+ }
+ } else if (S_ISLNK(libStat.st_mode)) {
+ if (unlink(libdir) < 0) {
+ rc = -1;
+ goto out;
+ }
+ }
+
+ if (mkdir(libdir, 0755) < 0) {
+ LOGE("cannot create dir '%s': %s\n", libdir, strerror(errno));
+ rc = -errno;
+ goto out;
+ }
+
+ if (chown(libdir, AID_SYSTEM, AID_SYSTEM) < 0) {
+ LOGE("cannot chown dir '%s': %s\n", libdir, strerror(errno));
+ unlink(libdir);
+ rc = -errno;
+ goto out;
+ }
+
+out:
+ if (chmod(dataDir, s.st_mode) < 0) {
+ LOGE("failed to chmod '%s': %s\n", dataDir, strerror(errno));
+ return -1;
+ }
+
+ if (chown(dataDir, s.st_uid, s.st_gid) < 0) {
+ LOGE("failed to chown '%s' : %s\n", dataDir, strerror(errno));
+ return -1;
+ }
+
+ return rc;
+}
diff --git a/cmds/installd/installd.c b/cmds/installd/installd.c
index c991845..9ba6402 100644
--- a/cmds/installd/installd.c
+++ b/cmds/installd/installd.c
@@ -101,6 +101,16 @@ static int do_movefiles(char **arg, char reply[REPLY_MAX])
return movefiles();
}
+static int do_linklib(char **arg, char reply[REPLY_MAX])
+{
+ return linklib(arg[0], arg[1]);
+}
+
+static int do_unlinklib(char **arg, char reply[REPLY_MAX])
+{
+ return unlinklib(arg[0]);
+}
+
struct cmdinfo {
const char *name;
unsigned numargs;
@@ -121,6 +131,8 @@ struct cmdinfo cmds[] = {
{ "getsize", 4, do_get_size },
{ "rmuserdata", 2, do_rm_user_data },
{ "movefiles", 0, do_movefiles },
+ { "linklib", 2, do_linklib },
+ { "unlinklib", 1, do_unlinklib },
};
static int readx(int s, void *_buf, int count)
diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h
index 479e4b2..59475e9 100644
--- a/cmds/installd/installd.h
+++ b/cmds/installd/installd.h
@@ -111,3 +111,5 @@ int get_size(const char *pkgname, const char *apkpath, const char *fwdlock_apkpa
int free_cache(int64_t free_size);
int dexopt(const char *apk_path, uid_t uid, int is_public);
int movefiles();
+int linklib(const char* target, const char* source);
+int unlinklib(const char* libPath);