diff options
author | Mathieu Chartier <mathieuc@google.com> | 2014-06-03 19:02:35 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2014-06-03 19:02:35 +0000 |
commit | 03b87b49fae82a6304ab69b10426701c4f82c7e9 (patch) | |
tree | c496707cd5f73d640921e787877774f5f643bd93 /libcutils | |
parent | b0b343d0864556816d89af61f7418130cea047d0 (diff) | |
parent | 1104ae8cfc0e5144e7d796cf29ee124d05401cbf (diff) | |
download | system_core-03b87b49fae82a6304ab69b10426701c4f82c7e9.zip system_core-03b87b49fae82a6304ab69b10426701c4f82c7e9.tar.gz system_core-03b87b49fae82a6304ab69b10426701c4f82c7e9.tar.bz2 |
Merge "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)? } |