xref: /qemu/linux-user/fd-trans.h (revision d759a62b)
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