diff options
author | Mark Salyzyn <salyzyn@google.com> | 2016-11-07 09:39:30 -0800 |
---|---|---|
committer | Mark Salyzyn <salyzyn@google.com> | 2016-11-16 15:56:56 -0800 |
commit | 52bd37e63373b410c009e8611508191dfbf31d30 (patch) | |
tree | 32ed2ad56a69bb6d00b2193eaaed07d813e46982 /libcutils/android_get_control_file.cpp | |
parent | e631e470e059d84388f3aacfe11a3fa60a584ba7 (diff) |
libcutils: move cutils/files.h to cutils/android_get_control_file.h
files.[h|cpp] is bound to be abused with junk, replace with
android_get_control_file.[h|cpp]. Plus some sundry cleanup.
Test: gTest libcutils-tests, logd-unit-tests, liblog-unit-tests,
logcat-unit-tests and init_tests
Bug: 32450474
Change-Id: Ibd4a7aa4624ea19a43d1f98a3c71ac37805d36b5
Diffstat (limited to 'libcutils/android_get_control_file.cpp')
-rw-r--r-- | libcutils/android_get_control_file.cpp | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/libcutils/android_get_control_file.cpp b/libcutils/android_get_control_file.cpp new file mode 100644 index 000000000..496fbbfe6 --- /dev/null +++ b/libcutils/android_get_control_file.cpp @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <ctype.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> + +#include <cutils/android_get_control_file.h> + +#include "android_get_control_env.h" + +LIBCUTILS_HIDDEN int __android_get_control_from_env(const char* prefix, + const char* name) { + if (!prefix || !name) return -1; + + char *key = NULL; + if (asprintf(&key, "%s%s", prefix, name) < 0) return -1; + if (!key) return -1; + + char *cp = key; + while (*cp) { + if (!isalnum(*cp)) *cp = '_'; + ++cp; + } + + const char* val = getenv(key); + free(key); + if (!val) return -1; + + errno = 0; + long fd = strtol(val, NULL, 10); + if (errno) return -1; + + // validity checking + if ((fd < 0) || (fd > INT_MAX)) return -1; + + // Since we are inheriting an fd, it could legitimately exceed _SC_OPEN_MAX + + // Still open? +#if defined(F_GETFD) // Linux lowest overhead + if (TEMP_FAILURE_RETRY(fcntl(fd, F_GETFD)) < 0) return -1; +#elif defined(F_GETFL) // Mac host lowest overhead + if (fcntl(fd, F_GETFL) < 0) return -1; +#else // Hail Mary pass + struct stat s; + if (fstat(fd, &s) < 0) return -1; +#endif + + return static_cast<int>(fd); +} + +int android_get_control_file(const char* path) { + int fd = __android_get_control_from_env(ANDROID_FILE_ENV_PREFIX, path); + +#if defined(__linux__) + // Find file path from /proc and make sure it is correct + char *proc = NULL; + if (asprintf(&proc, "/proc/self/fd/%d", fd) < 0) return -1; + if (!proc) return -1; + + size_t len = strlen(path); + // readlink() does not guarantee a nul byte, len+2 so we catch truncation. + char *buf = static_cast<char *>(calloc(1, len + 2)); + if (!buf) { + free(proc); + return -1; + } + ssize_t ret = TEMP_FAILURE_RETRY(readlink(proc, buf, len + 1)); + free(proc); + int cmp = (len != static_cast<size_t>(ret)) || strcmp(buf, path); + free(buf); + if (ret < 0) return -1; + if (cmp != 0) return -1; + // It is what we think it is +#endif + + return fd; +} |