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