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