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 19*c093364fSOwen Anderson #include "qemu/lockable.h" 20*c093364fSOwen 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; 30*c093364fSOwen Anderson extern QemuMutex target_fd_trans_lock; 31f7e6a401SLaurent Vivier 32f7e6a401SLaurent Vivier extern unsigned int target_fd_max; 33f7e6a401SLaurent Vivier 34*c093364fSOwen Anderson static inline void fd_trans_init(void) 35*c093364fSOwen Anderson { 36*c093364fSOwen Anderson qemu_mutex_init(&target_fd_trans_lock); 37*c093364fSOwen Anderson } 38*c093364fSOwen Anderson 39f7e6a401SLaurent Vivier static inline TargetFdDataFunc fd_trans_target_to_host_data(int fd) 40f7e6a401SLaurent Vivier { 41*c093364fSOwen Anderson if (fd < 0) { 42*c093364fSOwen Anderson return NULL; 43*c093364fSOwen Anderson } 44*c093364fSOwen Anderson 45*c093364fSOwen Anderson QEMU_LOCK_GUARD(&target_fd_trans_lock); 46*c093364fSOwen 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 52f7e6a401SLaurent Vivier static inline TargetFdDataFunc fd_trans_host_to_target_data(int fd) 53f7e6a401SLaurent Vivier { 54*c093364fSOwen Anderson if (fd < 0) { 55*c093364fSOwen Anderson return NULL; 56*c093364fSOwen Anderson } 57*c093364fSOwen Anderson 58*c093364fSOwen Anderson QEMU_LOCK_GUARD(&target_fd_trans_lock); 59*c093364fSOwen 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 65f7e6a401SLaurent Vivier static inline TargetFdAddrFunc fd_trans_target_to_host_addr(int fd) 66f7e6a401SLaurent Vivier { 67*c093364fSOwen Anderson if (fd < 0) { 68*c093364fSOwen Anderson return NULL; 69*c093364fSOwen Anderson } 70*c093364fSOwen Anderson 71*c093364fSOwen Anderson QEMU_LOCK_GUARD(&target_fd_trans_lock); 72*c093364fSOwen 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 78*c093364fSOwen Anderson static inline void internal_fd_trans_register_unsafe(int fd, 79*c093364fSOwen 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 94*c093364fSOwen Anderson static inline void fd_trans_register(int fd, TargetFdTrans *trans) 95*c093364fSOwen Anderson { 96*c093364fSOwen Anderson QEMU_LOCK_GUARD(&target_fd_trans_lock); 97*c093364fSOwen Anderson internal_fd_trans_register_unsafe(fd, trans); 98*c093364fSOwen Anderson } 99*c093364fSOwen Anderson 100*c093364fSOwen 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 107*c093364fSOwen Anderson static inline void fd_trans_unregister(int fd) 108*c093364fSOwen Anderson { 109*c093364fSOwen Anderson if (fd < 0) { 110*c093364fSOwen Anderson return; 111*c093364fSOwen Anderson } 112*c093364fSOwen Anderson 113*c093364fSOwen Anderson QEMU_LOCK_GUARD(&target_fd_trans_lock); 114*c093364fSOwen Anderson internal_fd_trans_unregister_unsafe(fd); 115*c093364fSOwen Anderson } 116*c093364fSOwen Anderson 117f7e6a401SLaurent Vivier static inline void fd_trans_dup(int oldfd, int newfd) 118f7e6a401SLaurent Vivier { 119*c093364fSOwen Anderson QEMU_LOCK_GUARD(&target_fd_trans_lock); 120*c093364fSOwen Anderson internal_fd_trans_unregister_unsafe(newfd); 121f7e6a401SLaurent Vivier if (oldfd < target_fd_max && target_fd_trans[oldfd]) { 122*c093364fSOwen 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; 133f7e6a401SLaurent Vivier #if (defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)) || \ 134f7e6a401SLaurent Vivier (defined(CONFIG_INOTIFY1) && defined(TARGET_NR_inotify_init1) && \ 135f7e6a401SLaurent Vivier defined(__NR_inotify_init1)) 136f7e6a401SLaurent Vivier extern TargetFdTrans target_inotify_trans; 137f7e6a401SLaurent Vivier #endif 138f7e6a401SLaurent Vivier #endif 139