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 | |
19 | typedef abi_long (*TargetFdDataFunc)(void *, size_t); |
20 | typedef abi_long (*TargetFdAddrFunc)(void *, abi_ulong, socklen_t); |
21 | typedef struct TargetFdTrans { |
22 | TargetFdDataFunc host_to_target_data; |
23 | TargetFdDataFunc target_to_host_data; |
24 | TargetFdAddrFunc target_to_host_addr; |
25 | } TargetFdTrans; |
26 | |
27 | extern TargetFdTrans **target_fd_trans; |
28 | |
29 | extern unsigned int target_fd_max; |
30 | |
31 | static inline TargetFdDataFunc fd_trans_target_to_host_data(int fd) |
32 | { |
33 | if (fd >= 0 && fd < target_fd_max && target_fd_trans[fd]) { |
34 | return target_fd_trans[fd]->target_to_host_data; |
35 | } |
36 | return NULL; |
37 | } |
38 | |
39 | static inline TargetFdDataFunc fd_trans_host_to_target_data(int fd) |
40 | { |
41 | if (fd >= 0 && fd < target_fd_max && target_fd_trans[fd]) { |
42 | return target_fd_trans[fd]->host_to_target_data; |
43 | } |
44 | return NULL; |
45 | } |
46 | |
47 | static inline TargetFdAddrFunc fd_trans_target_to_host_addr(int fd) |
48 | { |
49 | if (fd >= 0 && fd < target_fd_max && target_fd_trans[fd]) { |
50 | return target_fd_trans[fd]->target_to_host_addr; |
51 | } |
52 | return NULL; |
53 | } |
54 | |
55 | static inline void fd_trans_register(int fd, TargetFdTrans *trans) |
56 | { |
57 | unsigned int oldmax; |
58 | |
59 | if (fd >= target_fd_max) { |
60 | oldmax = target_fd_max; |
61 | target_fd_max = ((fd >> 6) + 1) << 6; /* by slice of 64 entries */ |
62 | target_fd_trans = g_renew(TargetFdTrans *, |
63 | target_fd_trans, target_fd_max); |
64 | memset((void *)(target_fd_trans + oldmax), 0, |
65 | (target_fd_max - oldmax) * sizeof(TargetFdTrans *)); |
66 | } |
67 | target_fd_trans[fd] = trans; |
68 | } |
69 | |
70 | static inline void fd_trans_unregister(int fd) |
71 | { |
72 | if (fd >= 0 && fd < target_fd_max) { |
73 | target_fd_trans[fd] = NULL; |
74 | } |
75 | } |
76 | |
77 | static inline void fd_trans_dup(int oldfd, int newfd) |
78 | { |
79 | fd_trans_unregister(newfd); |
80 | if (oldfd < target_fd_max && target_fd_trans[oldfd]) { |
81 | fd_trans_register(newfd, target_fd_trans[oldfd]); |
82 | } |
83 | } |
84 | |
85 | extern TargetFdTrans target_packet_trans; |
86 | #ifdef CONFIG_RTNETLINK |
87 | extern TargetFdTrans target_netlink_route_trans; |
88 | #endif |
89 | extern TargetFdTrans target_netlink_audit_trans; |
90 | extern TargetFdTrans target_signalfd_trans; |
91 | extern TargetFdTrans target_eventfd_trans; |
92 | #if (defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)) || \ |
93 | (defined(CONFIG_INOTIFY1) && defined(TARGET_NR_inotify_init1) && \ |
94 | defined(__NR_inotify_init1)) |
95 | extern TargetFdTrans target_inotify_trans; |
96 | #endif |
97 | #endif |
98 | |