@samitouri / QOSamiQemu / commits / e4cd71da25

bsd-user: Add bsd-ioctl.c infrastructure and termios conversion

Add initial bsd-ioctl.c file with termios conversion functions, structure type definitions, and ioctl table infrastructure. Includes target_to_host_termios and host_to_target_termios for terminal I/O control conversion, along with the ioctl dispatch table framework. Style complains about STRUCT and STRUCT_SPECIAL defines: ● checkpatch.pl: 197: ERROR: Macros with complex values should be enclosed in parenthesis ● checkpatch.pl: 198: ERROR: Macros with complex values should be enclosed in parenthesis but that's fine. We are doing weird things with macros, and it's fine. We can't put parens or do while (0) around these since they are table building macros for files that are included multiple times. Signed-off-by: Stacey Son <sson@FreeBSD.org> Signed-off-by: Sean Bruno <sbruno@FreeBSD.org> Signed-off-by: Kyle Evans <kevans@FreeBSD.org> Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> Signed-off-by: Warner Losh <imp@bsdimp.com>

Stacey Son committed Mar 14, 2026 at 11:26 UTC e4cd71da25f07a26118bf1fda57cd1634d906199
1 file changed +219
bsd-user/bsd-ioctl.c new
+219
@@ -0,0 +1,219 @@
1 +/*
2 + * BSD ioctl(2) emulation
3 + *
4 + * Copyright (c) 2013-2015 Stacey D. Son
5 + *
6 + * SPDX-License-Identifier: GPL-2.0-or-later
7 + */
8 +#include "qemu/osdep.h"
9 +
10 +#include <sys/types.h>
11 +#include <sys/param.h>
12 +#include <sys/disk.h>
13 +#include <sys/ioccom.h>
14 +#include <sys/ioctl.h>
15 +#include <sys/sockio.h>
16 +#include <sys/_termios.h>
17 +#include <sys/ttycom.h>
18 +#include <sys/filio.h>
19 +
20 +#include <crypto/cryptodev.h>
21 +
22 +#include <net/ethernet.h>
23 +#include <net/if.h>
24 +#include <net/if_var.h>
25 +#include <net/if_types.h>
26 +#include <net/route.h>
27 +#include <net/if_dl.h>
28 +#include <net/if_gif.h>
29 +#include <net/if_gre.h>
30 +#include <net/if_lagg.h>
31 +#include <net/if_media.h>
32 +#include <net/pfvar.h>
33 +#include <net/if_pfsync.h>
34 +#include <netinet/icmp6.h>
35 +#include <netinet/in.h>
36 +#include <netinet/ip_carp.h>
37 +#include <netinet6/in6_var.h>
38 +#include <netinet6/nd6.h>
39 +#include <net80211/ieee80211_ioctl.h>
40 +
41 +#include <stdio.h>
42 +
43 +#include "qemu.h"
44 +
45 +#include "syscall_defs.h"
46 +#include "bsd-ioctl.h"
47 +#include "os-ioctl-cryptodev.h"
48 +#include "os-ioctl-filio.h"
49 +#include "os-ioctl-in6_var.h"
50 +#include "os-ioctl-sockio.h"
51 +#include "os-ioctl-ttycom.h"
52 +#include "os-ioctl-disk.h"
53 +
54 +static void target_to_host_termios(void *dst, const void *src)
55 +{
56 + struct termios *host = dst;
57 + const struct target_termios *target = src;
58 +
59 + host->c_iflag = target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
60 + host->c_oflag = target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
61 + host->c_cflag = target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
62 + host->c_lflag = target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
63 +
64 + memset(host->c_cc, 0, sizeof(host->c_cc));
65 + host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
66 + host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
67 +#ifdef VEOL2
68 + host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
69 +#endif
70 + host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
71 +#ifdef VWERASE
72 + host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
73 +#endif
74 + host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
75 +#ifdef VREPRINT
76 + host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
77 +#endif
78 +#ifdef VERASE2
79 + host->c_cc[VERASE2] = target->c_cc[TARGET_VERASE2];
80 +#endif
81 + host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
82 + host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
83 + host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
84 +#ifdef VDSUSP
85 + host->c_cc[VDSUSP] = target->c_cc[TARGET_VDSUSP];
86 +#endif
87 + host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
88 + host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
89 +#ifdef VLNEXT
90 + host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
91 +#endif
92 +#ifdef VDISCARD
93 + host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
94 +#endif
95 + host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
96 + host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
97 +#ifdef VSTATUS
98 + host->c_cc[VSTATUS] = target->c_cc[TARGET_VSTATUS];
99 +#endif
100 +
101 + host->c_ispeed = tswap32(target->c_ispeed);
102 + host->c_ospeed = tswap32(target->c_ospeed);
103 +}
104 +
105 +static void host_to_target_termios(void *dst, const void *src)
106 +{
107 + struct target_termios *target = dst;
108 + const struct termios *host = src;
109 +
110 + target->c_iflag = tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
111 + target->c_oflag = tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
112 + target->c_cflag = tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
113 + target->c_lflag = tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
114 +
115 + memset(target->c_cc, 0, sizeof(target->c_cc));
116 + target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
117 + target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
118 +#ifdef VEOL2
119 + target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
120 +#endif
121 + target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
122 +#ifdef VWERASE
123 + target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
124 +#endif
125 + target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
126 +#ifdef VREPRINT
127 + target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
128 +#endif
129 +#ifdef VERASE2
130 + target->c_cc[TARGET_VERASE2] = host->c_cc[VERASE2];
131 +#endif
132 + target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
133 + target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
134 + target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
135 +#ifdef VDSUSP
136 + target->c_cc[TARGET_VDSUSP] = host->c_cc[VDSUSP];
137 +#endif
138 + target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
139 + target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
140 +#ifdef VLNEXT
141 + target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
142 +#endif
143 +#ifdef VDISCARD
144 + target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
145 +#endif
146 + target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
147 + target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
148 +#ifdef VSTATUS
149 + target->c_cc[TARGET_VSTATUS] = host->c_cc[VSTATUS];
150 +#endif
151 +
152 + target->c_ispeed = tswap32(host->c_ispeed);
153 + target->c_ospeed = tswap32(host->c_ospeed);
154 +}
155 +
156 +static const StructEntry struct_termios_def = {
157 + .convert = { host_to_target_termios, target_to_host_termios },
158 + .size = { sizeof(struct target_termios), sizeof(struct termios) },
159 + .align = { __alignof__(struct target_termios),
160 + __alignof__(struct termios) },
161 +};
162 +
163 +/* ioctl structure type definitions */
164 +#define STRUCT(name, ...) STRUCT_ ## name,
165 +#define STRUCT_SPECIAL(name) STRUCT_ ## name,
166 +enum {
167 +#include "os-ioctl-types.h"
168 +STRUCT_MAX
169 +};
170 +#undef STRUCT
171 +#undef STRUCT_SPECIAL
172 +
173 +#define STRUCT(name, ...) \
174 + static const argtype struct_ ## name ## _def[] = { __VA_ARGS__, TYPE_NULL };
175 +#define STRUCT_SPECIAL(name)
176 +#include "os-ioctl-types.h"
177 +#undef STRUCT
178 +#undef STRUCT_SPECIAL
179 +
180 +
181 +struct IOCTLEntry;
182 +
183 +typedef abi_long do_ioctl_fn(const struct IOCTLEntry *ie, uint8_t *buf_temp,
184 + int fd, abi_long cmd, abi_long arg);
185 +
186 +struct IOCTLEntry {
187 + unsigned int target_cmd;
188 + unsigned int host_cmd;
189 + const char *name;
190 + int access;
191 + do_ioctl_fn *do_ioctl;
192 + const argtype arg_type[5];
193 +};
194 +typedef struct IOCTLEntry IOCTLEntry;
195 +
196 +#define MAX_STRUCT_SIZE 4096
197 +
198 +static abi_long do_ioctl_unsupported(__unused const IOCTLEntry *ie,
199 + __unused uint8_t *buf_temp,
200 + __unused int fd, __unused abi_long cmd,
201 + __unused abi_long arg);
202 +
203 +static abi_long do_ioctl_in6_ifreq_sockaddr_int(const IOCTLEntry *ie,
204 + uint8_t *buf_temp, int fd, abi_long cmd, abi_long arg);
205 +
206 +static IOCTLEntry ioctl_entries[] = {
207 +#define IOC_ 0x0000
208 +#define IOC_R 0x0001
209 +#define IOC_W 0x0002
210 +#define IOC_RW (IOC_R | IOC_W)
211 +#define IOCTL(cmd, access, ...) \
212 + { TARGET_ ## cmd, cmd, #cmd, access, 0, { __VA_ARGS__ } },
213 +#define IOCTL_SPECIAL(cmd, access, dofn, ...) \
214 + { TARGET_ ## cmd, cmd, #cmd, access, dofn, { __VA_ARGS__ } },
215 +#define IOCTL_SPECIAL_UNIMPL(cmd, access, dofn, ...) \
216 + { TARGET_ ## cmd, 0, #cmd, access, dofn, { __VA_ARGS__ } },
217 +#include "os-ioctl-cmds.h"
218 + { 0, 0 },
219 +};