/* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef FD_TRANS_H #define FD_TRANS_H typedef abi_long (*TargetFdDataFunc)(void *, size_t); typedef abi_long (*TargetFdAddrFunc)(void *, abi_ulong, socklen_t); typedef struct TargetFdTrans { TargetFdDataFunc host_to_target_data; TargetFdDataFunc target_to_host_data; TargetFdAddrFunc target_to_host_addr; } TargetFdTrans; extern TargetFdTrans **target_fd_trans; extern unsigned int target_fd_max; static inline TargetFdDataFunc fd_trans_target_to_host_data(int fd) { if (fd >= 0 && fd < target_fd_max && target_fd_trans[fd]) { return target_fd_trans[fd]->target_to_host_data; } return NULL; } static inline TargetFdDataFunc fd_trans_host_to_target_data(int fd) { if (fd >= 0 && fd < target_fd_max && target_fd_trans[fd]) { return target_fd_trans[fd]->host_to_target_data; } return NULL; } static inline TargetFdAddrFunc fd_trans_target_to_host_addr(int fd) { if (fd >= 0 && fd < target_fd_max && target_fd_trans[fd]) { return target_fd_trans[fd]->target_to_host_addr; } return NULL; } static inline void fd_trans_register(int fd, TargetFdTrans *trans) { unsigned int oldmax; if (fd >= target_fd_max) { oldmax = target_fd_max; target_fd_max = ((fd >> 6) + 1) << 6; /* by slice of 64 entries */ target_fd_trans = g_renew(TargetFdTrans *, target_fd_trans, target_fd_max); memset((void *)(target_fd_trans + oldmax), 0, (target_fd_max - oldmax) * sizeof(TargetFdTrans *)); } target_fd_trans[fd] = trans; } static inline void fd_trans_unregister(int fd) { if (fd >= 0 && fd < target_fd_max) { target_fd_trans[fd] = NULL; } } static inline void fd_trans_dup(int oldfd, int newfd) { fd_trans_unregister(newfd); if (oldfd < target_fd_max && target_fd_trans[oldfd]) { fd_trans_register(newfd, target_fd_trans[oldfd]); } } extern TargetFdTrans target_packet_trans; #ifdef CONFIG_RTNETLINK extern TargetFdTrans target_netlink_route_trans; #endif extern TargetFdTrans target_netlink_audit_trans; extern TargetFdTrans target_signalfd_trans; extern TargetFdTrans target_eventfd_trans; #if (defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)) || \ (defined(CONFIG_INOTIFY1) && defined(TARGET_NR_inotify_init1) && \ defined(__NR_inotify_init1)) extern TargetFdTrans target_inotify_trans; #endif #endif