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