fd-trans.h (3985B)
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#include "qemu/lockable.h" 20 21typedef abi_long (*TargetFdDataFunc)(void *, size_t); 22typedef abi_long (*TargetFdAddrFunc)(void *, abi_ulong, socklen_t); 23typedef struct TargetFdTrans { 24 TargetFdDataFunc host_to_target_data; 25 TargetFdDataFunc target_to_host_data; 26 TargetFdAddrFunc target_to_host_addr; 27} TargetFdTrans; 28 29extern TargetFdTrans **target_fd_trans; 30extern QemuMutex target_fd_trans_lock; 31 32extern unsigned int target_fd_max; 33 34static inline void fd_trans_init(void) 35{ 36 qemu_mutex_init(&target_fd_trans_lock); 37} 38 39static inline TargetFdDataFunc fd_trans_target_to_host_data(int fd) 40{ 41 if (fd < 0) { 42 return NULL; 43 } 44 45 QEMU_LOCK_GUARD(&target_fd_trans_lock); 46 if (fd < target_fd_max && target_fd_trans[fd]) { 47 return target_fd_trans[fd]->target_to_host_data; 48 } 49 return NULL; 50} 51 52static inline TargetFdDataFunc fd_trans_host_to_target_data(int fd) 53{ 54 if (fd < 0) { 55 return NULL; 56 } 57 58 QEMU_LOCK_GUARD(&target_fd_trans_lock); 59 if (fd < target_fd_max && target_fd_trans[fd]) { 60 return target_fd_trans[fd]->host_to_target_data; 61 } 62 return NULL; 63} 64 65static inline TargetFdAddrFunc fd_trans_target_to_host_addr(int fd) 66{ 67 if (fd < 0) { 68 return NULL; 69 } 70 71 QEMU_LOCK_GUARD(&target_fd_trans_lock); 72 if (fd < target_fd_max && target_fd_trans[fd]) { 73 return target_fd_trans[fd]->target_to_host_addr; 74 } 75 return NULL; 76} 77 78static inline void internal_fd_trans_register_unsafe(int fd, 79 TargetFdTrans *trans) 80{ 81 unsigned int oldmax; 82 83 if (fd >= target_fd_max) { 84 oldmax = target_fd_max; 85 target_fd_max = ((fd >> 6) + 1) << 6; /* by slice of 64 entries */ 86 target_fd_trans = g_renew(TargetFdTrans *, 87 target_fd_trans, target_fd_max); 88 memset((void *)(target_fd_trans + oldmax), 0, 89 (target_fd_max - oldmax) * sizeof(TargetFdTrans *)); 90 } 91 target_fd_trans[fd] = trans; 92} 93 94static inline void fd_trans_register(int fd, TargetFdTrans *trans) 95{ 96 QEMU_LOCK_GUARD(&target_fd_trans_lock); 97 internal_fd_trans_register_unsafe(fd, trans); 98} 99 100static inline void internal_fd_trans_unregister_unsafe(int fd) 101{ 102 if (fd >= 0 && fd < target_fd_max) { 103 target_fd_trans[fd] = NULL; 104 } 105} 106 107static inline void fd_trans_unregister(int fd) 108{ 109 if (fd < 0) { 110 return; 111 } 112 113 QEMU_LOCK_GUARD(&target_fd_trans_lock); 114 internal_fd_trans_unregister_unsafe(fd); 115} 116 117static inline void fd_trans_dup(int oldfd, int newfd) 118{ 119 QEMU_LOCK_GUARD(&target_fd_trans_lock); 120 internal_fd_trans_unregister_unsafe(newfd); 121 if (oldfd < target_fd_max && target_fd_trans[oldfd]) { 122 internal_fd_trans_register_unsafe(newfd, target_fd_trans[oldfd]); 123 } 124} 125 126extern TargetFdTrans target_packet_trans; 127#ifdef CONFIG_RTNETLINK 128extern TargetFdTrans target_netlink_route_trans; 129#endif 130extern TargetFdTrans target_netlink_audit_trans; 131extern TargetFdTrans target_signalfd_trans; 132extern TargetFdTrans target_eventfd_trans; 133#if (defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)) || \ 134 (defined(CONFIG_INOTIFY1) && defined(TARGET_NR_inotify_init1) && \ 135 defined(__NR_inotify_init1)) 136extern TargetFdTrans target_inotify_trans; 137#endif 138#endif