diff options
author | Stephen Smalley <sds@tycho.nsa.gov> | 2012-02-03 11:09:44 -0500 |
---|---|---|
committer | Ricardo Cerqueira <cyanogenmod@cerqueira.org> | 2013-07-18 20:38:39 +0100 |
commit | 7cee87317b2265e9785a4842b2fdd735ce9be8b6 (patch) | |
tree | 4022e88f0706f46fbc071a533de275bd50dbf136 | |
parent | ac8ccace4b5355b108a69ea1ecc4ed54bc1303be (diff) | |
download | system_core-7cee87317b2265e9785a4842b2fdd735ce9be8b6.zip system_core-7cee87317b2265e9785a4842b2fdd735ce9be8b6.tar.gz system_core-7cee87317b2265e9785a4842b2fdd735ce9be8b6.tar.bz2 |
Add support for -R (recurse) to init chown builtin.
This is helpful for setting ownerships on entire directory trees,
such as sysfs and selinuxfs, particularly when the precise set of
files is dynamically generated at runtime.
Change-Id: I81070ea36fd7ffcab4ee8b3ef1bb0028d4b7839c
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
-rw-r--r-- | init/builtins.c | 42 | ||||
-rw-r--r-- | init/readme.txt | 4 |
2 files changed, 44 insertions, 2 deletions
diff --git a/init/builtins.c b/init/builtins.c index ba7fe3f..de067ce 100644 --- a/init/builtins.c +++ b/init/builtins.c @@ -35,6 +35,7 @@ #include <cutils/partition_utils.h> #include <sys/system_properties.h> #include <fs_mgr.h> +#include <fts.h> #ifdef HAVE_SELINUX #include <selinux/selinux.h> @@ -804,6 +805,47 @@ int do_chown(int nargs, char **args) { } else if (nargs == 4) { if (_chown(args[3], decode_uid(args[1]), decode_uid(args[2])) < 0) return -errno; + } else if (nargs == 5) { + int ret = 0; + int ftsflags = FTS_PHYSICAL; + FTS *fts; + FTSENT *ftsent; + char *options = args[1]; + uid_t uid = decode_uid(args[2]); + uid_t gid = decode_uid(args[3]); + char * path_argv[] = {args[4], NULL}; + if (strcmp(options, "-R")) { + ERROR("do_chown: Invalid argument: %s\n", args[1]); + return -EINVAL; + } + fts = fts_open(path_argv, ftsflags, NULL); + if (!fts) { + ERROR("do_chown: Error traversing hierarchy starting at %s\n", path_argv[0]); + return -errno; + } + while ((ftsent = fts_read(fts))) { + switch (ftsent->fts_info) { + case FTS_DP: + case FTS_SL: + break; + case FTS_DNR: + case FTS_ERR: + case FTS_NS: + ERROR("do_chown: Could not access %s\n", ftsent->fts_path); + fts_set(fts, ftsent, FTS_SKIP); + ret = -errno; + break; + default: + if (_chown(ftsent->fts_accpath, uid, gid) < 0) { + ret = -errno; + fts_set(fts, ftsent, FTS_SKIP); + } + break; + } + } + fts_close(fts); + if (ret) + return ret; } else { return -1; } diff --git a/init/readme.txt b/init/readme.txt index fe0d15d..f674db8 100644 --- a/init/readme.txt +++ b/init/readme.txt @@ -151,8 +151,8 @@ chdir <directory> chmod <octal-mode> <path> Change file access permissions. -chown <owner> <group> <path> - Change file owner and group. +chown [-R] <owner> <group> <path> + Change file owner and group. "-R" is for recursive chown. chroot <directory> Change process root directory. |