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