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; }
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; }