blob: 53aec97a083dde5f8d145c070652d2b7d8f71b47
1 | /* |
2 | * 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 | |
19 | #include <sys/cdefs.h> |
20 | #include <unistd.h> |
21 | #include <fcntl.h> |
22 | #include <sys/mman.h> |
23 | #include <pthread.h> /* for pthread_once() */ |
24 | #include <stdlib.h> |
25 | #include <stdio.h> |
26 | #include <string.h> |
27 | #include <errno.h> |
28 | |
29 | #ifndef D |
30 | # define D(...) do{}while(0) |
31 | #endif |
32 | |
33 | /* Try to open a new Qemu fast-pipe. This function returns a file descriptor |
34 | * that can be used to communicate with a named service managed by the |
35 | * emulator. |
36 | * |
37 | * This file descriptor can be used as a standard pipe/socket descriptor. |
38 | * |
39 | * 'pipeName' is the name of the emulator service you want to connect to. |
40 | * E.g. 'opengles' or 'camera'. |
41 | * |
42 | * On success, return a valid file descriptor |
43 | * Returns -1 on error, and errno gives the error code, e.g.: |
44 | * |
45 | * EINVAL -> unknown/unsupported pipeName |
46 | * ENOSYS -> fast pipes not available in this system. |
47 | * |
48 | * ENOSYS should never happen, except if you're trying to run within a |
49 | * misconfigured emulator. |
50 | * |
51 | * You should be able to open several pipes to the same pipe service, |
52 | * except for a few special cases (e.g. GSM modem), where EBUSY will be |
53 | * returned if more than one client tries to connect to it. |
54 | */ |
55 | static __inline__ int |
56 | qemu_pipe_open(const char* pipeName) |
57 | { |
58 | char buff[256]; |
59 | int buffLen; |
60 | int fd, ret; |
61 | |
62 | if (pipeName == NULL || pipeName[0] == '\0') { |
63 | errno = EINVAL; |
64 | return -1; |
65 | } |
66 | |
67 | snprintf(buff, sizeof buff, "pipe:%s", pipeName); |
68 | |
69 | fd = open("/dev/qemu_pipe", O_RDWR); |
70 | if (fd < 0 && errno == ENOENT) |
71 | fd = open("/dev/goldfish_pipe", O_RDWR); |
72 | if (fd < 0) { |
73 | D("%s: Could not open /dev/qemu_pipe: %s", __FUNCTION__, strerror(errno)); |
74 | //errno = ENOSYS; |
75 | return -1; |
76 | } |
77 | |
78 | buffLen = strlen(buff); |
79 | |
80 | ret = TEMP_FAILURE_RETRY(write(fd, buff, buffLen+1)); |
81 | if (ret != buffLen+1) { |
82 | D("%s: Could not connect to %s pipe service: %s", __FUNCTION__, pipeName, strerror(errno)); |
83 | if (ret == 0) { |
84 | errno = ECONNRESET; |
85 | } else if (ret > 0) { |
86 | errno = EINVAL; |
87 | } |
88 | return -1; |
89 | } |
90 | |
91 | return fd; |
92 | } |
93 | |
94 | #endif /* ANDROID_INCLUDE_HARDWARE_QEMUD_PIPE_H */ |
95 |