diff options
| author | Jeff Sharkey <jsharkey@android.com> | 2012-09-13 14:47:23 -0700 |
|---|---|---|
| committer | Jeff Sharkey <jsharkey@android.com> | 2012-09-13 15:02:53 -0700 |
| commit | ddb173394430a7b55b0c24896a843556f5f8de7a (patch) | |
| tree | 68448c53c7179d50195488b3ad291a4c100489d0 | |
| parent | 0f5e303c6a88c63fc5a4d325ab675af7ed57b777 (diff) | |
| download | system_core-ddb173394430a7b55b0c24896a843556f5f8de7a.zip system_core-ddb173394430a7b55b0c24896a843556f5f8de7a.tar.gz system_core-ddb173394430a7b55b0c24896a843556f5f8de7a.tar.bz2 | |
Wrap system calls in TEMP_FAILURE_RETRY.
fs_prepare_dir() is used heavily during Zygote init, and can easily
run into EINTR.
Bug: 7151474
Change-Id: I7aac43a43483d55db47ca20456fff68ce51bbc46
| -rw-r--r-- | include/cutils/fs.h | 15 | ||||
| -rw-r--r-- | libcutils/fs.c | 14 |
2 files changed, 23 insertions, 6 deletions
diff --git a/include/cutils/fs.h b/include/cutils/fs.h index 04c8839..fd5296b 100644 --- a/include/cutils/fs.h +++ b/include/cutils/fs.h @@ -19,6 +19,21 @@ #include <sys/types.h> +/* + * TEMP_FAILURE_RETRY is defined by some, but not all, versions of + * <unistd.h>. (Alas, it is not as standard as we'd hoped!) So, if it's + * not already defined, then define it here. + */ +#ifndef TEMP_FAILURE_RETRY +/* Used to retry syscalls that can return EINTR. */ +#define TEMP_FAILURE_RETRY(exp) ({ \ + typeof (exp) _rc; \ + do { \ + _rc = (exp); \ + } while (_rc == -1 && errno == EINTR); \ + _rc; }) +#endif + #ifdef __cplusplus extern "C" { #endif diff --git a/libcutils/fs.c b/libcutils/fs.c index 1788eca..6508b67 100644 --- a/libcutils/fs.c +++ b/libcutils/fs.c @@ -14,6 +14,8 @@ * limitations under the License. */ +#define LOG_TAG "cutils" + #include <cutils/fs.h> #include <cutils/log.h> @@ -31,11 +33,11 @@ int fs_prepare_dir(const char* path, mode_t mode, uid_t uid, gid_t gid) { // Check if path needs to be created struct stat sb; - if (lstat(path, &sb) == -1) { + if (TEMP_FAILURE_RETRY(lstat(path, &sb)) == -1) { if (errno == ENOENT) { goto create; } else { - ALOGE("Failed to stat(%s): %s", path, strerror(errno)); + ALOGE("Failed to lstat(%s): %s", path, strerror(errno)); return -1; } } @@ -52,17 +54,17 @@ int fs_prepare_dir(const char* path, mode_t mode, uid_t uid, gid_t gid) { } create: - if (mkdir(path, mode) == -1) { + if (TEMP_FAILURE_RETRY(mkdir(path, mode)) == -1) { ALOGE("Failed to mkdir(%s): %s", path, strerror(errno)); return -1; } fixup: - if (chmod(path, mode) == -1) { - ALOGE("Failed to chown(%s, %d): %s", path, mode, strerror(errno)); + if (TEMP_FAILURE_RETRY(chmod(path, mode)) == -1) { + ALOGE("Failed to chmod(%s, %d): %s", path, mode, strerror(errno)); return -1; } - if (chown(path, uid, gid) == -1) { + if (TEMP_FAILURE_RETRY(chown(path, uid, gid)) == -1) { ALOGE("Failed to chown(%s, %d, %d): %s", path, uid, gid, strerror(errno)); return -1; } |
