Improved how the Shell directories are created.
When dumpstate is run for the first time, the
/data/data/com.android.shell/files/bugreports does not exist, which was
crashing dumpstate because the code that added the version.txt entry was
not checking if the zip_writer was NULL.
The crash itself was fixed by adding a sanity check in the functions
that add entries to the zip file, but that only hid the real problem:
it is necessary to create the parent directories before creating the zip
file, otherwise the first run will always generate a .txt file (since
dumpstate falls back to .txt when it cannot create the .zip).
This change also improves how the parent directories are created by
checking if they exist first, rather than always calling mkdir().
BUG: 26949960
Change-Id: I1434be5c36a3fad0b3a2a26c7eaaab03a1228c30
diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index ee60f57..0c35430 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -657,23 +657,35 @@
close(fd);
}
-/* redirect output to a file */
-void redirect_to_file(FILE *redirect, char *path) {
- char *chp = path;
+void create_parent_dirs(const char *path) {
+ char *chp = (char*) path;
/* skip initial slash */
if (chp[0] == '/')
chp++;
/* create leading directories, if necessary */
+ struct stat dir_stat;
while (chp && chp[0]) {
chp = strchr(chp, '/');
if (chp) {
*chp = 0;
- mkdir(path, 0770); /* drwxrwx--- */
+ if (stat(path, &dir_stat) == -1 || !S_ISDIR(dir_stat.st_mode)) {
+ ALOGI("Creating directory %s\n", path);
+ if (mkdir(path, 0770)) { /* drwxrwx--- */
+ ALOGE("Unable to create directory %s: %s\n", path, strerror(errno));
+ } else if (chown(path, AID_SHELL, AID_SHELL)) {
+ ALOGE("Unable to change ownership of dir %s: %s\n", path, strerror(errno));
+ }
+ }
*chp++ = '/';
}
}
+}
+
+/* redirect output to a file */
+void redirect_to_file(FILE *redirect, char *path) {
+ create_parent_dirs(path);
int fd = TEMP_FAILURE_RETRY(open(path, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH));