]>
Commit | Line | Data |
---|---|---|
f7e6a401 LV |
1 | /* |
2 | * This program is free software; you can redistribute it and/or modify | |
3 | * it under the terms of the GNU General Public License as published by | |
4 | * the Free Software Foundation; either version 2 of the License, or | |
5 | * (at your option) any later version. | |
6 | * | |
7 | * This program is distributed in the hope that it will be useful, | |
8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
10 | * GNU General Public License for more details. | |
11 | * | |
12 | * You should have received a copy of the GNU General Public License | |
13 | * along with this program; if not, see <http://www.gnu.org/licenses/>. | |
14 | */ | |
15 | ||
16 | #ifndef FD_TRANS_H | |
17 | #define FD_TRANS_H | |
18 | ||
c093364f OA |
19 | #include "qemu/lockable.h" |
20 | ||
f7e6a401 LV |
21 | typedef abi_long (*TargetFdDataFunc)(void *, size_t); |
22 | typedef abi_long (*TargetFdAddrFunc)(void *, abi_ulong, socklen_t); | |
23 | typedef struct TargetFdTrans { | |
24 | TargetFdDataFunc host_to_target_data; | |
25 | TargetFdDataFunc target_to_host_data; | |
26 | TargetFdAddrFunc target_to_host_addr; | |
27 | } TargetFdTrans; | |
28 | ||
29 | extern TargetFdTrans **target_fd_trans; | |
c093364f | 30 | extern QemuMutex target_fd_trans_lock; |
f7e6a401 LV |
31 | |
32 | extern unsigned int target_fd_max; | |
33 | ||
c093364f OA |
34 | static inline void fd_trans_init(void) |
35 | { | |
36 | qemu_mutex_init(&target_fd_trans_lock); | |
37 | } | |
38 | ||
f7e6a401 LV |
39 | static inline TargetFdDataFunc fd_trans_target_to_host_data(int fd) |
40 | { | |
c093364f OA |
41 | if (fd < 0) { |
42 | return NULL; | |
43 | } | |
44 | ||
45 | QEMU_LOCK_GUARD(&target_fd_trans_lock); | |
46 | if (fd < target_fd_max && target_fd_trans[fd]) { | |
f7e6a401 LV |
47 | return target_fd_trans[fd]->target_to_host_data; |
48 | } | |
49 | return NULL; | |
50 | } | |
51 | ||
52 | static inline TargetFdDataFunc fd_trans_host_to_target_data(int fd) | |
53 | { | |
c093364f OA |
54 | if (fd < 0) { |
55 | return NULL; | |
56 | } | |
57 | ||
58 | QEMU_LOCK_GUARD(&target_fd_trans_lock); | |
59 | if (fd < target_fd_max && target_fd_trans[fd]) { | |
f7e6a401 LV |
60 | return target_fd_trans[fd]->host_to_target_data; |
61 | } | |
62 | return NULL; | |
63 | } | |
64 | ||
65 | static inline TargetFdAddrFunc fd_trans_target_to_host_addr(int fd) | |
66 | { | |
c093364f OA |
67 | if (fd < 0) { |
68 | return NULL; | |
69 | } | |
70 | ||
71 | QEMU_LOCK_GUARD(&target_fd_trans_lock); | |
72 | if (fd < target_fd_max && target_fd_trans[fd]) { | |
f7e6a401 LV |
73 | return target_fd_trans[fd]->target_to_host_addr; |
74 | } | |
75 | return NULL; | |
76 | } | |
77 | ||
c093364f OA |
78 | static inline void internal_fd_trans_register_unsafe(int fd, |
79 | TargetFdTrans *trans) | |
f7e6a401 LV |
80 | { |
81 | unsigned int oldmax; | |
82 | ||
83 | if (fd >= target_fd_max) { | |
84 | oldmax = target_fd_max; | |
85 | target_fd_max = ((fd >> 6) + 1) << 6; /* by slice of 64 entries */ | |
86 | target_fd_trans = g_renew(TargetFdTrans *, | |
87 | target_fd_trans, target_fd_max); | |
88 | memset((void *)(target_fd_trans + oldmax), 0, | |
89 | (target_fd_max - oldmax) * sizeof(TargetFdTrans *)); | |
90 | } | |
91 | target_fd_trans[fd] = trans; | |
92 | } | |
93 | ||
c093364f OA |
94 | static inline void fd_trans_register(int fd, TargetFdTrans *trans) |
95 | { | |
96 | QEMU_LOCK_GUARD(&target_fd_trans_lock); | |
97 | internal_fd_trans_register_unsafe(fd, trans); | |
98 | } | |
99 | ||
100 | static inline void internal_fd_trans_unregister_unsafe(int fd) | |
f7e6a401 LV |
101 | { |
102 | if (fd >= 0 && fd < target_fd_max) { | |
103 | target_fd_trans[fd] = NULL; | |
104 | } | |
105 | } | |
106 | ||
c093364f OA |
107 | static inline void fd_trans_unregister(int fd) |
108 | { | |
109 | if (fd < 0) { | |
110 | return; | |
111 | } | |
112 | ||
113 | QEMU_LOCK_GUARD(&target_fd_trans_lock); | |
114 | internal_fd_trans_unregister_unsafe(fd); | |
115 | } | |
116 | ||
f7e6a401 LV |
117 | static inline void fd_trans_dup(int oldfd, int newfd) |
118 | { | |
c093364f OA |
119 | QEMU_LOCK_GUARD(&target_fd_trans_lock); |
120 | internal_fd_trans_unregister_unsafe(newfd); | |
f7e6a401 | 121 | if (oldfd < target_fd_max && target_fd_trans[oldfd]) { |
c093364f | 122 | internal_fd_trans_register_unsafe(newfd, target_fd_trans[oldfd]); |
f7e6a401 LV |
123 | } |
124 | } | |
125 | ||
126 | extern TargetFdTrans target_packet_trans; | |
127 | #ifdef CONFIG_RTNETLINK | |
128 | extern TargetFdTrans target_netlink_route_trans; | |
129 | #endif | |
130 | extern TargetFdTrans target_netlink_audit_trans; | |
131 | extern TargetFdTrans target_signalfd_trans; | |
132 | extern TargetFdTrans target_eventfd_trans; | |
133 | #if (defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)) || \ | |
134 | (defined(CONFIG_INOTIFY1) && defined(TARGET_NR_inotify_init1) && \ | |
135 | defined(__NR_inotify_init1)) | |
136 | extern TargetFdTrans target_inotify_trans; | |
137 | #endif | |
138 | #endif |