diff options
author | Mark Salyzyn <salyzyn@google.com> | 2016-11-17 15:33:02 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2016-11-17 15:33:02 +0000 |
commit | 809dee506e000bea8aab462611e3cff016ac77ff (patch) | |
tree | d74cd0442b6c801fab6e85d7b00b08d4cdc73e73 /libcutils | |
parent | f5964b5cf9fdf8ea4b174310e0000372f96ae88e (diff) | |
parent | 8c41e791ed726449bd51a35f03dd6269274668c0 (diff) | |
download | core-809dee506e000bea8aab462611e3cff016ac77ff.tar.gz core-809dee506e000bea8aab462611e3cff016ac77ff.tar.bz2 core-809dee506e000bea8aab462611e3cff016ac77ff.zip |
Merge "libcutils: move cutils/files.h to cutils/android_get_control_file.h"
am: 8c41e791ed
Change-Id: Ifbc00285da734859d590153a7c6cfc8e51c014f9
Diffstat (limited to 'libcutils')
-rw-r--r-- | libcutils/Android.bp | 2 | ||||
-rw-r--r-- | libcutils/android_get_control_env.h | 33 | ||||
-rw-r--r-- | libcutils/android_get_control_file.cpp (renamed from libcutils/files.cpp) | 52 | ||||
-rw-r--r-- | libcutils/klog.cpp | 2 | ||||
-rw-r--r-- | libcutils/sockets.cpp | 79 | ||||
-rw-r--r-- | libcutils/sockets_unix.cpp | 29 | ||||
-rw-r--r-- | libcutils/sockets_windows.cpp | 4 | ||||
-rw-r--r-- | libcutils/tests/Android.bp | 8 | ||||
-rw-r--r-- | libcutils/tests/android_get_control_file_test.cpp (renamed from libcutils/tests/files_test.cpp) | 36 | ||||
-rw-r--r-- | libcutils/tests/android_get_control_socket_test.cpp | 71 | ||||
-rw-r--r-- | libcutils/tests/sockets_test.cpp | 50 |
11 files changed, 191 insertions, 175 deletions
diff --git a/libcutils/Android.bp b/libcutils/Android.bp index f7b497d9d..39f8aba8e 100644 --- a/libcutils/Android.bp +++ b/libcutils/Android.bp @@ -18,6 +18,7 @@ // they correspond to features not used by our host development tools // which are also hard or even impossible to port to native Win32 libcutils_nonwindows_sources = [ + "android_get_control_file.cpp", "fs.c", "multiuser.c", "socket_inaddr_any_server_unix.c", @@ -34,7 +35,6 @@ cc_library { host_supported: true, srcs: [ "config_utils.c", - "files.cpp", "fs_config.c", "canned_fs_config.c", "hashmap.c", diff --git a/libcutils/android_get_control_env.h b/libcutils/android_get_control_env.h new file mode 100644 index 000000000..638c8318a --- /dev/null +++ b/libcutils/android_get_control_env.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CUTILS_ANDROID_GET_CONTROL_ENV_H +#define __CUTILS_ANDROID_GET_CONTROL_ENV_H + +/* To declare library function hidden and internal */ +#define LIBCUTILS_HIDDEN __attribute__((visibility("hidden"))) + +#ifdef __cplusplus +extern "C" { +#endif + +LIBCUTILS_HIDDEN int __android_get_control_from_env(const char* prefix, + const char* name); +#ifdef __cplusplus +} +#endif + +#endif /* __CUTILS_ANDROID_GET_CONTROL_ENV_H */ diff --git a/libcutils/files.cpp b/libcutils/android_get_control_file.cpp index bf15b4283..496fbbfe6 100644 --- a/libcutils/files.cpp +++ b/libcutils/android_get_control_file.cpp @@ -25,11 +25,6 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ - -// This file contains files implementation that can be shared between -// platforms as long as the correct headers are included. -#define _GNU_SOURCE 1 // for asprintf - #include <ctype.h> #include <errno.h> #include <fcntl.h> @@ -41,17 +36,16 @@ #include <sys/types.h> #include <unistd.h> -#include <cutils/files.h> +#include <cutils/android_get_control_file.h> -#ifndef TEMP_FAILURE_RETRY // _WIN32 does not define -#define TEMP_FAILURE_RETRY(exp) (exp) -#endif +#include "android_get_control_env.h" -int android_get_control_file(const char* path) { - if (!path) return -1; +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, ANDROID_FILE_ENV_PREFIX "%s", path) < 0) return -1; + if (asprintf(&key, "%s%s", prefix, name) < 0) return -1; if (!key) return -1; char *cp = key; @@ -70,29 +64,33 @@ int android_get_control_file(const char* path) { // validity checking if ((fd < 0) || (fd > INT_MAX)) return -1; -#if defined(_SC_OPEN_MAX) - if (fd >= sysconf(_SC_OPEN_MAX)) return -1; -#elif defined(OPEN_MAX) - if (fd >= OPEN_MAX) return -1; -#elif defined(_POSIX_OPEN_MAX) - if (fd >= _POSIX_OPEN_MAX) return -1; -#endif -#if defined(F_GETFD) + // 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) - if (TEMP_FAILURE_RETRY(fcntl(fd, F_GETFL)) < 0) return -1; -#else +#elif defined(F_GETFL) // Mac host lowest overhead + if (fcntl(fd, F_GETFL) < 0) return -1; +#else // Hail Mary pass struct stat s; - if (TEMP_FAILURE_RETRY(fstat(fd, &s)) < 0) return -1; + 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/%ld", fd) < 0) return -1; + 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); @@ -104,8 +102,8 @@ int android_get_control_file(const char* path) { free(buf); if (ret < 0) return -1; if (cmp != 0) return -1; + // It is what we think it is #endif - // It is what we think it is - return static_cast<int>(fd); + return fd; } diff --git a/libcutils/klog.cpp b/libcutils/klog.cpp index 9d823cfae..4bad28a57 100644 --- a/libcutils/klog.cpp +++ b/libcutils/klog.cpp @@ -24,7 +24,7 @@ #include <sys/types.h> #include <unistd.h> -#include <cutils/files.h> +#include <cutils/android_get_control_file.h> #include <cutils/klog.h> static int klog_level = KLOG_DEFAULT_LEVEL; diff --git a/libcutils/sockets.cpp b/libcutils/sockets.cpp index 63761a2c5..23a447be8 100644 --- a/libcutils/sockets.cpp +++ b/libcutils/sockets.cpp @@ -28,33 +28,9 @@ // This file contains socket implementation that can be shared between // platforms as long as the correct headers are included. -#define _GNU_SOURCE 1 // For asprintf - -#include <ctype.h> -#include <errno.h> -#include <fcntl.h> -#include <limits.h> -#if !defined(_WIN32) -#include <netinet/in.h> -#endif -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/stat.h> -#include <sys/types.h> -#if !defined(_WIN32) -#include <sys/un.h> -#endif -#include <unistd.h> - -#include <string> #include <cutils/sockets.h> -#ifndef TEMP_FAILURE_RETRY // _WIN32 does not define -#define TEMP_FAILURE_RETRY(exp) (exp) -#endif - int socket_get_local_port(cutils_socket_t sock) { sockaddr_storage addr; socklen_t addr_size = sizeof(addr); @@ -65,58 +41,3 @@ int socket_get_local_port(cutils_socket_t sock) { } return -1; } - -int android_get_control_socket(const char* name) { - char *key = NULL; - if (asprintf(&key, ANDROID_SOCKET_ENV_PREFIX "%s", 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; -#if defined(_SC_OPEN_MAX) - if (fd >= sysconf(_SC_OPEN_MAX)) return -1; -#elif defined(OPEN_MAX) - if (fd >= OPEN_MAX) return -1; -#elif defined(_POSIX_OPEN_MAX) - if (fd >= _POSIX_OPEN_MAX) return -1; -#endif - -#if defined(F_GETFD) - if (TEMP_FAILURE_RETRY(fcntl(fd, F_GETFD)) < 0) return -1; -#elif defined(F_GETFL) - if (TEMP_FAILURE_RETRY(fcntl(fd, F_GETFL)) < 0) return -1; -#else - struct stat s; - if (TEMP_FAILURE_RETRY(fstat(fd, &s)) < 0) return -1; -#endif - -#if !defined(_WIN32) - struct sockaddr_un addr; - socklen_t addrlen = sizeof(addr); - int ret = TEMP_FAILURE_RETRY(getsockname(fd, (struct sockaddr *)&addr, &addrlen)); - if (ret < 0) return -1; - char *path = NULL; - if (asprintf(&path, ANDROID_SOCKET_DIR"/%s", name) < 0) return -1; - if (!path) return -1; - int cmp = strcmp(addr.sun_path, path); - free(path); - if (cmp != 0) return -1; -#endif - - // It is what we think it is - return static_cast<int>(fd); -} diff --git a/libcutils/sockets_unix.cpp b/libcutils/sockets_unix.cpp index 3545403aa..948d09c60 100644 --- a/libcutils/sockets_unix.cpp +++ b/libcutils/sockets_unix.cpp @@ -16,13 +16,21 @@ #define LOG_TAG "socket-unix" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/socket.h> #include <sys/uio.h> +#include <sys/un.h> #include <time.h> #include <unistd.h> #include <android/log.h> +#include <cutils/android_get_control_file.h> #include <cutils/sockets.h> +#include "android_get_control_env.h" + #if defined(__ANDROID__) /* For the socket trust (credentials) check */ #include <private/android_filesystem_config.h> @@ -80,3 +88,24 @@ ssize_t socket_send_buffers(cutils_socket_t sock, return writev(sock, iovec_buffers, num_buffers); } + +int android_get_control_socket(const char* name) { + int fd = __android_get_control_from_env(ANDROID_SOCKET_ENV_PREFIX, name); + + if (fd < 0) return fd; + + // Compare to UNIX domain socket name, must match! + struct sockaddr_un addr; + socklen_t addrlen = sizeof(addr); + int ret = TEMP_FAILURE_RETRY(getsockname(fd, (struct sockaddr *)&addr, &addrlen)); + if (ret < 0) return -1; + char *path = NULL; + if (asprintf(&path, ANDROID_SOCKET_DIR "/%s", name) < 0) return -1; + if (!path) return -1; + int cmp = strcmp(addr.sun_path, path); + free(path); + if (cmp != 0) return -1; + + // It is what we think it is + return fd; +} diff --git a/libcutils/sockets_windows.cpp b/libcutils/sockets_windows.cpp index ed6b1a781..3064c70e5 100644 --- a/libcutils/sockets_windows.cpp +++ b/libcutils/sockets_windows.cpp @@ -84,3 +84,7 @@ ssize_t socket_send_buffers(cutils_socket_t sock, return -1; } + +int android_get_control_socket(const char* name) { + return -1; +} diff --git a/libcutils/tests/Android.bp b/libcutils/tests/Android.bp index bd354129d..72e2eace5 100644 --- a/libcutils/tests/Android.bp +++ b/libcutils/tests/Android.bp @@ -14,7 +14,7 @@ cc_defaults { name: "libcutils_test_default", - srcs: ["sockets_test.cpp", "files_test.cpp"], + srcs: ["sockets_test.cpp"], target: { android: { @@ -28,7 +28,11 @@ cc_defaults { }, not_windows: { - srcs: ["test_str_parms.cpp"], + srcs: [ + "test_str_parms.cpp", + "android_get_control_socket_test.cpp", + "android_get_control_file_test.cpp" + ], }, }, diff --git a/libcutils/tests/files_test.cpp b/libcutils/tests/android_get_control_file_test.cpp index 1a7d67386..6c6fd2ad2 100644 --- a/libcutils/tests/files_test.cpp +++ b/libcutils/tests/android_get_control_file_test.cpp @@ -14,33 +14,37 @@ * limitations under the License. */ +#include <ctype.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <time.h> -#include <cutils/files.h> +#include <string> + +#include <android-base/stringprintf.h> +#include <android-base/test_utils.h> +#include <cutils/android_get_control_file.h> #include <gtest/gtest.h> TEST(FilesTest, android_get_control_file) { - static const char key[] = ANDROID_FILE_ENV_PREFIX "_dev_kmsg"; - static const char name[] = "/dev/kmsg"; + TemporaryFile tf; + ASSERT_GE(tf.fd, 0); + + std::string key(ANDROID_FILE_ENV_PREFIX); + key += tf.path; - EXPECT_EQ(unsetenv(key), 0); - EXPECT_EQ(android_get_control_file(name), -1); + std::for_each(key.begin(), key.end(), [] (char& c) { c = isalnum(c) ? c : '_'; }); - int fd; - ASSERT_GE(fd = open(name, O_RDONLY | O_CLOEXEC), 0); - EXPECT_EQ(android_get_control_file(name), -1); + EXPECT_EQ(unsetenv(key.c_str()), 0); + EXPECT_EQ(android_get_control_file(tf.path), -1); - char val[32]; - snprintf(val, sizeof(val), "%d", fd); - EXPECT_EQ(setenv(key, val, true), 0); + EXPECT_EQ(setenv(key.c_str(), android::base::StringPrintf("%d", tf.fd).c_str(), true), 0); - EXPECT_EQ(android_get_control_file(name), fd); - close(fd); - EXPECT_EQ(android_get_control_file(name), -1); - EXPECT_EQ(unsetenv(key), 0); - EXPECT_EQ(android_get_control_file(name), -1); + EXPECT_EQ(android_get_control_file(tf.path), tf.fd); + close(tf.fd); + EXPECT_EQ(android_get_control_file(tf.path), -1); + EXPECT_EQ(unsetenv(key.c_str()), 0); + EXPECT_EQ(android_get_control_file(tf.path), -1); } diff --git a/libcutils/tests/android_get_control_socket_test.cpp b/libcutils/tests/android_get_control_socket_test.cpp new file mode 100644 index 000000000..e58674864 --- /dev/null +++ b/libcutils/tests/android_get_control_socket_test.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <sys/un.h> +#include <time.h> + +#include <cutils/sockets.h> +#include <gtest/gtest.h> + +#ifndef SOCK_NONBLOCK +#define SOCK_NONBLOCK 0 +#endif + +#ifndef SOCK_CLOEXEC +#define SOCK_CLOEXEC 0 +#endif + +TEST(SocketsTest, android_get_control_socket) { + static const char key[] = ANDROID_SOCKET_ENV_PREFIX "SocketsTest_android_get_control_socket"; + static const char* name = key + strlen(ANDROID_SOCKET_ENV_PREFIX); + + EXPECT_EQ(unsetenv(key), 0); + EXPECT_EQ(android_get_control_socket(name), -1); + + int fd; + ASSERT_GE(fd = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0), 0); +#ifdef F_GETFL + int flags; + ASSERT_GE(flags = fcntl(fd, F_GETFL), 0); + ASSERT_GE(fcntl(fd, F_SETFL, flags | O_NONBLOCK), 0); +#endif + EXPECT_EQ(android_get_control_socket(name), -1); + + struct sockaddr_un addr; + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + snprintf(addr.sun_path, sizeof(addr.sun_path), ANDROID_SOCKET_DIR"/%s", name); + unlink(addr.sun_path); + + EXPECT_EQ(bind(fd, (struct sockaddr*)&addr, sizeof(addr)), 0); + EXPECT_EQ(android_get_control_socket(name), -1); + + char val[32]; + snprintf(val, sizeof(val), "%d", fd); + EXPECT_EQ(setenv(key, val, true), 0); + + EXPECT_EQ(android_get_control_socket(name), fd); + socket_close(fd); + EXPECT_EQ(android_get_control_socket(name), -1); + EXPECT_EQ(unlink(addr.sun_path), 0); + EXPECT_EQ(android_get_control_socket(name), -1); + EXPECT_EQ(unsetenv(key), 0); + EXPECT_EQ(android_get_control_socket(name), -1); +} diff --git a/libcutils/tests/sockets_test.cpp b/libcutils/tests/sockets_test.cpp index adfbf4ad3..0441fb636 100644 --- a/libcutils/tests/sockets_test.cpp +++ b/libcutils/tests/sockets_test.cpp @@ -18,11 +18,9 @@ // IPv6 capabilities. These tests assume that no UDP packets are lost, which // should be the case for loopback communication, but is not guaranteed. -#include <stdio.h> -#include <stdlib.h> +#include <string.h> #include <sys/socket.h> #include <sys/types.h> -#include <sys/un.h> #include <time.h> #include <cutils/sockets.h> @@ -189,49 +187,3 @@ TEST(SocketsTest, TestTcpReceiveTimeout) { TEST(SocketsTest, TestSocketSendBuffersFailure) { EXPECT_EQ(-1, socket_send_buffers(INVALID_SOCKET, nullptr, 0)); } - -#ifndef SOCK_NONBLOCK -#define SOCK_NONBLOCK 0 -#endif - -#ifndef SOCK_CLOEXEC -#define SOCK_CLOEXEC 0 -#endif - -TEST(SocketsTest, android_get_control_socket) { - static const char key[] = ANDROID_SOCKET_ENV_PREFIX "SocketsTest_android_get_control_socket"; - static const char* name = key + strlen(ANDROID_SOCKET_ENV_PREFIX); - - EXPECT_EQ(unsetenv(key), 0); - EXPECT_EQ(android_get_control_socket(name), -1); - - int fd; - ASSERT_GE(fd = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0), 0); -#ifdef F_GETFL - int flags; - ASSERT_GE(flags = fcntl(fd, F_GETFL), 0); - ASSERT_GE(fcntl(fd, F_SETFL, flags | O_NONBLOCK), 0); -#endif - EXPECT_EQ(android_get_control_socket(name), -1); - - struct sockaddr_un addr; - memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - snprintf(addr.sun_path, sizeof(addr.sun_path), ANDROID_SOCKET_DIR"/%s", name); - unlink(addr.sun_path); - - EXPECT_EQ(bind(fd, (struct sockaddr*)&addr, sizeof(addr)), 0); - EXPECT_EQ(android_get_control_socket(name), -1); - - char val[32]; - snprintf(val, sizeof(val), "%d", fd); - EXPECT_EQ(setenv(key, val, true), 0); - - EXPECT_EQ(android_get_control_socket(name), fd); - socket_close(fd); - EXPECT_EQ(android_get_control_socket(name), -1); - EXPECT_EQ(unlink(addr.sun_path), 0); - EXPECT_EQ(android_get_control_socket(name), -1); - EXPECT_EQ(unsetenv(key), 0); - EXPECT_EQ(android_get_control_socket(name), -1); -} |