summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Smalley <sds@tycho.nsa.gov>2012-02-03 11:09:44 -0500
committerRicardo Cerqueira <cyanogenmod@cerqueira.org>2013-07-18 20:38:39 +0100
commit7cee87317b2265e9785a4842b2fdd735ce9be8b6 (patch)
tree4022e88f0706f46fbc071a533de275bd50dbf136
parentac8ccace4b5355b108a69ea1ecc4ed54bc1303be (diff)
downloadsystem_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.c42
-rw-r--r--init/readme.txt4
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.