blob: 429b3fea7d7a4c4870044697aa5449b33e676bc8 [file] [log] [blame]
Lingfeng Yang88c170c2016-11-30 00:52:35 +00001/*
bohu104a7422017-02-24 22:42:03 -08002 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#ifndef ANDROID_INCLUDE_HARDWARE_QEMU_PIPE_H
17#define ANDROID_INCLUDE_HARDWARE_QEMU_PIPE_H
18
Lingfeng Yange38d15c2018-09-24 16:24:01 -070019#ifdef HOST_BUILD
20
21#include <sys/types.h>
22
23typedef void* QEMU_PIPE_HANDLE;
24
Weilun Du8b38e8b2018-10-03 10:25:21 -070025#define QEMU_PIPE_INVALID_HANDLE NULL
26
Lingfeng Yange38d15c2018-09-24 16:24:01 -070027QEMU_PIPE_HANDLE qemu_pipe_open(const char* pipeName);
28void qemu_pipe_close(QEMU_PIPE_HANDLE pipe);
29
30ssize_t qemu_pipe_read(QEMU_PIPE_HANDLE pipe, void* buffer, size_t len);
31ssize_t qemu_pipe_write(QEMU_PIPE_HANDLE pipe, const void* buffer, size_t len);
32
33bool qemu_pipe_try_again();
34bool qemu_pipe_valid(QEMU_PIPE_HANDLE pipe);
35
36void qemu_pipe_print_error(QEMU_PIPE_HANDLE pipe);
37
38#else
39
40typedef int QEMU_PIPE_HANDLE;
41
Weilun Du8b38e8b2018-10-03 10:25:21 -070042#define QEMU_PIPE_INVALID_HANDLE (-1)
43
David Reveman74e99bb2019-02-15 18:47:25 -050044#ifndef QEMU_PIPE_PATH
45#define QEMU_PIPE_PATH "/dev/qemu_pipe"
46#endif
47
48#ifndef TEMP_FAILURE_RETRY
49#define TEMP_FAILURE_RETRY(exp) ({ \
50 __typeof__(exp) _rc; \
51 do { \
52 _rc = (exp); \
53 } while (_rc == -1 && errno == EINTR); \
54 _rc; })
55#include <stdint.h>
56#endif
57
Luca Stefani1cb647a2019-03-07 21:58:17 +010058#if PLATFORM_SDK_VERSION < 26
Lingfeng Yange38d15c2018-09-24 16:24:01 -070059#include <cutils/log.h>
Luca Stefani1cb647a2019-03-07 21:58:17 +010060#else
61#include <log/log.h>
62#endif
David Reveman74e99bb2019-02-15 18:47:25 -050063#ifdef __ANDROID__
bohu104a7422017-02-24 22:42:03 -080064#include <sys/cdefs.h>
David Reveman74e99bb2019-02-15 18:47:25 -050065#endif
bohu104a7422017-02-24 22:42:03 -080066#include <unistd.h>
67#include <fcntl.h>
68#include <sys/mman.h>
69#include <pthread.h> /* for pthread_once() */
70#include <stdlib.h>
71#include <stdio.h>
72#include <string.h>
73#include <errno.h>
74
75#ifndef D
76# define D(...) do{}while(0)
77#endif
78
Lingfeng Yange38d15c2018-09-24 16:24:01 -070079static bool WriteFully(QEMU_PIPE_HANDLE fd, const void* data, size_t byte_count) {
bohu104a7422017-02-24 22:42:03 -080080 const uint8_t* p = (const uint8_t*)(data);
81 size_t remaining = byte_count;
82 while (remaining > 0) {
83 ssize_t n = TEMP_FAILURE_RETRY(write(fd, p, remaining));
84 if (n == -1) return false;
85 p += n;
86 remaining -= n;
87 }
88 return true;
89}
90
91/* Try to open a new Qemu fast-pipe. This function returns a file descriptor
92 * that can be used to communicate with a named service managed by the
93 * emulator.
94 *
95 * This file descriptor can be used as a standard pipe/socket descriptor.
96 *
97 * 'pipeName' is the name of the emulator service you want to connect to.
98 * E.g. 'opengles' or 'camera'.
99 *
100 * On success, return a valid file descriptor
101 * Returns -1 on error, and errno gives the error code, e.g.:
102 *
103 * EINVAL -> unknown/unsupported pipeName
104 * ENOSYS -> fast pipes not available in this system.
105 *
106 * ENOSYS should never happen, except if you're trying to run within a
107 * misconfigured emulator.
108 *
109 * You should be able to open several pipes to the same pipe service,
110 * except for a few special cases (e.g. GSM modem), where EBUSY will be
111 * returned if more than one client tries to connect to it.
112 */
Lingfeng Yange38d15c2018-09-24 16:24:01 -0700113static __inline__ QEMU_PIPE_HANDLE
114qemu_pipe_open(const char* pipeName) {
bohu104a7422017-02-24 22:42:03 -0800115 char buff[256];
116 int buffLen;
Lingfeng Yange38d15c2018-09-24 16:24:01 -0700117 QEMU_PIPE_HANDLE fd;
bohu104a7422017-02-24 22:42:03 -0800118
119 if (pipeName == NULL || pipeName[0] == '\0') {
120 errno = EINVAL;
121 return -1;
122 }
123
124 snprintf(buff, sizeof buff, "pipe:%s", pipeName);
125
David Reveman74e99bb2019-02-15 18:47:25 -0500126 fd = TEMP_FAILURE_RETRY(open(QEMU_PIPE_PATH, O_RDWR));
bohu104a7422017-02-24 22:42:03 -0800127 if (fd < 0 && errno == ENOENT)
128 fd = TEMP_FAILURE_RETRY(open("/dev/goldfish_pipe", O_RDWR));
129 if (fd < 0) {
David Reveman74e99bb2019-02-15 18:47:25 -0500130 D("%s: Could not open " QEMU_PIPE_PATH ": %s", __FUNCTION__, strerror(errno));
bohu104a7422017-02-24 22:42:03 -0800131 //errno = ENOSYS;
132 return -1;
133 }
134
135 buffLen = strlen(buff);
136
137 if (!WriteFully(fd, buff, buffLen + 1)) {
138 D("%s: Could not connect to %s pipe service: %s", __FUNCTION__, pipeName, strerror(errno));
139 return -1;
140 }
141
142 return fd;
143}
144
Lingfeng Yange38d15c2018-09-24 16:24:01 -0700145static __inline__ void
146qemu_pipe_close(QEMU_PIPE_HANDLE pipe) {
147 close(pipe);
148}
149
150static __inline__ ssize_t
151qemu_pipe_read(QEMU_PIPE_HANDLE pipe, void* buffer, size_t len) {
152 return read(pipe, buffer, len);
153}
154
155static __inline__ ssize_t
156qemu_pipe_write(QEMU_PIPE_HANDLE pipe, const void* buffer, size_t len) {
157 return write(pipe, buffer, len);
158}
159
160static __inline__ bool
161qemu_pipe_try_again() {
162 return errno == EINTR;
163}
164
165static __inline__ bool
166qemu_pipe_valid(QEMU_PIPE_HANDLE pipe) {
167 return pipe >= 0;
168}
169
170static __inline__ void
171qemu_pipe_print_error(QEMU_PIPE_HANDLE pipe) {
172 ALOGE("pipe error: fd %d errno %d", pipe, errno);
173}
174
175#endif // !HOST_BUILD
176
bohu104a7422017-02-24 22:42:03 -0800177#endif /* ANDROID_INCLUDE_HARDWARE_QEMU_PIPE_H */