diff --git a/adb/adb_unique_fd.h b/adb/adb_unique_fd.h index 9c02cbeec..7d2354d0e 100644 --- a/adb/adb_unique_fd.h +++ b/adb/adb_unique_fd.h @@ -28,11 +28,38 @@ struct AdbCloser { using unique_fd = android::base::unique_fd_impl; #if !defined(_WIN32) -inline bool Pipe(unique_fd* read, unique_fd* write) { +inline bool Pipe(unique_fd* read, unique_fd* write, int flags = 0) { int pipefd[2]; +#if !defined(__APPLE__) + if (pipe2(pipefd, flags) != 0) { + return false; + } +#else + // Darwin doesn't have pipe2. Implement it ourselves. + if (flags != 0 && (flags & ~(O_CLOEXEC | O_NONBLOCK)) != 0) { + errno = EINVAL; + return false; + } + if (pipe(pipefd) != 0) { return false; } + + if (flags & O_CLOEXEC) { + if (fcntl(pipefd[0], F_SETFD, FD_CLOEXEC) != 0 || + fcntl(pipefd[1], F_SETFD, FD_CLOEXEC) != 0) { + PLOG(FATAL) << "failed to set FD_CLOEXEC on newly created pipe"; + } + } + + if (flags & O_NONBLOCK) { + if (fcntl(pipefd[0], F_SETFL, O_NONBLOCK) != 0 || + fcntl(pipefd[1], F_SETFL, O_NONBLOCK) != 0) { + PLOG(FATAL) << "failed to set O_NONBLOCK on newly created pipe"; + } + } +#endif + read->reset(pipefd[0]); write->reset(pipefd[1]); return true;