diff options
author | Mathieu Chartier <mathieuc@google.com> | 2014-06-03 20:54:51 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2014-06-03 20:54:51 +0000 |
commit | 520a893b1a76598ac82cbbec2c8e5f36adfaa3af (patch) | |
tree | 6759cefaf77d96e7b9689143e59f654c940bd0ee /libcutils | |
parent | 76a77c7ade532062e8b6c837c610677743494dc2 (diff) | |
parent | b85c2494df1e1003b3101e36b29faace3a51dc3f (diff) | |
download | system_core-520a893b1a76598ac82cbbec2c8e5f36adfaa3af.zip system_core-520a893b1a76598ac82cbbec2c8e5f36adfaa3af.tar.gz system_core-520a893b1a76598ac82cbbec2c8e5f36adfaa3af.tar.bz2 |
am b85c2494: am 03b87b49: Merge "Make host ashmem_create_region seed only once."
* commit 'b85c2494df1e1003b3101e36b29faace3a51dc3f':
Make host ashmem_create_region seed only once.
Diffstat (limited to 'libcutils')
-rw-r--r-- | libcutils/ashmem-host.c | 124 |
1 files changed, 63 insertions, 61 deletions
diff --git a/libcutils/ashmem-host.c b/libcutils/ashmem-host.c index 7873964..4ac4f57 100644 --- a/libcutils/ashmem-host.c +++ b/libcutils/ashmem-host.c @@ -22,6 +22,8 @@ #include <errno.h> #include <fcntl.h> #include <limits.h> +#include <pthread.h> +#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -36,83 +38,83 @@ #define __unused __attribute__((__unused__)) #endif +static pthread_once_t seed_initialized = PTHREAD_ONCE_INIT; +static void initialize_random() { + srand(time(NULL) + getpid()); +} + int ashmem_create_region(const char *ignored __unused, size_t size) { - static const char txt[] = "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - char name[64]; - unsigned int retries = 0; - pid_t pid = getpid(); - int fd; - - srand(time(NULL) + pid); - -retry: - /* not beautiful, its just wolf-like loop unrolling */ - snprintf(name, sizeof(name), "/tmp/android-ashmem-%d-%c%c%c%c%c%c%c%c", - pid, - txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))], - txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))], - txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))], - txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))], - txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))], - txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))], - txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))], - txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))]); - - /* open O_EXCL & O_CREAT: we are either the sole owner or we fail */ - fd = open(name, O_RDWR | O_CREAT | O_EXCL, 0600); - if (fd == -1) { - /* unlikely, but if we failed because `name' exists, retry */ - if (errno == EEXIST && ++retries < 6) - goto retry; - return -1; - } - - /* truncate the file to `len' bytes */ - if (ftruncate(fd, size) == -1) - goto error; - - if (unlink(name) == -1) - goto error; - - return fd; -error: - close(fd); - return -1; + static const char txt[] = "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + char name[64]; + unsigned int retries = 0; + pid_t pid = getpid(); + int fd; + if (pthread_once(&seed_initialized, &initialize_random) != 0) { + return -1; + } + do { + /* not beautiful, its just wolf-like loop unrolling */ + snprintf(name, sizeof(name), "/tmp/android-ashmem-%d-%c%c%c%c%c%c%c%c", + pid, + txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))], + txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))], + txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))], + txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))], + txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))], + txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))], + txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))], + txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))]); + + /* open O_EXCL & O_CREAT: we are either the sole owner or we fail */ + fd = open(name, O_RDWR | O_CREAT | O_EXCL, 0600); + if (fd == -1) { + /* unlikely, but if we failed because `name' exists, retry */ + if (errno != EEXIST || ++retries >= 6) { + return -1; + } + } + } while (fd == -1); + /* truncate the file to `len' bytes */ + if (ftruncate(fd, size) != -1 && unlink(name) != -1) { + return fd; + } + close(fd); + return -1; } int ashmem_set_prot_region(int fd __unused, int prot __unused) { - return 0; + return 0; } int ashmem_pin_region(int fd __unused, size_t offset __unused, size_t len __unused) { - return ASHMEM_NOT_PURGED; + return ASHMEM_NOT_PURGED; } int ashmem_unpin_region(int fd __unused, size_t offset __unused, size_t len __unused) { - return ASHMEM_IS_UNPINNED; + return ASHMEM_IS_UNPINNED; } int ashmem_get_size_region(int fd) { - struct stat buf; - int result; - - result = fstat(fd, &buf); - if (result == -1) { - return -1; - } - - // Check if this is an "ashmem" region. - // TODO: This is very hacky, and can easily break. We need some reliable indicator. - if (!(buf.st_nlink == 0 && S_ISREG(buf.st_mode))) { - errno = ENOTTY; - return -1; - } - - return (int)buf.st_size; // TODO: care about overflow (> 2GB file)? + struct stat buf; + int result; + + result = fstat(fd, &buf); + if (result == -1) { + return -1; + } + + // Check if this is an "ashmem" region. + // TODO: This is very hacky, and can easily break. We need some reliable indicator. + if (!(buf.st_nlink == 0 && S_ISREG(buf.st_mode))) { + errno = ENOTTY; + return -1; + } + + return (int)buf.st_size; // TODO: care about overflow (> 2GB file)? } |