Pull up following revision(s) (requested by mrg in ticket #1481): sys/compat/ibcs2/ibcs2_exec_coff.c: 1.27-1.29 sys/compat/ibcs2/ibcs2_ioctl.c: 1.46 sys/compat/ibcs2/ibcs2_stat.c: 1.49-1.50 Check for NUL termination within the buffer we have. From Ilja Van Sprundel. -- Make sure we have enough space in the buffer before reading it. From Ilja Van Sprundel. -- Make sure we move forward over the buffer. From Ilja Van Sprundel. -- Zero buffers in ibcs2 ioctl to avoid disclosing stack to userland. From Ilja Van Sprundel. -- Don't drop vnode ref until we're done with mount in ibcs2_stat(v)fs. Nothing else guarantees the mount will stick around. From Ilja Van Sprundel. -- Little happy on the commit trigger. Actually use the out label.diff -r1.25 -r1.25.14.1 src/sys/compat/ibcs2/ibcs2_exec_coff.c
(snj)
--- src/sys/compat/ibcs2/Attic/ibcs2_exec_coff.c 2010/07/22 03:19:02 1.25
+++ src/sys/compat/ibcs2/Attic/ibcs2_exec_coff.c 2017/08/19 04:13:51 1.25.14.1
@@ -1,600 +1,606 @@ | @@ -1,600 +1,606 @@ | |||
1 | /* $NetBSD: ibcs2_exec_coff.c,v 1.25 2010/07/22 03:19:02 christos Exp $ */ | 1 | /* $NetBSD: ibcs2_exec_coff.c,v 1.25.14.1 2017/08/19 04:13:51 snj Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 1994, 1995, 1998 Scott Bartram | 4 | * Copyright (c) 1994, 1995, 1998 Scott Bartram | |
5 | * Copyright (c) 1994 Adam Glass | 5 | * Copyright (c) 1994 Adam Glass | |
6 | * Copyright (c) 1993, 1994 Christopher G. Demetriou | 6 | * Copyright (c) 1993, 1994 Christopher G. Demetriou | |
7 | * All rights reserved. | 7 | * All rights reserved. | |
8 | * | 8 | * | |
9 | * originally from kern/exec_ecoff.c | 9 | * originally from kern/exec_ecoff.c | |
10 | * | 10 | * | |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without | |
12 | * modification, are permitted provided that the following conditions | 12 | * modification, are permitted provided that the following conditions | |
13 | * are met: | 13 | * are met: | |
14 | * 1. Redistributions of source code must retain the above copyright | 14 | * 1. Redistributions of source code must retain the above copyright | |
15 | * notice, this list of conditions and the following disclaimer. | 15 | * notice, this list of conditions and the following disclaimer. | |
16 | * 2. Redistributions in binary form must reproduce the above copyright | 16 | * 2. Redistributions in binary form must reproduce the above copyright | |
17 | * notice, this list of conditions and the following disclaimer in the | 17 | * notice, this list of conditions and the following disclaimer in the | |
18 | * documentation and/or other materials provided with the distribution. | 18 | * documentation and/or other materials provided with the distribution. | |
19 | * 3. All advertising materials mentioning features or use of this software | 19 | * 3. All advertising materials mentioning features or use of this software | |
20 | * must display the following acknowledgement: | 20 | * must display the following acknowledgement: | |
21 | * This product includes software developed by Scott Bartram. | 21 | * This product includes software developed by Scott Bartram. | |
22 | * 4. The name of the author may not be used to endorse or promote products | 22 | * 4. The name of the author may not be used to endorse or promote products | |
23 | * derived from this software without specific prior written permission | 23 | * derived from this software without specific prior written permission | |
24 | * | 24 | * | |
25 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | 25 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | 26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
27 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | 27 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
28 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | 28 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
29 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | 29 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
30 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 30 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
31 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 31 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
32 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 32 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
33 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 33 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
35 | */ | 35 | */ | |
36 | 36 | |||
37 | #include <sys/cdefs.h> | 37 | #include <sys/cdefs.h> | |
38 | __KERNEL_RCSID(0, "$NetBSD: ibcs2_exec_coff.c,v 1.25 2010/07/22 03:19:02 christos Exp $"); | 38 | __KERNEL_RCSID(0, "$NetBSD: ibcs2_exec_coff.c,v 1.25.14.1 2017/08/19 04:13:51 snj Exp $"); | |
39 | 39 | |||
40 | #include <sys/param.h> | 40 | #include <sys/param.h> | |
41 | #include <sys/systm.h> | 41 | #include <sys/systm.h> | |
42 | #include <sys/kernel.h> | 42 | #include <sys/kernel.h> | |
43 | #include <sys/proc.h> | 43 | #include <sys/proc.h> | |
44 | #include <sys/malloc.h> | 44 | #include <sys/malloc.h> | |
45 | #include <sys/namei.h> | 45 | #include <sys/namei.h> | |
46 | #include <sys/vnode.h> | 46 | #include <sys/vnode.h> | |
47 | #include <sys/mount.h> | 47 | #include <sys/mount.h> | |
48 | #include <sys/exec.h> | 48 | #include <sys/exec.h> | |
49 | #include <sys/exec_coff.h> | 49 | #include <sys/exec_coff.h> | |
50 | #include <sys/resourcevar.h> | 50 | #include <sys/resourcevar.h> | |
51 | 51 | |||
52 | #include <sys/mman.h> | 52 | #include <sys/mman.h> | |
53 | 53 | |||
54 | #include <sys/cpu.h> | 54 | #include <sys/cpu.h> | |
55 | #include <machine/reg.h> | 55 | #include <machine/reg.h> | |
56 | #include <machine/ibcs2_machdep.h> | 56 | #include <machine/ibcs2_machdep.h> | |
57 | 57 | |||
58 | #include <compat/ibcs2/ibcs2_types.h> | 58 | #include <compat/ibcs2/ibcs2_types.h> | |
59 | #include <compat/ibcs2/ibcs2_exec.h> | 59 | #include <compat/ibcs2/ibcs2_exec.h> | |
60 | #include <compat/ibcs2/ibcs2_errno.h> | 60 | #include <compat/ibcs2/ibcs2_errno.h> | |
61 | #include <compat/ibcs2/ibcs2_util.h> | 61 | #include <compat/ibcs2/ibcs2_util.h> | |
62 | 62 | |||
63 | 63 | |||
64 | int exec_ibcs2_coff_prep_omagic(struct lwp *, struct exec_package *, | 64 | int exec_ibcs2_coff_prep_omagic(struct lwp *, struct exec_package *, | |
65 | struct coff_filehdr *, | 65 | struct coff_filehdr *, | |
66 | struct coff_aouthdr *); | 66 | struct coff_aouthdr *); | |
67 | int exec_ibcs2_coff_prep_nmagic(struct lwp *, struct exec_package *, | 67 | int exec_ibcs2_coff_prep_nmagic(struct lwp *, struct exec_package *, | |
68 | struct coff_filehdr *, | 68 | struct coff_filehdr *, | |
69 | struct coff_aouthdr *); | 69 | struct coff_aouthdr *); | |
70 | int exec_ibcs2_coff_prep_zmagic(struct lwp *, struct exec_package *, | 70 | int exec_ibcs2_coff_prep_zmagic(struct lwp *, struct exec_package *, | |
71 | struct coff_filehdr *, | 71 | struct coff_filehdr *, | |
72 | struct coff_aouthdr *); | 72 | struct coff_aouthdr *); | |
73 | void cpu_exec_ibcs2_coff_setup(int, struct proc *, struct exec_package *, | 73 | void cpu_exec_ibcs2_coff_setup(int, struct proc *, struct exec_package *, | |
74 | void *); | 74 | void *); | |
75 | 75 | |||
76 | static int coff_load_shlib(struct lwp *, const char *, | 76 | static int coff_load_shlib(struct lwp *, const char *, | |
77 | struct exec_package *); | 77 | struct exec_package *); | |
78 | static int coff_find_section(struct lwp *, struct vnode *, | 78 | static int coff_find_section(struct lwp *, struct vnode *, | |
79 | struct coff_filehdr *, struct coff_scnhdr *, | 79 | struct coff_filehdr *, struct coff_scnhdr *, | |
80 | int); | 80 | int); | |
81 | 81 | |||
82 | /* | 82 | /* | |
83 | * exec_ibcs2_coff_makecmds(): Check if it's an coff-format executable. | 83 | * exec_ibcs2_coff_makecmds(): Check if it's an coff-format executable. | |
84 | * | 84 | * | |
85 | * Given a proc pointer and an exec package pointer, see if the referent | 85 | * Given a proc pointer and an exec package pointer, see if the referent | |
86 | * of the epp is in coff format. Check 'standard' magic numbers for | 86 | * of the epp is in coff format. Check 'standard' magic numbers for | |
87 | * this architecture. If that fails, return failure. | 87 | * this architecture. If that fails, return failure. | |
88 | * | 88 | * | |
89 | * This function is responsible for creating a set of vmcmds which can be | 89 | * This function is responsible for creating a set of vmcmds which can be | |
90 | * used to build the process's vm space and inserting them into the exec | 90 | * used to build the process's vm space and inserting them into the exec | |
91 | * package. | 91 | * package. | |
92 | */ | 92 | */ | |
93 | 93 | |||
94 | int | 94 | int | |
95 | exec_ibcs2_coff_makecmds(struct lwp *l, struct exec_package *epp) | 95 | exec_ibcs2_coff_makecmds(struct lwp *l, struct exec_package *epp) | |
96 | { | 96 | { | |
97 | int error; | 97 | int error; | |
98 | struct coff_filehdr *fp = epp->ep_hdr; | 98 | struct coff_filehdr *fp = epp->ep_hdr; | |
99 | struct coff_aouthdr *ap; | 99 | struct coff_aouthdr *ap; | |
100 | 100 | |||
101 | if (epp->ep_hdrvalid < COFF_HDR_SIZE) { | 101 | if (epp->ep_hdrvalid < COFF_HDR_SIZE) { | |
102 | DPRINTF(("ibcs2: bad coff hdr size\n")); | 102 | DPRINTF(("ibcs2: bad coff hdr size\n")); | |
103 | return ENOEXEC; | 103 | return ENOEXEC; | |
104 | } | 104 | } | |
105 | 105 | |||
106 | if (COFF_BADMAG(fp)) { | 106 | if (COFF_BADMAG(fp)) { | |
107 | DPRINTF(("ibcs2: bad coff magic\n")); | 107 | DPRINTF(("ibcs2: bad coff magic\n")); | |
108 | return ENOEXEC; | 108 | return ENOEXEC; | |
109 | } | 109 | } | |
110 | 110 | |||
111 | ap = (void *)((char *)epp->ep_hdr + sizeof(struct coff_filehdr)); | 111 | ap = (void *)((char *)epp->ep_hdr + sizeof(struct coff_filehdr)); | |
112 | switch (ap->a_magic) { | 112 | switch (ap->a_magic) { | |
113 | case COFF_OMAGIC: | 113 | case COFF_OMAGIC: | |
114 | error = exec_ibcs2_coff_prep_omagic(l, epp, fp, ap); | 114 | error = exec_ibcs2_coff_prep_omagic(l, epp, fp, ap); | |
115 | break; | 115 | break; | |
116 | case COFF_NMAGIC: | 116 | case COFF_NMAGIC: | |
117 | error = exec_ibcs2_coff_prep_nmagic(l, epp, fp, ap); | 117 | error = exec_ibcs2_coff_prep_nmagic(l, epp, fp, ap); | |
118 | break; | 118 | break; | |
119 | case COFF_ZMAGIC: | 119 | case COFF_ZMAGIC: | |
120 | error = exec_ibcs2_coff_prep_zmagic(l, epp, fp, ap); | 120 | error = exec_ibcs2_coff_prep_zmagic(l, epp, fp, ap); | |
121 | break; | 121 | break; | |
122 | default: | 122 | default: | |
123 | DPRINTF(("ibcs2: bad coff magic %x\n", ap->a_magic)); | 123 | DPRINTF(("ibcs2: bad coff magic %x\n", ap->a_magic)); | |
124 | return ENOEXEC; | 124 | return ENOEXEC; | |
125 | } | 125 | } | |
126 | 126 | |||
127 | if (error) { | 127 | if (error) { | |
128 | kill_vmcmds(&epp->ep_vmcmds); | 128 | kill_vmcmds(&epp->ep_vmcmds); | |
129 | DPRINTF(("ibcs2: error loading magic %x (%d)\n", ap->a_magic, | 129 | DPRINTF(("ibcs2: error loading magic %x (%d)\n", ap->a_magic, | |
130 | error)); | 130 | error)); | |
131 | } | 131 | } | |
132 | 132 | |||
133 | return error; | 133 | return error; | |
134 | } | 134 | } | |
135 | 135 | |||
136 | /* | 136 | /* | |
137 | * exec_ibcs2_coff_prep_omagic(): Prepare a COFF OMAGIC binary's exec package | 137 | * exec_ibcs2_coff_prep_omagic(): Prepare a COFF OMAGIC binary's exec package | |
138 | */ | 138 | */ | |
139 | 139 | |||
140 | int | 140 | int | |
141 | exec_ibcs2_coff_prep_omagic(struct lwp *l, struct exec_package *epp, struct coff_filehdr *fp, struct coff_aouthdr *ap) | 141 | exec_ibcs2_coff_prep_omagic(struct lwp *l, struct exec_package *epp, struct coff_filehdr *fp, struct coff_aouthdr *ap) | |
142 | { | 142 | { | |
143 | epp->ep_taddr = COFF_SEGMENT_ALIGN(fp, ap, ap->a_tstart); | 143 | epp->ep_taddr = COFF_SEGMENT_ALIGN(fp, ap, ap->a_tstart); | |
144 | epp->ep_tsize = ap->a_tsize; | 144 | epp->ep_tsize = ap->a_tsize; | |
145 | epp->ep_daddr = COFF_SEGMENT_ALIGN(fp, ap, ap->a_dstart); | 145 | epp->ep_daddr = COFF_SEGMENT_ALIGN(fp, ap, ap->a_dstart); | |
146 | epp->ep_dsize = ap->a_dsize; | 146 | epp->ep_dsize = ap->a_dsize; | |
147 | epp->ep_entry = ap->a_entry; | 147 | epp->ep_entry = ap->a_entry; | |
148 | 148 | |||
149 | DPRINTF(("ibcs2_omagic: text=%#lx/%#lx, data=%#lx/%#lx, bss=%#lx/%#lx, entry=%#lx\n", | 149 | DPRINTF(("ibcs2_omagic: text=%#lx/%#lx, data=%#lx/%#lx, bss=%#lx/%#lx, entry=%#lx\n", | |
150 | epp->ep_taddr, epp->ep_tsize, | 150 | epp->ep_taddr, epp->ep_tsize, | |
151 | epp->ep_daddr, epp->ep_dsize, | 151 | epp->ep_daddr, epp->ep_dsize, | |
152 | ap->a_dstart + ap->a_dsize, ap->a_bsize, | 152 | ap->a_dstart + ap->a_dsize, ap->a_bsize, | |
153 | epp->ep_entry)); | 153 | epp->ep_entry)); | |
154 | 154 | |||
155 | /* set up command for text and data segments */ | 155 | /* set up command for text and data segments */ | |
156 | NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, | 156 | NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, | |
157 | ap->a_tsize + ap->a_dsize, epp->ep_taddr, epp->ep_vp, | 157 | ap->a_tsize + ap->a_dsize, epp->ep_taddr, epp->ep_vp, | |
158 | COFF_TXTOFF(fp, ap), | 158 | COFF_TXTOFF(fp, ap), | |
159 | VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); | 159 | VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); | |
160 | 160 | |||
161 | /* set up command for bss segment */ | 161 | /* set up command for bss segment */ | |
162 | if (ap->a_bsize > 0) { | 162 | if (ap->a_bsize > 0) { | |
163 | NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, ap->a_bsize, | 163 | NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, ap->a_bsize, | |
164 | COFF_SEGMENT_ALIGN(fp, ap, ap->a_dstart + ap->a_dsize), | 164 | COFF_SEGMENT_ALIGN(fp, ap, ap->a_dstart + ap->a_dsize), | |
165 | NULLVP, 0, | 165 | NULLVP, 0, | |
166 | VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); | 166 | VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); | |
167 | epp->ep_dsize += ap->a_bsize; | 167 | epp->ep_dsize += ap->a_bsize; | |
168 | } | 168 | } | |
169 | /* The following is to make obreak(2) happy. It expects daddr | 169 | /* The following is to make obreak(2) happy. It expects daddr | |
170 | * to on a page boundary and will round up dsize to a page | 170 | * to on a page boundary and will round up dsize to a page | |
171 | * address. | 171 | * address. | |
172 | */ | 172 | */ | |
173 | if (trunc_page(epp->ep_daddr) != epp->ep_daddr) { | 173 | if (trunc_page(epp->ep_daddr) != epp->ep_daddr) { | |
174 | epp->ep_dsize += epp->ep_daddr - trunc_page(epp->ep_daddr); | 174 | epp->ep_dsize += epp->ep_daddr - trunc_page(epp->ep_daddr); | |
175 | epp->ep_daddr = trunc_page(epp->ep_daddr); | 175 | epp->ep_daddr = trunc_page(epp->ep_daddr); | |
176 | if (epp->ep_taddr + epp->ep_tsize > epp->ep_daddr) | 176 | if (epp->ep_taddr + epp->ep_tsize > epp->ep_daddr) | |
177 | epp->ep_tsize = epp->ep_daddr - epp->ep_taddr; | 177 | epp->ep_tsize = epp->ep_daddr - epp->ep_taddr; | |
178 | } | 178 | } | |
179 | 179 | |||
180 | return (*epp->ep_esch->es_setup_stack)(l, epp); | 180 | return (*epp->ep_esch->es_setup_stack)(l, epp); | |
181 | } | 181 | } | |
182 | 182 | |||
183 | /* | 183 | /* | |
184 | * exec_ibcs2_coff_prep_nmagic(): Prepare a 'native' NMAGIC COFF binary's exec | 184 | * exec_ibcs2_coff_prep_nmagic(): Prepare a 'native' NMAGIC COFF binary's exec | |
185 | * package. | 185 | * package. | |
186 | */ | 186 | */ | |
187 | 187 | |||
188 | int | 188 | int | |
189 | exec_ibcs2_coff_prep_nmagic(struct lwp *l, struct exec_package *epp, struct coff_filehdr *fp, struct coff_aouthdr *ap) | 189 | exec_ibcs2_coff_prep_nmagic(struct lwp *l, struct exec_package *epp, struct coff_filehdr *fp, struct coff_aouthdr *ap) | |
190 | { | 190 | { | |
191 | long toverlap, doverlap; | 191 | long toverlap, doverlap; | |
192 | u_long tsize, tend; | 192 | u_long tsize, tend; | |
193 | 193 | |||
194 | epp->ep_taddr = ap->a_tstart; | 194 | epp->ep_taddr = ap->a_tstart; | |
195 | epp->ep_tsize = ap->a_tsize; | 195 | epp->ep_tsize = ap->a_tsize; | |
196 | epp->ep_daddr = ap->a_dstart; | 196 | epp->ep_daddr = ap->a_dstart; | |
197 | epp->ep_dsize = ap->a_dsize; | 197 | epp->ep_dsize = ap->a_dsize; | |
198 | epp->ep_entry = ap->a_entry; | 198 | epp->ep_entry = ap->a_entry; | |
199 | 199 | |||
200 | DPRINTF(("ibcs2_nmagic: text=%#lx/%#lx, data=%#lx/%#lx, bss=%#lx/%#lx, entry=%#lx\n", | 200 | DPRINTF(("ibcs2_nmagic: text=%#lx/%#lx, data=%#lx/%#lx, bss=%#lx/%#lx, entry=%#lx\n", | |
201 | epp->ep_taddr, epp->ep_tsize, | 201 | epp->ep_taddr, epp->ep_tsize, | |
202 | epp->ep_daddr, epp->ep_dsize, | 202 | epp->ep_daddr, epp->ep_dsize, | |
203 | ap->a_dstart + ap->a_dsize, ap->a_bsize, | 203 | ap->a_dstart + ap->a_dsize, ap->a_bsize, | |
204 | epp->ep_entry)); | 204 | epp->ep_entry)); | |
205 | 205 | |||
206 | /* Do the text and data pages overlap? | 206 | /* Do the text and data pages overlap? | |
207 | */ | 207 | */ | |
208 | tend = epp->ep_taddr + epp->ep_tsize - 1; | 208 | tend = epp->ep_taddr + epp->ep_tsize - 1; | |
209 | if (trunc_page(tend) == trunc_page(epp->ep_daddr)) { | 209 | if (trunc_page(tend) == trunc_page(epp->ep_daddr)) { | |
210 | /* If the first page of text is the first page of data, | 210 | /* If the first page of text is the first page of data, | |
211 | * then we consider it all data. | 211 | * then we consider it all data. | |
212 | */ | 212 | */ | |
213 | if (trunc_page(epp->ep_taddr) == trunc_page(epp->ep_daddr)) { | 213 | if (trunc_page(epp->ep_taddr) == trunc_page(epp->ep_daddr)) { | |
214 | tsize = 0; | 214 | tsize = 0; | |
215 | } else { | 215 | } else { | |
216 | tsize = trunc_page(tend) - epp->ep_taddr; | 216 | tsize = trunc_page(tend) - epp->ep_taddr; | |
217 | } | 217 | } | |
218 | 218 | |||
219 | /* If the text and data file and VA offsets are the | 219 | /* If the text and data file and VA offsets are the | |
220 | * same, simply bring the data segment to start on | 220 | * same, simply bring the data segment to start on | |
221 | * the start of the page. | 221 | * the start of the page. | |
222 | */ | 222 | */ | |
223 | if (epp->ep_daddr - epp->ep_taddr == | 223 | if (epp->ep_daddr - epp->ep_taddr == | |
224 | COFF_DATOFF(fp, ap) - COFF_TXTOFF(fp, ap)) { | 224 | COFF_DATOFF(fp, ap) - COFF_TXTOFF(fp, ap)) { | |
225 | u_long diff = epp->ep_daddr - trunc_page(epp->ep_daddr); | 225 | u_long diff = epp->ep_daddr - trunc_page(epp->ep_daddr); | |
226 | toverlap = 0; | 226 | toverlap = 0; | |
227 | doverlap = -diff; | 227 | doverlap = -diff; | |
228 | } else { | 228 | } else { | |
229 | /* otherwise copy the individual pieces */ | 229 | /* otherwise copy the individual pieces */ | |
230 | toverlap = epp->ep_tsize - tsize; | 230 | toverlap = epp->ep_tsize - tsize; | |
231 | doverlap = round_page(epp->ep_daddr) - epp->ep_daddr; | 231 | doverlap = round_page(epp->ep_daddr) - epp->ep_daddr; | |
232 | if (doverlap > epp->ep_dsize) | 232 | if (doverlap > epp->ep_dsize) | |
233 | doverlap = epp->ep_dsize; | 233 | doverlap = epp->ep_dsize; | |
234 | } | 234 | } | |
235 | } else { | 235 | } else { | |
236 | tsize = epp->ep_tsize; | 236 | tsize = epp->ep_tsize; | |
237 | toverlap = 0; | 237 | toverlap = 0; | |
238 | doverlap = 0; | 238 | doverlap = 0; | |
239 | } | 239 | } | |
240 | 240 | |||
241 | DPRINTF(("nmagic_vmcmds:")); | 241 | DPRINTF(("nmagic_vmcmds:")); | |
242 | if (tsize > 0) { | 242 | if (tsize > 0) { | |
243 | /* set up command for text segment */ | 243 | /* set up command for text segment */ | |
244 | NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, tsize, | 244 | NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, tsize, | |
245 | epp->ep_taddr, epp->ep_vp, COFF_TXTOFF(fp, ap), | 245 | epp->ep_taddr, epp->ep_vp, COFF_TXTOFF(fp, ap), | |
246 | VM_PROT_READ|VM_PROT_EXECUTE); | 246 | VM_PROT_READ|VM_PROT_EXECUTE); | |
247 | DPRINTF((" map_readvn(%#lx/%#lx@%#lx)", | 247 | DPRINTF((" map_readvn(%#lx/%#lx@%#lx)", | |
248 | epp->ep_taddr, tsize, (u_long) COFF_TXTOFF(fp, ap))); | 248 | epp->ep_taddr, tsize, (u_long) COFF_TXTOFF(fp, ap))); | |
249 | } | 249 | } | |
250 | if (toverlap > 0) { | 250 | if (toverlap > 0) { | |
251 | NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, toverlap, | 251 | NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, toverlap, | |
252 | epp->ep_taddr + tsize, epp->ep_vp, | 252 | epp->ep_taddr + tsize, epp->ep_vp, | |
253 | COFF_TXTOFF(fp, ap) + tsize, | 253 | COFF_TXTOFF(fp, ap) + tsize, | |
254 | VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); | 254 | VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); | |
255 | DPRINTF((" map_readvn(%#lx/%#lx@%#lx)", | 255 | DPRINTF((" map_readvn(%#lx/%#lx@%#lx)", | |
256 | epp->ep_taddr + tsize, toverlap, | 256 | epp->ep_taddr + tsize, toverlap, | |
257 | COFF_TXTOFF(fp, ap) + tsize)); | 257 | COFF_TXTOFF(fp, ap) + tsize)); | |
258 | NEW_VMCMD(&epp->ep_vmcmds, vmcmd_readvn, doverlap, | 258 | NEW_VMCMD(&epp->ep_vmcmds, vmcmd_readvn, doverlap, | |
259 | epp->ep_daddr, epp->ep_vp, | 259 | epp->ep_daddr, epp->ep_vp, | |
260 | COFF_DATOFF(fp, ap), | 260 | COFF_DATOFF(fp, ap), | |
261 | VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); | 261 | VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); | |
262 | DPRINTF((" readvn(%#lx/%#lx@%#lx)", epp->ep_daddr, doverlap, | 262 | DPRINTF((" readvn(%#lx/%#lx@%#lx)", epp->ep_daddr, doverlap, | |
263 | COFF_DATOFF(fp, ap))); | 263 | COFF_DATOFF(fp, ap))); | |
264 | } | 264 | } | |
265 | 265 | |||
266 | if (epp->ep_dsize > doverlap || doverlap < 0) { | 266 | if (epp->ep_dsize > doverlap || doverlap < 0) { | |
267 | /* set up command for data segment */ | 267 | /* set up command for data segment */ | |
268 | NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, | 268 | NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, | |
269 | epp->ep_dsize - doverlap, epp->ep_daddr + doverlap, | 269 | epp->ep_dsize - doverlap, epp->ep_daddr + doverlap, | |
270 | epp->ep_vp, COFF_DATOFF(fp, ap) + doverlap, | 270 | epp->ep_vp, COFF_DATOFF(fp, ap) + doverlap, | |
271 | VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); | 271 | VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); | |
272 | DPRINTF((" map_readvn(%#lx/%#lx@%#lx)", | 272 | DPRINTF((" map_readvn(%#lx/%#lx@%#lx)", | |
273 | epp->ep_daddr + doverlap, epp->ep_dsize - doverlap, | 273 | epp->ep_daddr + doverlap, epp->ep_dsize - doverlap, | |
274 | COFF_DATOFF(fp, ap) + doverlap)); | 274 | COFF_DATOFF(fp, ap) + doverlap)); | |
275 | } | 275 | } | |
276 | 276 | |||
277 | /* Handle page remainders for pagedvn. | 277 | /* Handle page remainders for pagedvn. | |
278 | */ | 278 | */ | |
279 | 279 | |||
280 | /* set up command for bss segment */ | 280 | /* set up command for bss segment */ | |
281 | if (ap->a_bsize > 0) { | 281 | if (ap->a_bsize > 0) { | |
282 | u_long dend = round_page(epp->ep_daddr + epp->ep_dsize); | 282 | u_long dend = round_page(epp->ep_daddr + epp->ep_dsize); | |
283 | u_long dspace = dend - (epp->ep_daddr + epp->ep_dsize); | 283 | u_long dspace = dend - (epp->ep_daddr + epp->ep_dsize); | |
284 | if (ap->a_bsize > dspace) { | 284 | if (ap->a_bsize > dspace) { | |
285 | NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, | 285 | NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, | |
286 | ap->a_bsize - dspace, dend, NULLVP, 0, | 286 | ap->a_bsize - dspace, dend, NULLVP, 0, | |
287 | VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); | 287 | VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); | |
288 | DPRINTF((" map_zero(%#lx/%#lx)", | 288 | DPRINTF((" map_zero(%#lx/%#lx)", | |
289 | dend, ap->a_bsize - dspace)); | 289 | dend, ap->a_bsize - dspace)); | |
290 | } | 290 | } | |
291 | epp->ep_dsize += ap->a_bsize; | 291 | epp->ep_dsize += ap->a_bsize; | |
292 | } | 292 | } | |
293 | DPRINTF(("\n")); | 293 | DPRINTF(("\n")); | |
294 | /* The following is to make obreak(2) happy. It expects daddr | 294 | /* The following is to make obreak(2) happy. It expects daddr | |
295 | * to on a page boundary and will round up dsize to a page | 295 | * to on a page boundary and will round up dsize to a page | |
296 | * address. | 296 | * address. | |
297 | */ | 297 | */ | |
298 | if (trunc_page(epp->ep_daddr) != epp->ep_daddr) { | 298 | if (trunc_page(epp->ep_daddr) != epp->ep_daddr) { | |
299 | epp->ep_dsize += epp->ep_daddr - trunc_page(epp->ep_daddr); | 299 | epp->ep_dsize += epp->ep_daddr - trunc_page(epp->ep_daddr); | |
300 | epp->ep_daddr = trunc_page(epp->ep_daddr); | 300 | epp->ep_daddr = trunc_page(epp->ep_daddr); | |
301 | if (epp->ep_taddr + epp->ep_tsize > epp->ep_daddr) | 301 | if (epp->ep_taddr + epp->ep_tsize > epp->ep_daddr) | |
302 | epp->ep_tsize = epp->ep_daddr - epp->ep_taddr; | 302 | epp->ep_tsize = epp->ep_daddr - epp->ep_taddr; | |
303 | } | 303 | } | |
304 | 304 | |||
305 | return (*epp->ep_esch->es_setup_stack)(l, epp); | 305 | return (*epp->ep_esch->es_setup_stack)(l, epp); | |
306 | } | 306 | } | |
307 | 307 | |||
308 | /* | 308 | /* | |
309 | * coff_find_section - load specified section header | 309 | * coff_find_section - load specified section header | |
310 | * | 310 | * | |
311 | * TODO - optimize by reading all section headers in at once | 311 | * TODO - optimize by reading all section headers in at once | |
312 | */ | 312 | */ | |
313 | 313 | |||
314 | static int | 314 | static int | |
315 | coff_find_section(struct lwp *l, struct vnode *vp, struct coff_filehdr *fp, struct coff_scnhdr *sh, int s_type) | 315 | coff_find_section(struct lwp *l, struct vnode *vp, struct coff_filehdr *fp, struct coff_scnhdr *sh, int s_type) | |
316 | { | 316 | { | |
317 | int i, pos, siz, error; | 317 | int i, pos, siz, error; | |
318 | size_t resid; | 318 | size_t resid; | |
319 | 319 | |||
320 | pos = COFF_HDR_SIZE; | 320 | pos = COFF_HDR_SIZE; | |
321 | for (i = 0; i < fp->f_nscns; i++, pos += sizeof(struct coff_scnhdr)) { | 321 | for (i = 0; i < fp->f_nscns; i++, pos += sizeof(struct coff_scnhdr)) { | |
322 | siz = sizeof(struct coff_scnhdr); | 322 | siz = sizeof(struct coff_scnhdr); | |
323 | error = vn_rdwr(UIO_READ, vp, (void *) sh, | 323 | error = vn_rdwr(UIO_READ, vp, (void *) sh, | |
324 | siz, pos, UIO_SYSSPACE, IO_NODELOCKED, l->l_cred, | 324 | siz, pos, UIO_SYSSPACE, IO_NODELOCKED, l->l_cred, | |
325 | &resid, NULL); | 325 | &resid, NULL); | |
326 | if (error) { | 326 | if (error) { | |
327 | DPRINTF(("section hdr %d read error %d\n", i, error)); | 327 | DPRINTF(("section hdr %d read error %d\n", i, error)); | |
328 | return error; | 328 | return error; | |
329 | } | 329 | } | |
330 | siz -= resid; | 330 | siz -= resid; | |
331 | if (siz != sizeof(struct coff_scnhdr)) { | 331 | if (siz != sizeof(struct coff_scnhdr)) { | |
332 | DPRINTF(("incomplete read: hdr %d ask=%d, rem=%lu got %d\n", | 332 | DPRINTF(("incomplete read: hdr %d ask=%d, rem=%lu got %d\n", | |
333 | s_type, sizeof(struct coff_scnhdr), | 333 | s_type, sizeof(struct coff_scnhdr), | |
334 | (u_long) resid, siz)); | 334 | (u_long) resid, siz)); | |
335 | return ENOEXEC; | 335 | return ENOEXEC; | |
336 | } | 336 | } | |
337 | /* DPRINTF(("found section: %x\n", sh->s_flags)); */ | 337 | /* DPRINTF(("found section: %x\n", sh->s_flags)); */ | |
338 | if (sh->s_flags == s_type) | 338 | if (sh->s_flags == s_type) | |
339 | return 0; | 339 | return 0; | |
340 | } | 340 | } | |
341 | return ENOEXEC; | 341 | return ENOEXEC; | |
342 | } | 342 | } | |
343 | 343 | |||
344 | /* | 344 | /* | |
345 | * exec_ibcs2_coff_prep_zmagic(): Prepare a COFF ZMAGIC binary's exec package | 345 | * exec_ibcs2_coff_prep_zmagic(): Prepare a COFF ZMAGIC binary's exec package | |
346 | * | 346 | * | |
347 | * First, set the various offsets/lengths in the exec package. | 347 | * First, set the various offsets/lengths in the exec package. | |
348 | * | 348 | * | |
349 | * Then, mark the text image busy (so it can be demand paged) or error | 349 | * Then, mark the text image busy (so it can be demand paged) or error | |
350 | * out if this is not possible. Finally, set up vmcmds for the | 350 | * out if this is not possible. Finally, set up vmcmds for the | |
351 | * text, data, bss, and stack segments. | 351 | * text, data, bss, and stack segments. | |
352 | */ | 352 | */ | |
353 | 353 | |||
354 | int | 354 | int | |
355 | exec_ibcs2_coff_prep_zmagic(struct lwp *l, struct exec_package *epp, struct coff_filehdr *fp, struct coff_aouthdr *ap) | 355 | exec_ibcs2_coff_prep_zmagic(struct lwp *l, struct exec_package *epp, struct coff_filehdr *fp, struct coff_aouthdr *ap) | |
356 | { | 356 | { | |
357 | int error; | 357 | int error; | |
358 | u_long offset; | 358 | u_long offset; | |
359 | long dsize, baddr, bsize; | 359 | long dsize, baddr, bsize; | |
360 | struct coff_scnhdr sh; | 360 | struct coff_scnhdr sh; | |
361 | 361 | |||
362 | /* DPRINTF(("enter exec_ibcs2_coff_prep_zmagic\n")); */ | 362 | /* DPRINTF(("enter exec_ibcs2_coff_prep_zmagic\n")); */ | |
363 | 363 | |||
364 | /* set up command for text segment */ | 364 | /* set up command for text segment */ | |
365 | error = coff_find_section(l, epp->ep_vp, fp, &sh, COFF_STYP_TEXT); | 365 | error = coff_find_section(l, epp->ep_vp, fp, &sh, COFF_STYP_TEXT); | |
366 | if (error) { | 366 | if (error) { | |
367 | DPRINTF(("can't find text section: %d\n", error)); | 367 | DPRINTF(("can't find text section: %d\n", error)); | |
368 | return error; | 368 | return error; | |
369 | } | 369 | } | |
370 | /* DPRINTF(("COFF text addr %x size %d offset %d\n", sh.s_vaddr, | 370 | /* DPRINTF(("COFF text addr %x size %d offset %d\n", sh.s_vaddr, | |
371 | sh.s_size, sh.s_scnptr)); */ | 371 | sh.s_size, sh.s_scnptr)); */ | |
372 | epp->ep_taddr = COFF_ALIGN(sh.s_vaddr); | 372 | epp->ep_taddr = COFF_ALIGN(sh.s_vaddr); | |
373 | offset = sh.s_scnptr - (sh.s_vaddr - epp->ep_taddr); | 373 | offset = sh.s_scnptr - (sh.s_vaddr - epp->ep_taddr); | |
374 | epp->ep_tsize = sh.s_size + (sh.s_vaddr - epp->ep_taddr); | 374 | epp->ep_tsize = sh.s_size + (sh.s_vaddr - epp->ep_taddr); | |
375 | 375 | |||
376 | /* DPRINTF(("VMCMD: addr %x size %d offset %d\n", epp->ep_taddr, | 376 | /* DPRINTF(("VMCMD: addr %x size %d offset %d\n", epp->ep_taddr, | |
377 | epp->ep_tsize, offset)); */ | 377 | epp->ep_tsize, offset)); */ | |
378 | #ifdef notyet | 378 | #ifdef notyet | |
379 | error = vn_marktext(epp->ep_vp); | 379 | error = vn_marktext(epp->ep_vp); | |
380 | if (error) | 380 | if (error) | |
381 | return (error); | 381 | return (error); | |
382 | 382 | |||
383 | NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_pagedvn, epp->ep_tsize, | 383 | NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_pagedvn, epp->ep_tsize, | |
384 | epp->ep_taddr, epp->ep_vp, offset, | 384 | epp->ep_taddr, epp->ep_vp, offset, | |
385 | VM_PROT_READ|VM_PROT_EXECUTE); | 385 | VM_PROT_READ|VM_PROT_EXECUTE); | |
386 | #else | 386 | #else | |
387 | NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, epp->ep_tsize, | 387 | NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, epp->ep_tsize, | |
388 | epp->ep_taddr, epp->ep_vp, offset, | 388 | epp->ep_taddr, epp->ep_vp, offset, | |
389 | VM_PROT_READ|VM_PROT_EXECUTE); | 389 | VM_PROT_READ|VM_PROT_EXECUTE); | |
390 | #endif | 390 | #endif | |
391 | 391 | |||
392 | /* set up command for data segment */ | 392 | /* set up command for data segment */ | |
393 | error = coff_find_section(l, epp->ep_vp, fp, &sh, COFF_STYP_DATA); | 393 | error = coff_find_section(l, epp->ep_vp, fp, &sh, COFF_STYP_DATA); | |
394 | if (error) { | 394 | if (error) { | |
395 | DPRINTF(("can't find data section: %d\n", error)); | 395 | DPRINTF(("can't find data section: %d\n", error)); | |
396 | return error; | 396 | return error; | |
397 | } | 397 | } | |
398 | /* DPRINTF(("COFF data addr %x size %d offset %d\n", sh.s_vaddr, | 398 | /* DPRINTF(("COFF data addr %x size %d offset %d\n", sh.s_vaddr, | |
399 | sh.s_size, sh.s_scnptr)); */ | 399 | sh.s_size, sh.s_scnptr)); */ | |
400 | epp->ep_daddr = COFF_ALIGN(sh.s_vaddr); | 400 | epp->ep_daddr = COFF_ALIGN(sh.s_vaddr); | |
401 | offset = sh.s_scnptr - (sh.s_vaddr - epp->ep_daddr); | 401 | offset = sh.s_scnptr - (sh.s_vaddr - epp->ep_daddr); | |
402 | dsize = sh.s_size + (sh.s_vaddr - epp->ep_daddr); | 402 | dsize = sh.s_size + (sh.s_vaddr - epp->ep_daddr); | |
403 | epp->ep_dsize = dsize + ap->a_bsize; | 403 | epp->ep_dsize = dsize + ap->a_bsize; | |
404 | 404 | |||
405 | /* DPRINTF(("VMCMD: addr %x size %d offset %d\n", epp->ep_daddr, | 405 | /* DPRINTF(("VMCMD: addr %x size %d offset %d\n", epp->ep_daddr, | |
406 | dsize, offset)); */ | 406 | dsize, offset)); */ | |
407 | #ifdef notyet | 407 | #ifdef notyet | |
408 | NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_pagedvn, dsize, | 408 | NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_pagedvn, dsize, | |
409 | epp->ep_daddr, epp->ep_vp, offset, | 409 | epp->ep_daddr, epp->ep_vp, offset, | |
410 | VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); | 410 | VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); | |
411 | #else | 411 | #else | |
412 | NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, | 412 | NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, | |
413 | dsize, epp->ep_daddr, epp->ep_vp, offset, | 413 | dsize, epp->ep_daddr, epp->ep_vp, offset, | |
414 | VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); | 414 | VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); | |
415 | #endif | 415 | #endif | |
416 | 416 | |||
417 | /* set up command for bss segment */ | 417 | /* set up command for bss segment */ | |
418 | baddr = round_page(epp->ep_daddr + dsize); | 418 | baddr = round_page(epp->ep_daddr + dsize); | |
419 | bsize = epp->ep_daddr + epp->ep_dsize - baddr; | 419 | bsize = epp->ep_daddr + epp->ep_dsize - baddr; | |
420 | if (bsize > 0) { | 420 | if (bsize > 0) { | |
421 | /* DPRINTF(("VMCMD: addr %x size %d offset %d\n", | 421 | /* DPRINTF(("VMCMD: addr %x size %d offset %d\n", | |
422 | baddr, bsize, 0)); */ | 422 | baddr, bsize, 0)); */ | |
423 | NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, | 423 | NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, | |
424 | bsize, baddr, NULLVP, 0, | 424 | bsize, baddr, NULLVP, 0, | |
425 | VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); | 425 | VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); | |
426 | } | 426 | } | |
427 | 427 | |||
428 | /* load any shared libraries */ | 428 | /* load any shared libraries */ | |
429 | error = coff_find_section(l, epp->ep_vp, fp, &sh, COFF_STYP_SHLIB); | 429 | error = coff_find_section(l, epp->ep_vp, fp, &sh, COFF_STYP_SHLIB); | |
430 | if (!error) { | 430 | if (!error) { | |
431 | size_t resid; | 431 | size_t resid; | |
432 | struct coff_slhdr *slhdr; | 432 | struct coff_slhdr *slhdr; | |
433 | char *tbuf, *bufp; | 433 | char *tbuf, *bufp; | |
434 | size_t len = sh.s_size, path_index, entry_len; | 434 | size_t len = sh.s_size, path_index, entry_len; | |
435 | 435 | |||
436 | if (len > 64 * 1024) | 436 | if (len > 64 * 1024) | |
437 | return ENOEXEC; | 437 | return ENOEXEC; | |
438 | 438 | |||
439 | tbuf = malloc(len, M_TEMP, M_WAITOK); | 439 | tbuf = malloc(len, M_TEMP, M_WAITOK); | |
440 | if (tbuf == NULL) | 440 | if (tbuf == NULL) | |
441 | return ENOEXEC; | 441 | return ENOEXEC; | |
442 | 442 | |||
443 | /* DPRINTF(("COFF shlib size %d offset %d\n", | 443 | /* DPRINTF(("COFF shlib size %d offset %d\n", | |
444 | sh.s_size, sh.s_scnptr)); */ | 444 | sh.s_size, sh.s_scnptr)); */ | |
445 | 445 | |||
446 | error = vn_rdwr(UIO_READ, epp->ep_vp, tbuf, | 446 | error = vn_rdwr(UIO_READ, epp->ep_vp, tbuf, | |
447 | len, sh.s_scnptr, | 447 | len, sh.s_scnptr, | |
448 | UIO_SYSSPACE, IO_NODELOCKED, l->l_cred, | 448 | UIO_SYSSPACE, IO_NODELOCKED, l->l_cred, | |
449 | &resid, NULL); | 449 | &resid, NULL); | |
450 | if (error) { | 450 | if (error) { | |
451 | DPRINTF(("shlib section read error %d\n", error)); | 451 | DPRINTF(("shlib section read error %d\n", error)); | |
452 | free(tbuf, M_TEMP); | 452 | free(tbuf, M_TEMP); | |
453 | return ENOEXEC; | 453 | return ENOEXEC; | |
454 | } | 454 | } | |
455 | bufp = tbuf; | 455 | bufp = tbuf; | |
456 | while (len) { | 456 | while (len) { | |
457 | if (len < sizeof(struct coff_slhdr)) { | |||
458 | free(tbuf, M_TEMP); | |||
459 | return ENOEXEC; | |||
460 | } | |||
457 | slhdr = (struct coff_slhdr *)bufp; | 461 | slhdr = (struct coff_slhdr *)bufp; | |
458 | 462 | |||
459 | if (slhdr->path_index > LONG_MAX / sizeof(long) || | 463 | if (slhdr->path_index > LONG_MAX / sizeof(long) || | |
460 | slhdr->entry_len > LONG_MAX / sizeof(long)) { | 464 | slhdr->entry_len > LONG_MAX / sizeof(long)) { | |
461 | free(tbuf, M_TEMP); | 465 | free(tbuf, M_TEMP); | |
462 | return ENOEXEC; | 466 | return ENOEXEC; | |
463 | } | 467 | } | |
464 | 468 | |||
465 | path_index = slhdr->path_index * sizeof(long); | 469 | path_index = slhdr->path_index * sizeof(long); | |
466 | entry_len = slhdr->entry_len * sizeof(long); | 470 | entry_len = slhdr->entry_len * sizeof(long); | |
467 | 471 | |||
468 | if (entry_len > len) { | 472 | if (entry_len < sizeof(struct coff_slhdr) || | |
473 | entry_len > len || | |||
474 | strnlen(slhdr->sl_name, entry_len) == entry_len) { | |||
469 | free(tbuf, M_TEMP); | 475 | free(tbuf, M_TEMP); | |
470 | return ENOEXEC; | 476 | return ENOEXEC; | |
471 | } | 477 | } | |
472 | 478 | |||
473 | /* DPRINTF(("path_index: %d entry_len: %d name: %s\n", | 479 | /* DPRINTF(("path_index: %d entry_len: %d name: %s\n", | |
474 | path_index, entry_len, slhdr->sl_name)); */ | 480 | path_index, entry_len, slhdr->sl_name)); */ | |
475 | 481 | |||
476 | error = coff_load_shlib(l, slhdr->sl_name, epp); | 482 | error = coff_load_shlib(l, slhdr->sl_name, epp); | |
477 | if (error) { | 483 | if (error) { | |
478 | free(tbuf, M_TEMP); | 484 | free(tbuf, M_TEMP); | |
479 | return ENOEXEC; | 485 | return ENOEXEC; | |
480 | } | 486 | } | |
481 | bufp += entry_len; | 487 | bufp += entry_len; | |
482 | len -= entry_len; | 488 | len -= entry_len; | |
483 | } | 489 | } | |
484 | free(tbuf, M_TEMP); | 490 | free(tbuf, M_TEMP); | |
485 | } | 491 | } | |
486 | 492 | |||
487 | /* set up entry point */ | 493 | /* set up entry point */ | |
488 | epp->ep_entry = ap->a_entry; | 494 | epp->ep_entry = ap->a_entry; | |
489 | 495 | |||
490 | DPRINTF(("ibcs2_zmagic: text addr: %#lx size: %#lx data addr: %#lx size: %#lx entry: %#lx\n", | 496 | DPRINTF(("ibcs2_zmagic: text addr: %#lx size: %#lx data addr: %#lx size: %#lx entry: %#lx\n", | |
491 | epp->ep_taddr, epp->ep_tsize, | 497 | epp->ep_taddr, epp->ep_tsize, | |
492 | epp->ep_daddr, epp->ep_dsize, | 498 | epp->ep_daddr, epp->ep_dsize, | |
493 | epp->ep_entry)); | 499 | epp->ep_entry)); | |
494 | 500 | |||
495 | /* The following is to make obreak(2) happy. It expects daddr | 501 | /* The following is to make obreak(2) happy. It expects daddr | |
496 | * to on a page boundary and will round up dsize to a page | 502 | * to on a page boundary and will round up dsize to a page | |
497 | * address. | 503 | * address. | |
498 | */ | 504 | */ | |
499 | if (trunc_page(epp->ep_daddr) != epp->ep_daddr) { | 505 | if (trunc_page(epp->ep_daddr) != epp->ep_daddr) { | |
500 | epp->ep_dsize += epp->ep_daddr - trunc_page(epp->ep_daddr); | 506 | epp->ep_dsize += epp->ep_daddr - trunc_page(epp->ep_daddr); | |
501 | epp->ep_daddr = trunc_page(epp->ep_daddr); | 507 | epp->ep_daddr = trunc_page(epp->ep_daddr); | |
502 | if (epp->ep_taddr + epp->ep_tsize > epp->ep_daddr) | 508 | if (epp->ep_taddr + epp->ep_tsize > epp->ep_daddr) | |
503 | epp->ep_tsize = epp->ep_daddr - epp->ep_taddr; | 509 | epp->ep_tsize = epp->ep_daddr - epp->ep_taddr; | |
504 | } | 510 | } | |
505 | 511 | |||
506 | 512 | |||
507 | return (*epp->ep_esch->es_setup_stack)(l, epp); | 513 | return (*epp->ep_esch->es_setup_stack)(l, epp); | |
508 | } | 514 | } | |
509 | 515 | |||
510 | static int | 516 | static int | |
511 | coff_load_shlib(struct lwp *l, const char *path, struct exec_package *epp) | 517 | coff_load_shlib(struct lwp *l, const char *path, struct exec_package *epp) | |
512 | { | 518 | { | |
513 | int error, siz; | 519 | int error, siz; | |
514 | int taddr, tsize, daddr, dsize, offset; | 520 | int taddr, tsize, daddr, dsize, offset; | |
515 | size_t resid; | 521 | size_t resid; | |
516 | struct vnode *vp; | 522 | struct vnode *vp; | |
517 | struct coff_filehdr fh, *fhp = &fh; | 523 | struct coff_filehdr fh, *fhp = &fh; | |
518 | struct coff_scnhdr sh, *shp = &sh; | 524 | struct coff_scnhdr sh, *shp = &sh; | |
519 | 525 | |||
520 | /* | 526 | /* | |
521 | * 1. open shlib file | 527 | * 1. open shlib file | |
522 | * 2. read filehdr | 528 | * 2. read filehdr | |
523 | * 3. map text, data, and bss out of it using VM_* | 529 | * 3. map text, data, and bss out of it using VM_* | |
524 | */ | 530 | */ | |
525 | /* first get the vnode */ | 531 | /* first get the vnode */ | |
526 | error = namei_simple_kernel(path, NSM_FOLLOW_TRYEMULROOT, &vp); | 532 | error = namei_simple_kernel(path, NSM_FOLLOW_TRYEMULROOT, &vp); | |
527 | if (error != 0) { | 533 | if (error != 0) { | |
528 | DPRINTF(("coff_load_shlib: can't find library %s\n", path)); | 534 | DPRINTF(("coff_load_shlib: can't find library %s\n", path)); | |
529 | return error; | 535 | return error; | |
530 | } | 536 | } | |
531 | 537 | |||
532 | siz = sizeof(struct coff_filehdr); | 538 | siz = sizeof(struct coff_filehdr); | |
533 | error = vn_rdwr(UIO_READ, vp, (void *) fhp, siz, 0, | 539 | error = vn_rdwr(UIO_READ, vp, (void *) fhp, siz, 0, | |
534 | UIO_SYSSPACE, IO_NODELOCKED, l->l_cred, &resid, l); | 540 | UIO_SYSSPACE, IO_NODELOCKED, l->l_cred, &resid, l); | |
535 | if (error) { | 541 | if (error) { | |
536 | DPRINTF(("filehdr read error %d\n", error)); | 542 | DPRINTF(("filehdr read error %d\n", error)); | |
537 | vrele(vp); | 543 | vrele(vp); | |
538 | return error; | 544 | return error; | |
539 | } | 545 | } | |
540 | siz -= resid; | 546 | siz -= resid; | |
541 | if (siz != sizeof(struct coff_filehdr)) { | 547 | if (siz != sizeof(struct coff_filehdr)) { | |
542 | DPRINTF(("coff_load_shlib: incomplete read: ask=%d, rem=%lu got %d\n", | 548 | DPRINTF(("coff_load_shlib: incomplete read: ask=%d, rem=%lu got %d\n", | |
543 | sizeof(struct coff_filehdr), (u_long) resid, siz)); | 549 | sizeof(struct coff_filehdr), (u_long) resid, siz)); | |
544 | vrele(vp); | 550 | vrele(vp); | |
545 | return ENOEXEC; | 551 | return ENOEXEC; | |
546 | } | 552 | } | |
547 | 553 | |||
548 | /* load text */ | 554 | /* load text */ | |
549 | error = coff_find_section(l, vp, fhp, shp, COFF_STYP_TEXT); | 555 | error = coff_find_section(l, vp, fhp, shp, COFF_STYP_TEXT); | |
550 | if (error) { | 556 | if (error) { | |
551 | DPRINTF(("can't find shlib text section\n")); | 557 | DPRINTF(("can't find shlib text section\n")); | |
552 | vrele(vp); | 558 | vrele(vp); | |
553 | return error; | 559 | return error; | |
554 | } | 560 | } | |
555 | /* DPRINTF(("COFF text addr %x size %d offset %d\n", sh.s_vaddr, | 561 | /* DPRINTF(("COFF text addr %x size %d offset %d\n", sh.s_vaddr, | |
556 | sh.s_size, sh.s_scnptr)); */ | 562 | sh.s_size, sh.s_scnptr)); */ | |
557 | taddr = COFF_ALIGN(shp->s_vaddr); | 563 | taddr = COFF_ALIGN(shp->s_vaddr); | |
558 | offset = shp->s_scnptr - (shp->s_vaddr - taddr); | 564 | offset = shp->s_scnptr - (shp->s_vaddr - taddr); | |
559 | tsize = shp->s_size + (shp->s_vaddr - taddr); | 565 | tsize = shp->s_size + (shp->s_vaddr - taddr); | |
560 | /* DPRINTF(("VMCMD: addr %x size %d offset %d\n", taddr, tsize, offset)); */ | 566 | /* DPRINTF(("VMCMD: addr %x size %d offset %d\n", taddr, tsize, offset)); */ | |
561 | NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, tsize, taddr, | 567 | NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, tsize, taddr, | |
562 | vp, offset, | 568 | vp, offset, | |
563 | VM_PROT_READ|VM_PROT_EXECUTE); | 569 | VM_PROT_READ|VM_PROT_EXECUTE); | |
564 | 570 | |||
565 | /* load data */ | 571 | /* load data */ | |
566 | error = coff_find_section(l, vp, fhp, shp, COFF_STYP_DATA); | 572 | error = coff_find_section(l, vp, fhp, shp, COFF_STYP_DATA); | |
567 | if (error) { | 573 | if (error) { | |
568 | DPRINTF(("can't find shlib data section\n")); | 574 | DPRINTF(("can't find shlib data section\n")); | |
569 | vrele(vp); | 575 | vrele(vp); | |
570 | return error; | 576 | return error; | |
571 | } | 577 | } | |
572 | /* DPRINTF(("COFF data addr %x size %d offset %d\n", shp->s_vaddr, | 578 | /* DPRINTF(("COFF data addr %x size %d offset %d\n", shp->s_vaddr, | |
573 | shp->s_size, shp->s_scnptr)); */ | 579 | shp->s_size, shp->s_scnptr)); */ | |
574 | daddr = COFF_ALIGN(shp->s_vaddr); | 580 | daddr = COFF_ALIGN(shp->s_vaddr); | |
575 | offset = shp->s_scnptr - (shp->s_vaddr - daddr); | 581 | offset = shp->s_scnptr - (shp->s_vaddr - daddr); | |
576 | dsize = shp->s_size + (shp->s_vaddr - daddr); | 582 | dsize = shp->s_size + (shp->s_vaddr - daddr); | |
577 | /* epp->ep_dsize = dsize + ap->a_bsize; */ | 583 | /* epp->ep_dsize = dsize + ap->a_bsize; */ | |
578 | 584 | |||
579 | /* DPRINTF(("VMCMD: addr %x size %d offset %d\n", daddr, dsize, offset)); */ | 585 | /* DPRINTF(("VMCMD: addr %x size %d offset %d\n", daddr, dsize, offset)); */ | |
580 | NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, | 586 | NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, | |
581 | dsize, daddr, vp, offset, | 587 | dsize, daddr, vp, offset, | |
582 | VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); | 588 | VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); | |
583 | 589 | |||
584 | /* load bss */ | 590 | /* load bss */ | |
585 | error = coff_find_section(l, vp, fhp, shp, COFF_STYP_BSS); | 591 | error = coff_find_section(l, vp, fhp, shp, COFF_STYP_BSS); | |
586 | if (!error) { | 592 | if (!error) { | |
587 | int baddr = round_page(daddr + dsize); | 593 | int baddr = round_page(daddr + dsize); | |
588 | int bsize = daddr + dsize + shp->s_size - baddr; | 594 | int bsize = daddr + dsize + shp->s_size - baddr; | |
589 | if (bsize > 0) { | 595 | if (bsize > 0) { | |
590 | /* DPRINTF(("VMCMD: addr %x size %d offset %d\n", | 596 | /* DPRINTF(("VMCMD: addr %x size %d offset %d\n", | |
591 | baddr, bsize, 0)); */ | 597 | baddr, bsize, 0)); */ | |
592 | NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, | 598 | NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, | |
593 | bsize, baddr, NULLVP, 0, | 599 | bsize, baddr, NULLVP, 0, | |
594 | VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); | 600 | VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); | |
595 | } | 601 | } | |
596 | } | 602 | } | |
597 | vrele(vp); | 603 | vrele(vp); | |
598 | 604 | |||
599 | return 0; | 605 | return 0; | |
600 | } | 606 | } |
--- src/sys/compat/ibcs2/Attic/ibcs2_ioctl.c 2008/06/24 10:03:17 1.45
+++ src/sys/compat/ibcs2/Attic/ibcs2_ioctl.c 2017/08/19 04:13:51 1.45.36.1
@@ -1,571 +1,574 @@ | @@ -1,571 +1,574 @@ | |||
1 | /* $NetBSD: ibcs2_ioctl.c,v 1.45 2008/06/24 10:03:17 gmcgarry Exp $ */ | 1 | /* $NetBSD: ibcs2_ioctl.c,v 1.45.36.1 2017/08/19 04:13:51 snj Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 1994, 1995 Scott Bartram | 4 | * Copyright (c) 1994, 1995 Scott Bartram | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * based on compat/sunos/sun_ioctl.c | 7 | * based on compat/sunos/sun_ioctl.c | |
8 | * | 8 | * | |
9 | * Redistribution and use in source and binary forms, with or without | 9 | * Redistribution and use in source and binary forms, with or without | |
10 | * modification, are permitted provided that the following conditions | 10 | * modification, are permitted provided that the following conditions | |
11 | * are met: | 11 | * are met: | |
12 | * 1. Redistributions of source code must retain the above copyright | 12 | * 1. Redistributions of source code must retain the above copyright | |
13 | * notice, this list of conditions and the following disclaimer. | 13 | * notice, this list of conditions and the following disclaimer. | |
14 | * 2. The name of the author may not be used to endorse or promote products | 14 | * 2. The name of the author may not be used to endorse or promote products | |
15 | * derived from this software without specific prior written permission | 15 | * derived from this software without specific prior written permission | |
16 | * | 16 | * | |
17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
27 | */ | 27 | */ | |
28 | 28 | |||
29 | #include <sys/cdefs.h> | 29 | #include <sys/cdefs.h> | |
30 | __KERNEL_RCSID(0, "$NetBSD: ibcs2_ioctl.c,v 1.45 2008/06/24 10:03:17 gmcgarry Exp $"); | 30 | __KERNEL_RCSID(0, "$NetBSD: ibcs2_ioctl.c,v 1.45.36.1 2017/08/19 04:13:51 snj Exp $"); | |
31 | 31 | |||
32 | #include <sys/param.h> | 32 | #include <sys/param.h> | |
33 | #include <sys/systm.h> | 33 | #include <sys/systm.h> | |
34 | #include <sys/namei.h> | 34 | #include <sys/namei.h> | |
35 | #include <sys/dirent.h> | 35 | #include <sys/dirent.h> | |
36 | #include <sys/proc.h> | 36 | #include <sys/proc.h> | |
37 | #include <sys/file.h> | 37 | #include <sys/file.h> | |
38 | #include <sys/stat.h> | 38 | #include <sys/stat.h> | |
39 | #include <sys/filedesc.h> | 39 | #include <sys/filedesc.h> | |
40 | #include <sys/ioctl.h> | 40 | #include <sys/ioctl.h> | |
41 | #include <sys/kernel.h> | 41 | #include <sys/kernel.h> | |
42 | #include <sys/mbuf.h> | 42 | #include <sys/mbuf.h> | |
43 | #include <sys/mman.h> | 43 | #include <sys/mman.h> | |
44 | #include <sys/mount.h> | 44 | #include <sys/mount.h> | |
45 | #include <sys/reboot.h> | 45 | #include <sys/reboot.h> | |
46 | #include <sys/resource.h> | 46 | #include <sys/resource.h> | |
47 | #include <sys/resourcevar.h> | 47 | #include <sys/resourcevar.h> | |
48 | #include <sys/signal.h> | 48 | #include <sys/signal.h> | |
49 | #include <sys/signalvar.h> | 49 | #include <sys/signalvar.h> | |
50 | #include <sys/socket.h> | 50 | #include <sys/socket.h> | |
51 | #include <sys/termios.h> | 51 | #include <sys/termios.h> | |
52 | #include <sys/time.h> | 52 | #include <sys/time.h> | |
53 | #include <sys/times.h> | 53 | #include <sys/times.h> | |
54 | #include <sys/tty.h> | 54 | #include <sys/tty.h> | |
55 | #include <sys/vnode.h> | 55 | #include <sys/vnode.h> | |
56 | #include <sys/uio.h> | 56 | #include <sys/uio.h> | |
57 | #include <sys/wait.h> | 57 | #include <sys/wait.h> | |
58 | #include <sys/utsname.h> | 58 | #include <sys/utsname.h> | |
59 | #include <sys/unistd.h> | 59 | #include <sys/unistd.h> | |
60 | 60 | |||
61 | #include <net/if.h> | 61 | #include <net/if.h> | |
62 | #include <sys/syscallargs.h> | 62 | #include <sys/syscallargs.h> | |
63 | 63 | |||
64 | #include <compat/ibcs2/ibcs2_types.h> | 64 | #include <compat/ibcs2/ibcs2_types.h> | |
65 | #include <compat/ibcs2/ibcs2_signal.h> | 65 | #include <compat/ibcs2/ibcs2_signal.h> | |
66 | #include <compat/ibcs2/ibcs2_socksys.h> | 66 | #include <compat/ibcs2/ibcs2_socksys.h> | |
67 | #include <compat/ibcs2/ibcs2_stropts.h> | 67 | #include <compat/ibcs2/ibcs2_stropts.h> | |
68 | #include <compat/ibcs2/ibcs2_syscallargs.h> | 68 | #include <compat/ibcs2/ibcs2_syscallargs.h> | |
69 | #include <compat/ibcs2/ibcs2_termios.h> | 69 | #include <compat/ibcs2/ibcs2_termios.h> | |
70 | #include <compat/ibcs2/ibcs2_util.h> | 70 | #include <compat/ibcs2/ibcs2_util.h> | |
71 | 71 | |||
72 | /* | 72 | /* | |
73 | * iBCS2 ioctl calls. | 73 | * iBCS2 ioctl calls. | |
74 | */ | 74 | */ | |
75 | 75 | |||
76 | static const struct speedtab sptab[] = { | 76 | static const struct speedtab sptab[] = { | |
77 | { 0, 0 }, | 77 | { 0, 0 }, | |
78 | { 50, 1 }, | 78 | { 50, 1 }, | |
79 | { 75, 2 }, | 79 | { 75, 2 }, | |
80 | { 110, 3 }, | 80 | { 110, 3 }, | |
81 | { 134, 4 }, | 81 | { 134, 4 }, | |
82 | { 135, 4 }, | 82 | { 135, 4 }, | |
83 | { 150, 5 }, | 83 | { 150, 5 }, | |
84 | { 200, 6 }, | 84 | { 200, 6 }, | |
85 | { 300, 7 }, | 85 | { 300, 7 }, | |
86 | { 600, 8 }, | 86 | { 600, 8 }, | |
87 | { 1200, 9 }, | 87 | { 1200, 9 }, | |
88 | { 1800, 10 }, | 88 | { 1800, 10 }, | |
89 | { 2400, 11 }, | 89 | { 2400, 11 }, | |
90 | { 4800, 12 }, | 90 | { 4800, 12 }, | |
91 | { 9600, 13 }, | 91 | { 9600, 13 }, | |
92 | { 19200, 14 }, | 92 | { 19200, 14 }, | |
93 | { 38400, 15 }, | 93 | { 38400, 15 }, | |
94 | { -1, -1 } | 94 | { -1, -1 } | |
95 | }; | 95 | }; | |
96 | 96 | |||
97 | static const u_long s2btab[] = { | 97 | static const u_long s2btab[] = { | |
98 | 0, | 98 | 0, | |
99 | 50, | 99 | 50, | |
100 | 75, | 100 | 75, | |
101 | 110, | 101 | 110, | |
102 | 134, | 102 | 134, | |
103 | 150, | 103 | 150, | |
104 | 200, | 104 | 200, | |
105 | 300, | 105 | 300, | |
106 | 600, | 106 | 600, | |
107 | 1200, | 107 | 1200, | |
108 | 1800, | 108 | 1800, | |
109 | 2400, | 109 | 2400, | |
110 | 4800, | 110 | 4800, | |
111 | 9600, | 111 | 9600, | |
112 | 19200, | 112 | 19200, | |
113 | 38400, | 113 | 38400, | |
114 | }; | 114 | }; | |
115 | 115 | |||
116 | static void stios2btios(struct ibcs2_termios *, struct termios *); | 116 | static void stios2btios(struct ibcs2_termios *, struct termios *); | |
117 | static void btios2stios(struct termios *, struct ibcs2_termios *); | 117 | static void btios2stios(struct termios *, struct ibcs2_termios *); | |
118 | static void stios2stio(struct ibcs2_termios *, struct ibcs2_termio *); | 118 | static void stios2stio(struct ibcs2_termios *, struct ibcs2_termio *); | |
119 | static void stio2stios(struct ibcs2_termio *, struct ibcs2_termios *); | 119 | static void stio2stios(struct ibcs2_termio *, struct ibcs2_termios *); | |
120 | 120 | |||
121 | static void | 121 | static void | |
122 | stios2btios(struct ibcs2_termios *st, struct termios *bt) | 122 | stios2btios(struct ibcs2_termios *st, struct termios *bt) | |
123 | { | 123 | { | |
124 | u_long l, r; | 124 | u_long l, r; | |
125 | 125 | |||
126 | l = st->c_iflag; r = 0; | 126 | l = st->c_iflag; r = 0; | |
127 | if (l & IBCS2_IGNBRK) r |= IGNBRK; | 127 | if (l & IBCS2_IGNBRK) r |= IGNBRK; | |
128 | if (l & IBCS2_BRKINT) r |= BRKINT; | 128 | if (l & IBCS2_BRKINT) r |= BRKINT; | |
129 | if (l & IBCS2_IGNPAR) r |= IGNPAR; | 129 | if (l & IBCS2_IGNPAR) r |= IGNPAR; | |
130 | if (l & IBCS2_PARMRK) r |= PARMRK; | 130 | if (l & IBCS2_PARMRK) r |= PARMRK; | |
131 | if (l & IBCS2_INPCK) r |= INPCK; | 131 | if (l & IBCS2_INPCK) r |= INPCK; | |
132 | if (l & IBCS2_ISTRIP) r |= ISTRIP; | 132 | if (l & IBCS2_ISTRIP) r |= ISTRIP; | |
133 | if (l & IBCS2_INLCR) r |= INLCR; | 133 | if (l & IBCS2_INLCR) r |= INLCR; | |
134 | if (l & IBCS2_IGNCR) r |= IGNCR; | 134 | if (l & IBCS2_IGNCR) r |= IGNCR; | |
135 | if (l & IBCS2_ICRNL) r |= ICRNL; | 135 | if (l & IBCS2_ICRNL) r |= ICRNL; | |
136 | if (l & IBCS2_IXON) r |= IXON; | 136 | if (l & IBCS2_IXON) r |= IXON; | |
137 | if (l & IBCS2_IXANY) r |= IXANY; | 137 | if (l & IBCS2_IXANY) r |= IXANY; | |
138 | if (l & IBCS2_IXOFF) r |= IXOFF; | 138 | if (l & IBCS2_IXOFF) r |= IXOFF; | |
139 | if (l & IBCS2_IMAXBEL) r |= IMAXBEL; | 139 | if (l & IBCS2_IMAXBEL) r |= IMAXBEL; | |
140 | bt->c_iflag = r; | 140 | bt->c_iflag = r; | |
141 | 141 | |||
142 | l = st->c_oflag; r = 0; | 142 | l = st->c_oflag; r = 0; | |
143 | if (l & IBCS2_OPOST) r |= OPOST; | 143 | if (l & IBCS2_OPOST) r |= OPOST; | |
144 | if (l & IBCS2_ONLCR) r |= ONLCR; | 144 | if (l & IBCS2_ONLCR) r |= ONLCR; | |
145 | if (l & IBCS2_TAB3) r |= OXTABS; | 145 | if (l & IBCS2_TAB3) r |= OXTABS; | |
146 | bt->c_oflag = r; | 146 | bt->c_oflag = r; | |
147 | 147 | |||
148 | l = st->c_cflag; r = 0; | 148 | l = st->c_cflag; r = 0; | |
149 | switch (l & IBCS2_CSIZE) { | 149 | switch (l & IBCS2_CSIZE) { | |
150 | case IBCS2_CS5: r |= CS5; break; | 150 | case IBCS2_CS5: r |= CS5; break; | |
151 | case IBCS2_CS6: r |= CS6; break; | 151 | case IBCS2_CS6: r |= CS6; break; | |
152 | case IBCS2_CS7: r |= CS7; break; | 152 | case IBCS2_CS7: r |= CS7; break; | |
153 | case IBCS2_CS8: r |= CS8; break; | 153 | case IBCS2_CS8: r |= CS8; break; | |
154 | } | 154 | } | |
155 | if (l & IBCS2_CSTOPB) r |= CSTOPB; | 155 | if (l & IBCS2_CSTOPB) r |= CSTOPB; | |
156 | if (l & IBCS2_CREAD) r |= CREAD; | 156 | if (l & IBCS2_CREAD) r |= CREAD; | |
157 | if (l & IBCS2_PARENB) r |= PARENB; | 157 | if (l & IBCS2_PARENB) r |= PARENB; | |
158 | if (l & IBCS2_PARODD) r |= PARODD; | 158 | if (l & IBCS2_PARODD) r |= PARODD; | |
159 | if (l & IBCS2_HUPCL) r |= HUPCL; | 159 | if (l & IBCS2_HUPCL) r |= HUPCL; | |
160 | if (l & IBCS2_CLOCAL) r |= CLOCAL; | 160 | if (l & IBCS2_CLOCAL) r |= CLOCAL; | |
161 | bt->c_cflag = r; | 161 | bt->c_cflag = r; | |
162 | bt->c_ispeed = bt->c_ospeed = s2btab[l & 0x0f]; | 162 | bt->c_ispeed = bt->c_ospeed = s2btab[l & 0x0f]; | |
163 | 163 | |||
164 | l = st->c_lflag; r = 0; | 164 | l = st->c_lflag; r = 0; | |
165 | if (l & IBCS2_ISIG) r |= ISIG; | 165 | if (l & IBCS2_ISIG) r |= ISIG; | |
166 | if (l & IBCS2_ICANON) r |= ICANON; | 166 | if (l & IBCS2_ICANON) r |= ICANON; | |
167 | if (l & IBCS2_ECHO) r |= ECHO; | 167 | if (l & IBCS2_ECHO) r |= ECHO; | |
168 | if (l & IBCS2_ECHOE) r |= ECHOE; | 168 | if (l & IBCS2_ECHOE) r |= ECHOE; | |
169 | if (l & IBCS2_ECHOK) r |= ECHOK; | 169 | if (l & IBCS2_ECHOK) r |= ECHOK; | |
170 | if (l & IBCS2_ECHONL) r |= ECHONL; | 170 | if (l & IBCS2_ECHONL) r |= ECHONL; | |
171 | if (l & IBCS2_NOFLSH) r |= NOFLSH; | 171 | if (l & IBCS2_NOFLSH) r |= NOFLSH; | |
172 | if (l & IBCS2_TOSTOP) r |= TOSTOP; | 172 | if (l & IBCS2_TOSTOP) r |= TOSTOP; | |
173 | bt->c_lflag = r; | 173 | bt->c_lflag = r; | |
174 | 174 | |||
175 | bt->c_cc[VINTR] = | 175 | bt->c_cc[VINTR] = | |
176 | st->c_cc[IBCS2_VINTR] ? st->c_cc[IBCS2_VINTR] : _POSIX_VDISABLE; | 176 | st->c_cc[IBCS2_VINTR] ? st->c_cc[IBCS2_VINTR] : _POSIX_VDISABLE; | |
177 | bt->c_cc[VQUIT] = | 177 | bt->c_cc[VQUIT] = | |
178 | st->c_cc[IBCS2_VQUIT] ? st->c_cc[IBCS2_VQUIT] : _POSIX_VDISABLE; | 178 | st->c_cc[IBCS2_VQUIT] ? st->c_cc[IBCS2_VQUIT] : _POSIX_VDISABLE; | |
179 | bt->c_cc[VERASE] = | 179 | bt->c_cc[VERASE] = | |
180 | st->c_cc[IBCS2_VERASE] ? st->c_cc[IBCS2_VERASE] : _POSIX_VDISABLE; | 180 | st->c_cc[IBCS2_VERASE] ? st->c_cc[IBCS2_VERASE] : _POSIX_VDISABLE; | |
181 | bt->c_cc[VKILL] = | 181 | bt->c_cc[VKILL] = | |
182 | st->c_cc[IBCS2_VKILL] ? st->c_cc[IBCS2_VKILL] : _POSIX_VDISABLE; | 182 | st->c_cc[IBCS2_VKILL] ? st->c_cc[IBCS2_VKILL] : _POSIX_VDISABLE; | |
183 | if (bt->c_lflag & ICANON) { | 183 | if (bt->c_lflag & ICANON) { | |
184 | bt->c_cc[VEOF] = | 184 | bt->c_cc[VEOF] = | |
185 | st->c_cc[IBCS2_VEOF] ? st->c_cc[IBCS2_VEOF] : _POSIX_VDISABLE; | 185 | st->c_cc[IBCS2_VEOF] ? st->c_cc[IBCS2_VEOF] : _POSIX_VDISABLE; | |
186 | bt->c_cc[VEOL] = | 186 | bt->c_cc[VEOL] = | |
187 | st->c_cc[IBCS2_VEOL] ? st->c_cc[IBCS2_VEOL] : _POSIX_VDISABLE; | 187 | st->c_cc[IBCS2_VEOL] ? st->c_cc[IBCS2_VEOL] : _POSIX_VDISABLE; | |
188 | } else { | 188 | } else { | |
189 | bt->c_cc[VMIN] = st->c_cc[IBCS2_VMIN]; | 189 | bt->c_cc[VMIN] = st->c_cc[IBCS2_VMIN]; | |
190 | bt->c_cc[VTIME] = st->c_cc[IBCS2_VTIME]; | 190 | bt->c_cc[VTIME] = st->c_cc[IBCS2_VTIME]; | |
191 | } | 191 | } | |
192 | bt->c_cc[VEOL2] = | 192 | bt->c_cc[VEOL2] = | |
193 | st->c_cc[IBCS2_VEOL2] ? st->c_cc[IBCS2_VEOL2] : _POSIX_VDISABLE; | 193 | st->c_cc[IBCS2_VEOL2] ? st->c_cc[IBCS2_VEOL2] : _POSIX_VDISABLE; | |
194 | #if 0 | 194 | #if 0 | |
195 | bt->c_cc[VSWTCH] = | 195 | bt->c_cc[VSWTCH] = | |
196 | st->c_cc[IBCS2_VSWTCH] ? st->c_cc[IBCS2_VSWTCH] : _POSIX_VDISABLE; | 196 | st->c_cc[IBCS2_VSWTCH] ? st->c_cc[IBCS2_VSWTCH] : _POSIX_VDISABLE; | |
197 | #endif | 197 | #endif | |
198 | bt->c_cc[VSTART] = | 198 | bt->c_cc[VSTART] = | |
199 | st->c_cc[IBCS2_VSTART] ? st->c_cc[IBCS2_VSTART] : _POSIX_VDISABLE; | 199 | st->c_cc[IBCS2_VSTART] ? st->c_cc[IBCS2_VSTART] : _POSIX_VDISABLE; | |
200 | bt->c_cc[VSTOP] = | 200 | bt->c_cc[VSTOP] = | |
201 | st->c_cc[IBCS2_VSTOP] ? st->c_cc[IBCS2_VSTOP] : _POSIX_VDISABLE; | 201 | st->c_cc[IBCS2_VSTOP] ? st->c_cc[IBCS2_VSTOP] : _POSIX_VDISABLE; | |
202 | bt->c_cc[VSUSP] = | 202 | bt->c_cc[VSUSP] = | |
203 | st->c_cc[IBCS2_VSUSP] ? st->c_cc[IBCS2_VSUSP] : _POSIX_VDISABLE; | 203 | st->c_cc[IBCS2_VSUSP] ? st->c_cc[IBCS2_VSUSP] : _POSIX_VDISABLE; | |
204 | bt->c_cc[VDSUSP] = _POSIX_VDISABLE; | 204 | bt->c_cc[VDSUSP] = _POSIX_VDISABLE; | |
205 | bt->c_cc[VREPRINT] = _POSIX_VDISABLE; | 205 | bt->c_cc[VREPRINT] = _POSIX_VDISABLE; | |
206 | bt->c_cc[VDISCARD] = _POSIX_VDISABLE; | 206 | bt->c_cc[VDISCARD] = _POSIX_VDISABLE; | |
207 | bt->c_cc[VWERASE] = _POSIX_VDISABLE; | 207 | bt->c_cc[VWERASE] = _POSIX_VDISABLE; | |
208 | bt->c_cc[VLNEXT] = _POSIX_VDISABLE; | 208 | bt->c_cc[VLNEXT] = _POSIX_VDISABLE; | |
209 | bt->c_cc[VSTATUS] = _POSIX_VDISABLE; | 209 | bt->c_cc[VSTATUS] = _POSIX_VDISABLE; | |
210 | } | 210 | } | |
211 | 211 | |||
212 | static void | 212 | static void | |
213 | btios2stios(struct termios *bt, struct ibcs2_termios *st) | 213 | btios2stios(struct termios *bt, struct ibcs2_termios *st) | |
214 | { | 214 | { | |
215 | int i; | 215 | int i; | |
216 | u_long l, r; | 216 | u_long l, r; | |
217 | 217 | |||
218 | l = bt->c_iflag; r = 0; | 218 | l = bt->c_iflag; r = 0; | |
219 | if (l & IGNBRK) r |= IBCS2_IGNBRK; | 219 | if (l & IGNBRK) r |= IBCS2_IGNBRK; | |
220 | if (l & BRKINT) r |= IBCS2_BRKINT; | 220 | if (l & BRKINT) r |= IBCS2_BRKINT; | |
221 | if (l & IGNPAR) r |= IBCS2_IGNPAR; | 221 | if (l & IGNPAR) r |= IBCS2_IGNPAR; | |
222 | if (l & PARMRK) r |= IBCS2_PARMRK; | 222 | if (l & PARMRK) r |= IBCS2_PARMRK; | |
223 | if (l & INPCK) r |= IBCS2_INPCK; | 223 | if (l & INPCK) r |= IBCS2_INPCK; | |
224 | if (l & ISTRIP) r |= IBCS2_ISTRIP; | 224 | if (l & ISTRIP) r |= IBCS2_ISTRIP; | |
225 | if (l & INLCR) r |= IBCS2_INLCR; | 225 | if (l & INLCR) r |= IBCS2_INLCR; | |
226 | if (l & IGNCR) r |= IBCS2_IGNCR; | 226 | if (l & IGNCR) r |= IBCS2_IGNCR; | |
227 | if (l & ICRNL) r |= IBCS2_ICRNL; | 227 | if (l & ICRNL) r |= IBCS2_ICRNL; | |
228 | if (l & IXON) r |= IBCS2_IXON; | 228 | if (l & IXON) r |= IBCS2_IXON; | |
229 | if (l & IXANY) r |= IBCS2_IXANY; | 229 | if (l & IXANY) r |= IBCS2_IXANY; | |
230 | if (l & IXOFF) r |= IBCS2_IXOFF; | 230 | if (l & IXOFF) r |= IBCS2_IXOFF; | |
231 | if (l & IMAXBEL) r |= IBCS2_IMAXBEL; | 231 | if (l & IMAXBEL) r |= IBCS2_IMAXBEL; | |
232 | st->c_iflag = r; | 232 | st->c_iflag = r; | |
233 | 233 | |||
234 | l = bt->c_oflag; r = 0; | 234 | l = bt->c_oflag; r = 0; | |
235 | if (l & OPOST) r |= IBCS2_OPOST; | 235 | if (l & OPOST) r |= IBCS2_OPOST; | |
236 | if (l & ONLCR) r |= IBCS2_ONLCR; | 236 | if (l & ONLCR) r |= IBCS2_ONLCR; | |
237 | if (l & OXTABS) r |= IBCS2_TAB3; | 237 | if (l & OXTABS) r |= IBCS2_TAB3; | |
238 | st->c_oflag = r; | 238 | st->c_oflag = r; | |
239 | 239 | |||
240 | l = bt->c_cflag; r = 0; | 240 | l = bt->c_cflag; r = 0; | |
241 | switch (l & CSIZE) { | 241 | switch (l & CSIZE) { | |
242 | case CS5: r |= IBCS2_CS5; break; | 242 | case CS5: r |= IBCS2_CS5; break; | |
243 | case CS6: r |= IBCS2_CS6; break; | 243 | case CS6: r |= IBCS2_CS6; break; | |
244 | case CS7: r |= IBCS2_CS7; break; | 244 | case CS7: r |= IBCS2_CS7; break; | |
245 | case CS8: r |= IBCS2_CS8; break; | 245 | case CS8: r |= IBCS2_CS8; break; | |
246 | } | 246 | } | |
247 | if (l & CSTOPB) r |= IBCS2_CSTOPB; | 247 | if (l & CSTOPB) r |= IBCS2_CSTOPB; | |
248 | if (l & CREAD) r |= IBCS2_CREAD; | 248 | if (l & CREAD) r |= IBCS2_CREAD; | |
249 | if (l & PARENB) r |= IBCS2_PARENB; | 249 | if (l & PARENB) r |= IBCS2_PARENB; | |
250 | if (l & PARODD) r |= IBCS2_PARODD; | 250 | if (l & PARODD) r |= IBCS2_PARODD; | |
251 | if (l & HUPCL) r |= IBCS2_HUPCL; | 251 | if (l & HUPCL) r |= IBCS2_HUPCL; | |
252 | if (l & CLOCAL) r |= IBCS2_CLOCAL; | 252 | if (l & CLOCAL) r |= IBCS2_CLOCAL; | |
253 | st->c_cflag = r; | 253 | st->c_cflag = r; | |
254 | 254 | |||
255 | l = bt->c_lflag; r = 0; | 255 | l = bt->c_lflag; r = 0; | |
256 | if (l & ISIG) r |= IBCS2_ISIG; | 256 | if (l & ISIG) r |= IBCS2_ISIG; | |
257 | if (l & ICANON) r |= IBCS2_ICANON; | 257 | if (l & ICANON) r |= IBCS2_ICANON; | |
258 | if (l & ECHO) r |= IBCS2_ECHO; | 258 | if (l & ECHO) r |= IBCS2_ECHO; | |
259 | if (l & ECHOE) r |= IBCS2_ECHOE; | 259 | if (l & ECHOE) r |= IBCS2_ECHOE; | |
260 | if (l & ECHOK) r |= IBCS2_ECHOK; | 260 | if (l & ECHOK) r |= IBCS2_ECHOK; | |
261 | if (l & ECHONL) r |= IBCS2_ECHONL; | 261 | if (l & ECHONL) r |= IBCS2_ECHONL; | |
262 | if (l & NOFLSH) r |= IBCS2_NOFLSH; | 262 | if (l & NOFLSH) r |= IBCS2_NOFLSH; | |
263 | if (l & TOSTOP) r |= IBCS2_TOSTOP; | 263 | if (l & TOSTOP) r |= IBCS2_TOSTOP; | |
264 | st->c_lflag = r; | 264 | st->c_lflag = r; | |
265 | 265 | |||
266 | i = ttspeedtab(bt->c_ospeed, sptab); | 266 | i = ttspeedtab(bt->c_ospeed, sptab); | |
267 | if (i >= 0) | 267 | if (i >= 0) | |
268 | st->c_cflag |= i; | 268 | st->c_cflag |= i; | |
269 | 269 | |||
270 | st->c_cc[IBCS2_VINTR] = | 270 | st->c_cc[IBCS2_VINTR] = | |
271 | bt->c_cc[VINTR] != _POSIX_VDISABLE ? bt->c_cc[VINTR] : 0; | 271 | bt->c_cc[VINTR] != _POSIX_VDISABLE ? bt->c_cc[VINTR] : 0; | |
272 | st->c_cc[IBCS2_VQUIT] = | 272 | st->c_cc[IBCS2_VQUIT] = | |
273 | bt->c_cc[VQUIT] != _POSIX_VDISABLE ? bt->c_cc[VQUIT] : 0; | 273 | bt->c_cc[VQUIT] != _POSIX_VDISABLE ? bt->c_cc[VQUIT] : 0; | |
274 | st->c_cc[IBCS2_VERASE] = | 274 | st->c_cc[IBCS2_VERASE] = | |
275 | bt->c_cc[VERASE] != _POSIX_VDISABLE ? bt->c_cc[VERASE] : 0; | 275 | bt->c_cc[VERASE] != _POSIX_VDISABLE ? bt->c_cc[VERASE] : 0; | |
276 | st->c_cc[IBCS2_VKILL] = | 276 | st->c_cc[IBCS2_VKILL] = | |
277 | bt->c_cc[VKILL] != _POSIX_VDISABLE ? bt->c_cc[VKILL] : 0; | 277 | bt->c_cc[VKILL] != _POSIX_VDISABLE ? bt->c_cc[VKILL] : 0; | |
278 | if (bt->c_lflag & ICANON) { | 278 | if (bt->c_lflag & ICANON) { | |
279 | st->c_cc[IBCS2_VEOF] = | 279 | st->c_cc[IBCS2_VEOF] = | |
280 | bt->c_cc[VEOF] != _POSIX_VDISABLE ? bt->c_cc[VEOF] : 0; | 280 | bt->c_cc[VEOF] != _POSIX_VDISABLE ? bt->c_cc[VEOF] : 0; | |
281 | st->c_cc[IBCS2_VEOL] = | 281 | st->c_cc[IBCS2_VEOL] = | |
282 | bt->c_cc[VEOL] != _POSIX_VDISABLE ? bt->c_cc[VEOL] : 0; | 282 | bt->c_cc[VEOL] != _POSIX_VDISABLE ? bt->c_cc[VEOL] : 0; | |
283 | } else { | 283 | } else { | |
284 | st->c_cc[IBCS2_VMIN] = bt->c_cc[VMIN]; | 284 | st->c_cc[IBCS2_VMIN] = bt->c_cc[VMIN]; | |
285 | st->c_cc[IBCS2_VTIME] = bt->c_cc[VTIME]; | 285 | st->c_cc[IBCS2_VTIME] = bt->c_cc[VTIME]; | |
286 | } | 286 | } | |
287 | st->c_cc[IBCS2_VEOL2] = | 287 | st->c_cc[IBCS2_VEOL2] = | |
288 | bt->c_cc[VEOL2] != _POSIX_VDISABLE ? bt->c_cc[VEOL2] : 0; | 288 | bt->c_cc[VEOL2] != _POSIX_VDISABLE ? bt->c_cc[VEOL2] : 0; | |
289 | st->c_cc[IBCS2_VSWTCH] = | 289 | st->c_cc[IBCS2_VSWTCH] = | |
290 | 0; | 290 | 0; | |
291 | st->c_cc[IBCS2_VSUSP] = | 291 | st->c_cc[IBCS2_VSUSP] = | |
292 | bt->c_cc[VSUSP] != _POSIX_VDISABLE ? bt->c_cc[VSUSP] : 0; | 292 | bt->c_cc[VSUSP] != _POSIX_VDISABLE ? bt->c_cc[VSUSP] : 0; | |
293 | st->c_cc[IBCS2_VSTART] = | 293 | st->c_cc[IBCS2_VSTART] = | |
294 | bt->c_cc[VSTART] != _POSIX_VDISABLE ? bt->c_cc[VSTART] : 0; | 294 | bt->c_cc[VSTART] != _POSIX_VDISABLE ? bt->c_cc[VSTART] : 0; | |
295 | st->c_cc[IBCS2_VSTOP] = | 295 | st->c_cc[IBCS2_VSTOP] = | |
296 | bt->c_cc[VSTOP] != _POSIX_VDISABLE ? bt->c_cc[VSTOP] : 0; | 296 | bt->c_cc[VSTOP] != _POSIX_VDISABLE ? bt->c_cc[VSTOP] : 0; | |
297 | 297 | |||
298 | st->c_line = 0; | 298 | st->c_line = 0; | |
299 | } | 299 | } | |
300 | 300 | |||
301 | static void | 301 | static void | |
302 | stios2stio(struct ibcs2_termios *ts, struct ibcs2_termio *t) | 302 | stios2stio(struct ibcs2_termios *ts, struct ibcs2_termio *t) | |
303 | { | 303 | { | |
304 | 304 | |||
305 | t->c_iflag = ts->c_iflag; | 305 | t->c_iflag = ts->c_iflag; | |
306 | t->c_oflag = ts->c_oflag; | 306 | t->c_oflag = ts->c_oflag; | |
307 | t->c_cflag = ts->c_cflag; | 307 | t->c_cflag = ts->c_cflag; | |
308 | t->c_lflag = ts->c_lflag; | 308 | t->c_lflag = ts->c_lflag; | |
309 | t->c_line = ts->c_line; | 309 | t->c_line = ts->c_line; | |
310 | memcpy(t->c_cc, ts->c_cc, IBCS2_NCC); | 310 | memcpy(t->c_cc, ts->c_cc, IBCS2_NCC); | |
311 | } | 311 | } | |
312 | 312 | |||
313 | static void | 313 | static void | |
314 | stio2stios(struct ibcs2_termio *t, struct ibcs2_termios *ts) | 314 | stio2stios(struct ibcs2_termio *t, struct ibcs2_termios *ts) | |
315 | { | 315 | { | |
316 | 316 | |||
317 | ts->c_iflag = t->c_iflag; | 317 | ts->c_iflag = t->c_iflag; | |
318 | ts->c_oflag = t->c_oflag; | 318 | ts->c_oflag = t->c_oflag; | |
319 | ts->c_cflag = t->c_cflag; | 319 | ts->c_cflag = t->c_cflag; | |
320 | ts->c_lflag = t->c_lflag; | 320 | ts->c_lflag = t->c_lflag; | |
321 | ts->c_line = t->c_line; | 321 | ts->c_line = t->c_line; | |
322 | memcpy(ts->c_cc, t->c_cc, IBCS2_NCC); | 322 | memcpy(ts->c_cc, t->c_cc, IBCS2_NCC); | |
323 | } | 323 | } | |
324 | 324 | |||
325 | int | 325 | int | |
326 | ibcs2_sys_ioctl(struct lwp *l, const struct ibcs2_sys_ioctl_args *uap, register_t *retval) | 326 | ibcs2_sys_ioctl(struct lwp *l, const struct ibcs2_sys_ioctl_args *uap, register_t *retval) | |
327 | { | 327 | { | |
328 | /* { | 328 | /* { | |
329 | syscallarg(int) fd; | 329 | syscallarg(int) fd; | |
330 | syscallarg(int) cmd; | 330 | syscallarg(int) cmd; | |
331 | syscallarg(void *) data; | 331 | syscallarg(void *) data; | |
332 | } */ | 332 | } */ | |
333 | struct proc *p = l->l_proc; | 333 | struct proc *p = l->l_proc; | |
334 | struct file *fp; | 334 | struct file *fp; | |
335 | int (*ctl)(struct file *, u_long, void *); | 335 | int (*ctl)(struct file *, u_long, void *); | |
336 | struct termios bts; | 336 | struct termios bts; | |
337 | struct ibcs2_termios sts; | 337 | struct ibcs2_termios sts; | |
338 | struct ibcs2_termio st; | 338 | struct ibcs2_termio st; | |
339 | struct sys_ioctl_args bsd_ua; | 339 | struct sys_ioctl_args bsd_ua; | |
340 | int error, t; | 340 | int error, t; | |
341 | 341 | |||
342 | SCARG(&bsd_ua, fd) = SCARG(uap, fd); | 342 | SCARG(&bsd_ua, fd) = SCARG(uap, fd); | |
343 | SCARG(&bsd_ua, data) = SCARG(uap, data); | 343 | SCARG(&bsd_ua, data) = SCARG(uap, data); | |
344 | 344 | |||
345 | /* Handle the easy ones first */ | 345 | /* Handle the easy ones first */ | |
346 | switch ((unsigned long)SCARG(uap, cmd)) { | 346 | switch ((unsigned long)SCARG(uap, cmd)) { | |
347 | case IBCS2_TIOCGWINSZ: | 347 | case IBCS2_TIOCGWINSZ: | |
348 | SCARG(&bsd_ua, com) = TIOCGWINSZ; | 348 | SCARG(&bsd_ua, com) = TIOCGWINSZ; | |
349 | return sys_ioctl(l, &bsd_ua, retval); | 349 | return sys_ioctl(l, &bsd_ua, retval); | |
350 | 350 | |||
351 | case IBCS2_TIOCSWINSZ: | 351 | case IBCS2_TIOCSWINSZ: | |
352 | SCARG(&bsd_ua, com) = TIOCSWINSZ; | 352 | SCARG(&bsd_ua, com) = TIOCSWINSZ; | |
353 | return sys_ioctl(l, &bsd_ua, retval); | 353 | return sys_ioctl(l, &bsd_ua, retval); | |
354 | 354 | |||
355 | case IBCS2_TIOCGPGRP: | 355 | case IBCS2_TIOCGPGRP: | |
356 | return copyout(&p->p_pgrp->pg_id, SCARG(uap, data), | 356 | return copyout(&p->p_pgrp->pg_id, SCARG(uap, data), | |
357 | sizeof(p->p_pgrp->pg_id)); | 357 | sizeof(p->p_pgrp->pg_id)); | |
358 | 358 | |||
359 | case IBCS2_TIOCSPGRP: /* XXX - is uap->data a pointer to pgid? */ | 359 | case IBCS2_TIOCSPGRP: /* XXX - is uap->data a pointer to pgid? */ | |
360 | { | 360 | { | |
361 | struct sys_setpgid_args sa; | 361 | struct sys_setpgid_args sa; | |
362 | 362 | |||
363 | SCARG(&sa, pid) = 0; | 363 | SCARG(&sa, pid) = 0; | |
364 | SCARG(&sa, pgid) = (int)SCARG(uap, data); | 364 | SCARG(&sa, pgid) = (int)SCARG(uap, data); | |
365 | if ((error = sys_setpgid(l, &sa, retval)) != 0) | 365 | if ((error = sys_setpgid(l, &sa, retval)) != 0) | |
366 | return error; | 366 | return error; | |
367 | return 0; | 367 | return 0; | |
368 | } | 368 | } | |
369 | 369 | |||
370 | case IBCS2_TCGETSC: /* SCO console - get scancode flags */ | 370 | case IBCS2_TCGETSC: /* SCO console - get scancode flags */ | |
371 | case IBCS2_TCSETSC: /* SCO console - set scancode flags */ | 371 | case IBCS2_TCSETSC: /* SCO console - set scancode flags */ | |
372 | return ENOSYS; | 372 | return ENOSYS; | |
373 | 373 | |||
374 | case IBCS2_SIOCSOCKSYS: | 374 | case IBCS2_SIOCSOCKSYS: | |
375 | return ibcs2_socksys(l, (const void *)uap, retval); | 375 | return ibcs2_socksys(l, (const void *)uap, retval); | |
376 | 376 | |||
377 | case IBCS2_I_NREAD: /* STREAMS */ | 377 | case IBCS2_I_NREAD: /* STREAMS */ | |
378 | SCARG(&bsd_ua, com) = FIONREAD; | 378 | SCARG(&bsd_ua, com) = FIONREAD; | |
379 | return sys_ioctl(l, &bsd_ua, retval); | 379 | return sys_ioctl(l, &bsd_ua, retval); | |
380 | default: | 380 | default: | |
381 | break; | 381 | break; | |
382 | } | 382 | } | |
383 | 383 | |||
384 | if ((fp = fd_getfile(SCARG(uap, fd))) == NULL) { | 384 | if ((fp = fd_getfile(SCARG(uap, fd))) == NULL) { | |
385 | DPRINTF(("ibcs2_ioctl(%d): bad fd %d ", p->p_pid, | 385 | DPRINTF(("ibcs2_ioctl(%d): bad fd %d ", p->p_pid, | |
386 | SCARG(uap, fd))); | 386 | SCARG(uap, fd))); | |
387 | return EBADF; | 387 | return EBADF; | |
388 | } | 388 | } | |
389 | 389 | |||
390 | if ((fp->f_flag & (FREAD|FWRITE)) == 0) { | 390 | if ((fp->f_flag & (FREAD|FWRITE)) == 0) { | |
391 | DPRINTF(("ibcs2_ioctl(%d): bad fp flag ", p->p_pid)); | 391 | DPRINTF(("ibcs2_ioctl(%d): bad fp flag ", p->p_pid)); | |
392 | error = EBADF; | 392 | error = EBADF; | |
393 | goto out; | 393 | goto out; | |
394 | } | 394 | } | |
395 | 395 | |||
396 | ctl = fp->f_ops->fo_ioctl; | 396 | ctl = fp->f_ops->fo_ioctl; | |
397 | 397 | |||
398 | switch ((unsigned long)SCARG(uap, cmd)) { | 398 | switch ((unsigned long)SCARG(uap, cmd)) { | |
399 | case IBCS2_TCGETA: | 399 | case IBCS2_TCGETA: | |
400 | case IBCS2_XCGETA: | 400 | case IBCS2_XCGETA: | |
401 | case IBCS2_OXCGETA: | 401 | case IBCS2_OXCGETA: | |
402 | if ((error = (*ctl)(fp, TIOCGETA, &bts)) != 0) | 402 | if ((error = (*ctl)(fp, TIOCGETA, &bts)) != 0) | |
403 | goto out; | 403 | goto out; | |
404 | 404 | |||
405 | memset(&sts, 0, sizeof(sts)); | |||
405 | btios2stios(&bts, &sts); | 406 | btios2stios(&bts, &sts); | |
406 | if (SCARG(uap, cmd) == IBCS2_TCGETA) { | 407 | if (SCARG(uap, cmd) == IBCS2_TCGETA) { | |
408 | memset(&st, 0, sizeof(st)); | |||
407 | stios2stio(&sts, &st); | 409 | stios2stio(&sts, &st); | |
408 | error = copyout(&st, SCARG(uap, data), sizeof(st)); | 410 | error = copyout(&st, SCARG(uap, data), sizeof(st)); | |
409 | if (error) | 411 | if (error) | |
410 | DPRINTF(("ibcs2_ioctl(%d): copyout failed ", | 412 | DPRINTF(("ibcs2_ioctl(%d): copyout failed ", | |
411 | p->p_pid)); | 413 | p->p_pid)); | |
412 | } else | 414 | } else | |
413 | error = copyout(&sts, SCARG(uap, data), sizeof(sts)); | 415 | error = copyout(&sts, SCARG(uap, data), sizeof(sts)); | |
414 | break; | 416 | break; | |
415 | 417 | |||
416 | case IBCS2_TCSETA: | 418 | case IBCS2_TCSETA: | |
417 | case IBCS2_TCSETAW: | 419 | case IBCS2_TCSETAW: | |
418 | case IBCS2_TCSETAF: | 420 | case IBCS2_TCSETAF: | |
419 | if ((error = copyin(SCARG(uap, data), &st, sizeof(st))) != 0) { | 421 | if ((error = copyin(SCARG(uap, data), &st, sizeof(st))) != 0) { | |
420 | DPRINTF(("ibcs2_ioctl(%d): TCSET copyin failed ", | 422 | DPRINTF(("ibcs2_ioctl(%d): TCSET copyin failed ", | |
421 | p->p_pid)); | 423 | p->p_pid)); | |
422 | goto out; | 424 | goto out; | |
423 | } | 425 | } | |
424 | 426 | |||
425 | /* get full BSD termios so we don't lose information */ | 427 | /* get full BSD termios so we don't lose information */ | |
426 | if ((error = (*ctl)(fp, TIOCGETA, &bts)) != 0) { | 428 | if ((error = (*ctl)(fp, TIOCGETA, &bts)) != 0) { | |
427 | DPRINTF(("ibcs2_ioctl(%d): TCSET ctl failed fd %d ", | 429 | DPRINTF(("ibcs2_ioctl(%d): TCSET ctl failed fd %d ", | |
428 | p->p_pid, SCARG(uap, fd))); | 430 | p->p_pid, SCARG(uap, fd))); | |
429 | goto out; | 431 | goto out; | |
430 | } | 432 | } | |
431 | 433 | |||
432 | /* | 434 | /* | |
433 | * convert to iBCS2 termios, copy in information from | 435 | * convert to iBCS2 termios, copy in information from | |
434 | * termio, and convert back, then set new values. | 436 | * termio, and convert back, then set new values. | |
435 | */ | 437 | */ | |
436 | btios2stios(&bts, &sts); | 438 | btios2stios(&bts, &sts); | |
437 | stio2stios(&st, &sts); | 439 | stio2stios(&st, &sts); | |
438 | stios2btios(&sts, &bts); | 440 | stios2btios(&sts, &bts); | |
439 | 441 | |||
440 | t = SCARG(uap, cmd) - IBCS2_TCSETA + TIOCSETA; | 442 | t = SCARG(uap, cmd) - IBCS2_TCSETA + TIOCSETA; | |
441 | error = (*ctl)(fp, t, &bts); | 443 | error = (*ctl)(fp, t, &bts); | |
442 | break; | 444 | break; | |
443 | 445 | |||
444 | case IBCS2_XCSETA: | 446 | case IBCS2_XCSETA: | |
445 | case IBCS2_XCSETAW: | 447 | case IBCS2_XCSETAW: | |
446 | case IBCS2_XCSETAF: | 448 | case IBCS2_XCSETAF: | |
447 | if ((error = copyin(SCARG(uap, data), &sts, sizeof(sts))) != 0) | 449 | if ((error = copyin(SCARG(uap, data), &sts, sizeof(sts))) != 0) | |
448 | goto out; | 450 | goto out; | |
449 | 451 | |||
450 | stios2btios(&sts, &bts); | 452 | stios2btios(&sts, &bts); | |
451 | t = SCARG(uap, cmd) - IBCS2_XCSETA + TIOCSETA; | 453 | t = SCARG(uap, cmd) - IBCS2_XCSETA + TIOCSETA; | |
452 | error = (*ctl)(fp, t, &bts); | 454 | error = (*ctl)(fp, t, &bts); | |
453 | break; | 455 | break; | |
454 | 456 | |||
455 | case IBCS2_OXCSETA: | 457 | case IBCS2_OXCSETA: | |
456 | case IBCS2_OXCSETAW: | 458 | case IBCS2_OXCSETAW: | |
457 | case IBCS2_OXCSETAF: | 459 | case IBCS2_OXCSETAF: | |
458 | if ((error = copyin(SCARG(uap, data), &sts, sizeof(sts))) != 0) | 460 | if ((error = copyin(SCARG(uap, data), &sts, sizeof(sts))) != 0) | |
459 | goto out; | 461 | goto out; | |
460 | stios2btios(&sts, &bts); | 462 | stios2btios(&sts, &bts); | |
461 | t = SCARG(uap, cmd) - IBCS2_OXCSETA + TIOCSETA; | 463 | t = SCARG(uap, cmd) - IBCS2_OXCSETA + TIOCSETA; | |
462 | error = (*ctl)(fp, t, &bts); | 464 | error = (*ctl)(fp, t, &bts); | |
463 | break; | 465 | break; | |
464 | 466 | |||
465 | case IBCS2_TCSBRK: | 467 | case IBCS2_TCSBRK: | |
466 | t = (int) SCARG(uap, data); | 468 | t = (int) SCARG(uap, data); | |
467 | t = (t ? t : 1) * hz * 4; | 469 | t = (t ? t : 1) * hz * 4; | |
468 | t /= 10; | 470 | t /= 10; | |
469 | if ((error = (*ctl)(fp, TIOCSBRK, NULL)) != 0) | 471 | if ((error = (*ctl)(fp, TIOCSBRK, NULL)) != 0) | |
470 | goto out; | 472 | goto out; | |
471 | error = tsleep(&t, PZERO | PCATCH, "ibcs2_tcsbrk", t); | 473 | error = tsleep(&t, PZERO | PCATCH, "ibcs2_tcsbrk", t); | |
472 | if (error == EINTR || error == ERESTART) { | 474 | if (error == EINTR || error == ERESTART) { | |
473 | (void)(*ctl)(fp, TIOCCBRK, NULL); | 475 | (void)(*ctl)(fp, TIOCCBRK, NULL); | |
474 | error = EINTR; | 476 | error = EINTR; | |
475 | } else | 477 | } else | |
476 | error = (*ctl)(fp, TIOCCBRK, NULL); | 478 | error = (*ctl)(fp, TIOCCBRK, NULL); | |
477 | break; | 479 | break; | |
478 | 480 | |||
479 | case IBCS2_TCXONC: | 481 | case IBCS2_TCXONC: | |
480 | switch ((int)SCARG(uap, data)) { | 482 | switch ((int)SCARG(uap, data)) { | |
481 | case 0: | 483 | case 0: | |
482 | case 1: | 484 | case 1: | |
483 | DPRINTF(("ibcs2_ioctl(%d): TCXONC ", p->p_pid)); | 485 | DPRINTF(("ibcs2_ioctl(%d): TCXONC ", p->p_pid)); | |
484 | error = ENOSYS; | 486 | error = ENOSYS; | |
485 | break; | 487 | break; | |
486 | case 2: | 488 | case 2: | |
487 | error = (*ctl)(fp, TIOCSTOP, NULL); | 489 | error = (*ctl)(fp, TIOCSTOP, NULL); | |
488 | break; | 490 | break; | |
489 | case 3: | 491 | case 3: | |
490 | error = (*ctl)(fp, TIOCSTART, (void *)1); | 492 | error = (*ctl)(fp, TIOCSTART, (void *)1); | |
491 | break; | 493 | break; | |
492 | default: | 494 | default: | |
493 | error = EINVAL; | 495 | error = EINVAL; | |
494 | break; | 496 | break; | |
495 | } | 497 | } | |
496 | break; | 498 | break; | |
497 | 499 | |||
498 | case IBCS2_TCFLSH: | 500 | case IBCS2_TCFLSH: | |
499 | switch ((int)SCARG(uap, data)) { | 501 | switch ((int)SCARG(uap, data)) { | |
500 | case 0: | 502 | case 0: | |
501 | t = FREAD; | 503 | t = FREAD; | |
502 | break; | 504 | break; | |
503 | case 1: | 505 | case 1: | |
504 | t = FWRITE; | 506 | t = FWRITE; | |
505 | break; | 507 | break; | |
506 | case 2: | 508 | case 2: | |
507 | t = FREAD | FWRITE; | 509 | t = FREAD | FWRITE; | |
508 | break; | 510 | break; | |
509 | default: | 511 | default: | |
510 | error = EINVAL; | 512 | error = EINVAL; | |
511 | goto out; | 513 | goto out; | |
512 | } | 514 | } | |
513 | error = (*ctl)(fp, TIOCFLUSH, &t); | 515 | error = (*ctl)(fp, TIOCFLUSH, &t); | |
514 | break; | 516 | break; | |
515 | 517 | |||
516 | case IBCS2_FIONBIO: | 518 | case IBCS2_FIONBIO: | |
517 | if ((error = copyin(SCARG(uap, data), &t, sizeof(t))) != 0) | 519 | if ((error = copyin(SCARG(uap, data), &t, sizeof(t))) != 0) | |
518 | goto out; | 520 | goto out; | |
519 | error = (*ctl)(fp, FIONBIO, (void *)&t); | 521 | error = (*ctl)(fp, FIONBIO, (void *)&t); | |
520 | break; | 522 | break; | |
521 | 523 | |||
522 | default: | 524 | default: | |
523 | DPRINTF(("ibcs2_ioctl(%d): unknown cmd 0x%x ", | 525 | DPRINTF(("ibcs2_ioctl(%d): unknown cmd 0x%x ", | |
524 | p->p_pid, SCARG(uap, cmd))); | 526 | p->p_pid, SCARG(uap, cmd))); | |
525 | error = ENOSYS; | 527 | error = ENOSYS; | |
526 | break; | 528 | break; | |
527 | } | 529 | } | |
528 | out: | 530 | out: | |
529 | fd_putfile(SCARG(uap, fd)); | 531 | fd_putfile(SCARG(uap, fd)); | |
530 | return error; | 532 | return error; | |
531 | } | 533 | } | |
532 | 534 | |||
533 | int | 535 | int | |
534 | ibcs2_sys_gtty(struct lwp *l, const struct ibcs2_sys_gtty_args *uap, register_t *retval) | 536 | ibcs2_sys_gtty(struct lwp *l, const struct ibcs2_sys_gtty_args *uap, register_t *retval) | |
535 | { | 537 | { | |
536 | /* { | 538 | /* { | |
537 | syscallarg(int) fd; | 539 | syscallarg(int) fd; | |
538 | syscallarg(struct sgttyb *) tb; | 540 | syscallarg(struct sgttyb *) tb; | |
539 | } */ | 541 | } */ | |
540 | struct file *fp; | 542 | struct file *fp; | |
541 | struct sgttyb tb; | 543 | struct sgttyb tb; | |
542 | struct ibcs2_sgttyb itb; | 544 | struct ibcs2_sgttyb itb; | |
543 | int error; | 545 | int error; | |
544 | 546 | |||
545 | if ((fp = fd_getfile(SCARG(uap, fd))) == NULL) { | 547 | if ((fp = fd_getfile(SCARG(uap, fd))) == NULL) { | |
546 | DPRINTF(("ibcs2_sys_gtty(%d): bad fd %d ", curproc->p_pid, | 548 | DPRINTF(("ibcs2_sys_gtty(%d): bad fd %d ", curproc->p_pid, | |
547 | SCARG(uap, fd))); | 549 | SCARG(uap, fd))); | |
548 | return EBADF; | 550 | return EBADF; | |
549 | } | 551 | } | |
550 | if ((fp->f_flag & (FREAD|FWRITE)) == 0) { | 552 | if ((fp->f_flag & (FREAD|FWRITE)) == 0) { | |
551 | DPRINTF(("ibcs2_sys_gtty(%d): bad fp flag ", curproc->p_pid)); | 553 | DPRINTF(("ibcs2_sys_gtty(%d): bad fp flag ", curproc->p_pid)); | |
552 | error = EBADF; | 554 | error = EBADF; | |
553 | goto out; | 555 | goto out; | |
554 | } | 556 | } | |
555 | 557 | |||
556 | error = (*fp->f_ops->fo_ioctl)(fp, TIOCGETP, (void *)&tb); | 558 | error = (*fp->f_ops->fo_ioctl)(fp, TIOCGETP, (void *)&tb); | |
557 | if (error) | 559 | if (error) | |
558 | goto out; | 560 | goto out; | |
559 | 561 | |||
560 | fd_putfile(SCARG(uap, fd)); | 562 | fd_putfile(SCARG(uap, fd)); | |
561 | 563 | |||
564 | memset(&itb, 0, sizeof(itb)); | |||
562 | itb.sg_ispeed = tb.sg_ispeed; | 565 | itb.sg_ispeed = tb.sg_ispeed; | |
563 | itb.sg_ospeed = tb.sg_ospeed; | 566 | itb.sg_ospeed = tb.sg_ospeed; | |
564 | itb.sg_erase = tb.sg_erase; | 567 | itb.sg_erase = tb.sg_erase; | |
565 | itb.sg_kill = tb.sg_kill; | 568 | itb.sg_kill = tb.sg_kill; | |
566 | itb.sg_flags = tb.sg_flags & ~(IBCS2_GHUPCL|IBCS2_GXTABS); | 569 | itb.sg_flags = tb.sg_flags & ~(IBCS2_GHUPCL|IBCS2_GXTABS); | |
567 | return copyout((void *)&itb, SCARG(uap, tb), sizeof(itb)); | 570 | return copyout((void *)&itb, SCARG(uap, tb), sizeof(itb)); | |
568 | out: | 571 | out: | |
569 | fd_putfile(SCARG(uap, fd)); | 572 | fd_putfile(SCARG(uap, fd)); | |
570 | return error; | 573 | return error; | |
571 | } | 574 | } |
--- src/sys/compat/ibcs2/Attic/ibcs2_stat.c 2009/06/29 05:08:16 1.47
+++ src/sys/compat/ibcs2/Attic/ibcs2_stat.c 2017/08/19 04:13:51 1.47.18.1
@@ -1,336 +1,340 @@ | @@ -1,336 +1,340 @@ | |||
1 | /* $NetBSD: ibcs2_stat.c,v 1.47 2009/06/29 05:08:16 dholland Exp $ */ | 1 | /* $NetBSD: ibcs2_stat.c,v 1.47.18.1 2017/08/19 04:13:51 snj Exp $ */ | |
2 | /* | 2 | /* | |
3 | * Copyright (c) 1995, 1998 Scott Bartram | 3 | * Copyright (c) 1995, 1998 Scott Bartram | |
4 | * All rights reserved. | 4 | * All rights reserved. | |
5 | * | 5 | * | |
6 | * Redistribution and use in source and binary forms, with or without | 6 | * Redistribution and use in source and binary forms, with or without | |
7 | * modification, are permitted provided that the following conditions | 7 | * modification, are permitted provided that the following conditions | |
8 | * are met: | 8 | * are met: | |
9 | * 1. Redistributions of source code must retain the above copyright | 9 | * 1. Redistributions of source code must retain the above copyright | |
10 | * notice, this list of conditions and the following disclaimer. | 10 | * notice, this list of conditions and the following disclaimer. | |
11 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright | |
12 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the | |
13 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. | |
14 | * 3. The name of the author may not be used to endorse or promote products | 14 | * 3. The name of the author may not be used to endorse or promote products | |
15 | * derived from this software without specific prior written permission | 15 | * derived from this software without specific prior written permission | |
16 | * | 16 | * | |
17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
27 | */ | 27 | */ | |
28 | 28 | |||
29 | #include <sys/cdefs.h> | 29 | #include <sys/cdefs.h> | |
30 | __KERNEL_RCSID(0, "$NetBSD: ibcs2_stat.c,v 1.47 2009/06/29 05:08:16 dholland Exp $"); | 30 | __KERNEL_RCSID(0, "$NetBSD: ibcs2_stat.c,v 1.47.18.1 2017/08/19 04:13:51 snj Exp $"); | |
31 | 31 | |||
32 | #include <sys/param.h> | 32 | #include <sys/param.h> | |
33 | #include <sys/systm.h> | 33 | #include <sys/systm.h> | |
34 | #include <sys/namei.h> | 34 | #include <sys/namei.h> | |
35 | #include <sys/proc.h> | 35 | #include <sys/proc.h> | |
36 | #include <sys/file.h> | 36 | #include <sys/file.h> | |
37 | #include <sys/stat.h> | 37 | #include <sys/stat.h> | |
38 | #include <sys/filedesc.h> | 38 | #include <sys/filedesc.h> | |
39 | #include <sys/ioctl.h> | 39 | #include <sys/ioctl.h> | |
40 | #include <sys/kernel.h> | 40 | #include <sys/kernel.h> | |
41 | #include <sys/mount.h> | 41 | #include <sys/mount.h> | |
42 | #include <sys/vnode.h> | 42 | #include <sys/vnode.h> | |
43 | #include <sys/syscallargs.h> | 43 | #include <sys/syscallargs.h> | |
44 | #include <sys/vfs_syscalls.h> | 44 | #include <sys/vfs_syscalls.h> | |
45 | 45 | |||
46 | #include <compat/ibcs2/ibcs2_types.h> | 46 | #include <compat/ibcs2/ibcs2_types.h> | |
47 | #include <compat/ibcs2/ibcs2_fcntl.h> | 47 | #include <compat/ibcs2/ibcs2_fcntl.h> | |
48 | #include <compat/ibcs2/ibcs2_signal.h> | 48 | #include <compat/ibcs2/ibcs2_signal.h> | |
49 | #include <compat/ibcs2/ibcs2_stat.h> | 49 | #include <compat/ibcs2/ibcs2_stat.h> | |
50 | #include <compat/ibcs2/ibcs2_statfs.h> | 50 | #include <compat/ibcs2/ibcs2_statfs.h> | |
51 | #include <compat/ibcs2/ibcs2_syscallargs.h> | 51 | #include <compat/ibcs2/ibcs2_syscallargs.h> | |
52 | #include <compat/ibcs2/ibcs2_ustat.h> | 52 | #include <compat/ibcs2/ibcs2_ustat.h> | |
53 | #include <compat/ibcs2/ibcs2_util.h> | 53 | #include <compat/ibcs2/ibcs2_util.h> | |
54 | #include <compat/ibcs2/ibcs2_utsname.h> | 54 | #include <compat/ibcs2/ibcs2_utsname.h> | |
55 | 55 | |||
56 | static void bsd_stat2ibcs_stat(struct stat *, struct ibcs2_stat *); | 56 | static void bsd_stat2ibcs_stat(struct stat *, struct ibcs2_stat *); | |
57 | static int cvt_statfs(struct statvfs *, void *, int); | 57 | static int cvt_statfs(struct statvfs *, void *, int); | |
58 | static int cvt_statvfs(struct statvfs *, void *, int); | 58 | static int cvt_statvfs(struct statvfs *, void *, int); | |
59 | 59 | |||
60 | static void | 60 | static void | |
61 | bsd_stat2ibcs_stat(struct stat *st, struct ibcs2_stat *st4) | 61 | bsd_stat2ibcs_stat(struct stat *st, struct ibcs2_stat *st4) | |
62 | { | 62 | { | |
63 | memset(st4, 0, sizeof(*st4)); | 63 | memset(st4, 0, sizeof(*st4)); | |
64 | st4->st_dev = (ibcs2_dev_t)st->st_dev; | 64 | st4->st_dev = (ibcs2_dev_t)st->st_dev; | |
65 | st4->st_ino = (ibcs2_ino_t)st->st_ino; | 65 | st4->st_ino = (ibcs2_ino_t)st->st_ino; | |
66 | st4->st_mode = (ibcs2_mode_t)st->st_mode; | 66 | st4->st_mode = (ibcs2_mode_t)st->st_mode; | |
67 | if (st->st_nlink >= (1 << 15)) | 67 | if (st->st_nlink >= (1 << 15)) | |
68 | st4->st_nlink = (1 << 15) - 1; | 68 | st4->st_nlink = (1 << 15) - 1; | |
69 | else | 69 | else | |
70 | st4->st_nlink = (ibcs2_nlink_t)st->st_nlink; | 70 | st4->st_nlink = (ibcs2_nlink_t)st->st_nlink; | |
71 | st4->st_uid = (ibcs2_uid_t)st->st_uid; | 71 | st4->st_uid = (ibcs2_uid_t)st->st_uid; | |
72 | st4->st_gid = (ibcs2_gid_t)st->st_gid; | 72 | st4->st_gid = (ibcs2_gid_t)st->st_gid; | |
73 | st4->st_rdev = (ibcs2_dev_t)st->st_rdev; | 73 | st4->st_rdev = (ibcs2_dev_t)st->st_rdev; | |
74 | st4->st_size = (ibcs2_off_t)st->st_size; | 74 | st4->st_size = (ibcs2_off_t)st->st_size; | |
75 | st4->st_atim = (ibcs2_time_t)st->st_atime; | 75 | st4->st_atim = (ibcs2_time_t)st->st_atime; | |
76 | st4->st_mtim = (ibcs2_time_t)st->st_mtime; | 76 | st4->st_mtim = (ibcs2_time_t)st->st_mtime; | |
77 | st4->st_ctim = (ibcs2_time_t)st->st_ctime; | 77 | st4->st_ctim = (ibcs2_time_t)st->st_ctime; | |
78 | } | 78 | } | |
79 | 79 | |||
80 | static int | 80 | static int | |
81 | cvt_statfs(struct statvfs *sp, void *tbuf, int len) | 81 | cvt_statfs(struct statvfs *sp, void *tbuf, int len) | |
82 | { | 82 | { | |
83 | struct ibcs2_statfs ssfs; | 83 | struct ibcs2_statfs ssfs; | |
84 | 84 | |||
85 | if (len < 0) | 85 | if (len < 0) | |
86 | return (EINVAL); | 86 | return (EINVAL); | |
87 | if (len > sizeof(ssfs)) | 87 | if (len > sizeof(ssfs)) | |
88 | len = sizeof(ssfs); | 88 | len = sizeof(ssfs); | |
89 | 89 | |||
90 | memset(&ssfs, 0, sizeof ssfs); | 90 | memset(&ssfs, 0, sizeof ssfs); | |
91 | ssfs.f_fstyp = 0; | 91 | ssfs.f_fstyp = 0; | |
92 | ssfs.f_bsize = sp->f_bsize; | 92 | ssfs.f_bsize = sp->f_bsize; | |
93 | ssfs.f_frsize = sp->f_frsize; | 93 | ssfs.f_frsize = sp->f_frsize; | |
94 | ssfs.f_blocks = sp->f_blocks; | 94 | ssfs.f_blocks = sp->f_blocks; | |
95 | ssfs.f_bfree = sp->f_bfree; | 95 | ssfs.f_bfree = sp->f_bfree; | |
96 | ssfs.f_files = sp->f_files; | 96 | ssfs.f_files = sp->f_files; | |
97 | ssfs.f_ffree = sp->f_ffree; | 97 | ssfs.f_ffree = sp->f_ffree; | |
98 | ssfs.f_fname[0] = 0; | 98 | ssfs.f_fname[0] = 0; | |
99 | ssfs.f_fpack[0] = 0; | 99 | ssfs.f_fpack[0] = 0; | |
100 | return copyout((void *)&ssfs, tbuf, len); | 100 | return copyout((void *)&ssfs, tbuf, len); | |
101 | } | 101 | } | |
102 | 102 | |||
103 | static int | 103 | static int | |
104 | cvt_statvfs(struct statvfs *sp, void *tbuf, int len) | 104 | cvt_statvfs(struct statvfs *sp, void *tbuf, int len) | |
105 | { | 105 | { | |
106 | struct ibcs2_statvfs ssvfs; | 106 | struct ibcs2_statvfs ssvfs; | |
107 | 107 | |||
108 | if (len < 0) | 108 | if (len < 0) | |
109 | return (EINVAL); | 109 | return (EINVAL); | |
110 | if (len > sizeof(ssvfs)) | 110 | if (len > sizeof(ssvfs)) | |
111 | len = sizeof(ssvfs); | 111 | len = sizeof(ssvfs); | |
112 | 112 | |||
113 | memset(&ssvfs, 0, sizeof ssvfs); | 113 | memset(&ssvfs, 0, sizeof ssvfs); | |
114 | ssvfs.f_bsize = sp->f_bsize; | 114 | ssvfs.f_bsize = sp->f_bsize; | |
115 | ssvfs.f_frsize = sp->f_frsize; | 115 | ssvfs.f_frsize = sp->f_frsize; | |
116 | ssvfs.f_blocks = sp->f_blocks; | 116 | ssvfs.f_blocks = sp->f_blocks; | |
117 | ssvfs.f_bfree = sp->f_bfree; | 117 | ssvfs.f_bfree = sp->f_bfree; | |
118 | ssvfs.f_bavail = sp->f_bavail; | 118 | ssvfs.f_bavail = sp->f_bavail; | |
119 | ssvfs.f_files = sp->f_files; | 119 | ssvfs.f_files = sp->f_files; | |
120 | ssvfs.f_ffree = sp->f_ffree; | 120 | ssvfs.f_ffree = sp->f_ffree; | |
121 | ssvfs.f_favail = sp->f_favail; | 121 | ssvfs.f_favail = sp->f_favail; | |
122 | ssvfs.f_fsid = sp->f_fsidx.__fsid_val[0]; | 122 | ssvfs.f_fsid = sp->f_fsidx.__fsid_val[0]; | |
123 | strncpy(ssvfs.f_basetype, sp->f_fstypename, 15); | 123 | strncpy(ssvfs.f_basetype, sp->f_fstypename, 15); | |
124 | ssvfs.f_flag = 0; | 124 | ssvfs.f_flag = 0; | |
125 | ssvfs.f_namemax = PATH_MAX; | 125 | ssvfs.f_namemax = PATH_MAX; | |
126 | ssvfs.f_fstr[0] = 0; | 126 | ssvfs.f_fstr[0] = 0; | |
127 | return copyout((void *)&ssvfs, tbuf, len); | 127 | return copyout((void *)&ssvfs, tbuf, len); | |
128 | } | 128 | } | |
129 | 129 | |||
130 | int | 130 | int | |
131 | ibcs2_sys_statfs(struct lwp *l, const struct ibcs2_sys_statfs_args *uap, register_t *retval) | 131 | ibcs2_sys_statfs(struct lwp *l, const struct ibcs2_sys_statfs_args *uap, register_t *retval) | |
132 | { | 132 | { | |
133 | /* { | 133 | /* { | |
134 | syscallarg(const char *) path; | 134 | syscallarg(const char *) path; | |
135 | syscallarg(struct ibcs2_statfs *) buf; | 135 | syscallarg(struct ibcs2_statfs *) buf; | |
136 | syscallarg(int) len; | 136 | syscallarg(int) len; | |
137 | syscallarg(int) fstype; | 137 | syscallarg(int) fstype; | |
138 | } */ | 138 | } */ | |
139 | struct mount *mp; | 139 | struct mount *mp; | |
140 | struct statvfs *sp; | 140 | struct statvfs *sp; | |
141 | int error; | 141 | int error; | |
142 | struct vnode *vp; | 142 | struct vnode *vp; | |
143 | 143 | |||
144 | error = namei_simple_user(SCARG(uap, path), | 144 | error = namei_simple_user(SCARG(uap, path), | |
145 | NSM_FOLLOW_TRYEMULROOT, &vp); | 145 | NSM_FOLLOW_TRYEMULROOT, &vp); | |
146 | if (error != 0) | 146 | if (error != 0) | |
147 | return (error); | 147 | return (error); | |
148 | mp = vp->v_mount; | 148 | mp = vp->v_mount; | |
149 | sp = &mp->mnt_stat; | 149 | sp = &mp->mnt_stat; | |
150 | vrele(vp); | |||
151 | if ((error = VFS_STATVFS(mp, sp)) != 0) | 150 | if ((error = VFS_STATVFS(mp, sp)) != 0) | |
152 | return (error); | 151 | goto out; | |
153 | sp->f_flag = mp->mnt_flag & MNT_VISFLAGMASK; | 152 | sp->f_flag = mp->mnt_flag & MNT_VISFLAGMASK; | |
154 | return cvt_statfs(sp, (void *)SCARG(uap, buf), SCARG(uap, len)); | 153 | error = cvt_statfs(sp, (void *)SCARG(uap, buf), SCARG(uap, len)); | |
154 | out: | |||
155 | vrele(vp); | |||
156 | return (error); | |||
155 | } | 157 | } | |
156 | 158 | |||
157 | int | 159 | int | |
158 | ibcs2_sys_fstatfs(struct lwp *l, const struct ibcs2_sys_fstatfs_args *uap, register_t *retval) | 160 | ibcs2_sys_fstatfs(struct lwp *l, const struct ibcs2_sys_fstatfs_args *uap, register_t *retval) | |
159 | { | 161 | { | |
160 | /* { | 162 | /* { | |
161 | syscallarg(int) fd; | 163 | syscallarg(int) fd; | |
162 | syscallarg(struct ibcs2_statfs *) buf; | 164 | syscallarg(struct ibcs2_statfs *) buf; | |
163 | syscallarg(int) len; | 165 | syscallarg(int) len; | |
164 | syscallarg(int) fstype; | 166 | syscallarg(int) fstype; | |
165 | } */ | 167 | } */ | |
166 | file_t *fp; | 168 | file_t *fp; | |
167 | struct mount *mp; | 169 | struct mount *mp; | |
168 | struct statvfs *sp; | 170 | struct statvfs *sp; | |
169 | int error; | 171 | int error; | |
170 | 172 | |||
171 | /* fd_getvnode() will use the descriptor for us */ | 173 | /* fd_getvnode() will use the descriptor for us */ | |
172 | if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0) | 174 | if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0) | |
173 | return (error); | 175 | return (error); | |
174 | mp = ((struct vnode *)fp->f_data)->v_mount; | 176 | mp = ((struct vnode *)fp->f_data)->v_mount; | |
175 | sp = &mp->mnt_stat; | 177 | sp = &mp->mnt_stat; | |
176 | if ((error = VFS_STATVFS(mp, sp)) != 0) | 178 | if ((error = VFS_STATVFS(mp, sp)) != 0) | |
177 | goto out; | 179 | goto out; | |
178 | sp->f_flag = mp->mnt_flag & MNT_VISFLAGMASK; | 180 | sp->f_flag = mp->mnt_flag & MNT_VISFLAGMASK; | |
179 | error = cvt_statfs(sp, (void *)SCARG(uap, buf), SCARG(uap, len)); | 181 | error = cvt_statfs(sp, (void *)SCARG(uap, buf), SCARG(uap, len)); | |
180 | out: | 182 | out: | |
181 | fd_putfile(SCARG(uap, fd)); | 183 | fd_putfile(SCARG(uap, fd)); | |
182 | return (error); | 184 | return (error); | |
183 | } | 185 | } | |
184 | 186 | |||
185 | int | 187 | int | |
186 | ibcs2_sys_statvfs(struct lwp *l, const struct ibcs2_sys_statvfs_args *uap, register_t *retval) | 188 | ibcs2_sys_statvfs(struct lwp *l, const struct ibcs2_sys_statvfs_args *uap, register_t *retval) | |
187 | { | 189 | { | |
188 | /* { | 190 | /* { | |
189 | syscallarg(const char *) path; | 191 | syscallarg(const char *) path; | |
190 | syscallarg(struct ibcs2_statvfs *) buf; | 192 | syscallarg(struct ibcs2_statvfs *) buf; | |
191 | } */ | 193 | } */ | |
192 | struct mount *mp; | 194 | struct mount *mp; | |
193 | struct statvfs *sp; | 195 | struct statvfs *sp; | |
194 | int error; | 196 | int error; | |
195 | struct vnode *vp; | 197 | struct vnode *vp; | |
196 | 198 | |||
197 | error = namei_simple_user(SCARG(uap, path), | 199 | error = namei_simple_user(SCARG(uap, path), | |
198 | NSM_FOLLOW_TRYEMULROOT, &vp); | 200 | NSM_FOLLOW_TRYEMULROOT, &vp); | |
199 | if (error != 0) | 201 | if (error != 0) | |
200 | return (error); | 202 | return (error); | |
201 | mp = vp->v_mount; | 203 | mp = vp->v_mount; | |
202 | sp = &mp->mnt_stat; | 204 | sp = &mp->mnt_stat; | |
203 | vrele(vp); | |||
204 | if ((error = VFS_STATVFS(mp, sp)) != 0) | 205 | if ((error = VFS_STATVFS(mp, sp)) != 0) | |
205 | return (error); | 206 | goto out; | |
206 | sp->f_flag = mp->mnt_flag & MNT_VISFLAGMASK; | 207 | sp->f_flag = mp->mnt_flag & MNT_VISFLAGMASK; | |
207 | return cvt_statvfs(sp, (void *)SCARG(uap, buf), | 208 | error = cvt_statvfs(sp, (void *)SCARG(uap, buf), | |
208 | sizeof(struct ibcs2_statvfs)); | 209 | sizeof(struct ibcs2_statvfs)); | |
210 | out: | |||
211 | vrele(vp); | |||
212 | return error; | |||
209 | } | 213 | } | |
210 | 214 | |||
211 | int | 215 | int | |
212 | ibcs2_sys_fstatvfs(struct lwp *l, const struct ibcs2_sys_fstatvfs_args *uap, register_t *retval) | 216 | ibcs2_sys_fstatvfs(struct lwp *l, const struct ibcs2_sys_fstatvfs_args *uap, register_t *retval) | |
213 | { | 217 | { | |
214 | /* { | 218 | /* { | |
215 | syscallarg(int) fd; | 219 | syscallarg(int) fd; | |
216 | syscallarg(struct ibcs2_statvfs *) buf; | 220 | syscallarg(struct ibcs2_statvfs *) buf; | |
217 | } */ | 221 | } */ | |
218 | file_t *fp; | 222 | file_t *fp; | |
219 | struct mount *mp; | 223 | struct mount *mp; | |
220 | struct statvfs *sp; | 224 | struct statvfs *sp; | |
221 | int error; | 225 | int error; | |
222 | 226 | |||
223 | /* fd_getvnode() will use the descriptor for us */ | 227 | /* fd_getvnode() will use the descriptor for us */ | |
224 | if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0) | 228 | if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0) | |
225 | return (error); | 229 | return (error); | |
226 | mp = ((struct vnode *)fp->f_data)->v_mount; | 230 | mp = ((struct vnode *)fp->f_data)->v_mount; | |
227 | sp = &mp->mnt_stat; | 231 | sp = &mp->mnt_stat; | |
228 | if ((error = VFS_STATVFS(mp, sp)) != 0) | 232 | if ((error = VFS_STATVFS(mp, sp)) != 0) | |
229 | goto out; | 233 | goto out; | |
230 | sp->f_flag = mp->mnt_flag & MNT_VISFLAGMASK; | 234 | sp->f_flag = mp->mnt_flag & MNT_VISFLAGMASK; | |
231 | error = cvt_statvfs(sp, SCARG(uap, buf), sizeof(struct ibcs2_statvfs)); | 235 | error = cvt_statvfs(sp, SCARG(uap, buf), sizeof(struct ibcs2_statvfs)); | |
232 | out: | 236 | out: | |
233 | fd_putfile(SCARG(uap, fd)); | 237 | fd_putfile(SCARG(uap, fd)); | |
234 | return (error); | 238 | return (error); | |
235 | } | 239 | } | |
236 | 240 | |||
237 | int | 241 | int | |
238 | ibcs2_sys_stat(struct lwp *l, const struct ibcs2_sys_stat_args *uap, register_t *retval) | 242 | ibcs2_sys_stat(struct lwp *l, const struct ibcs2_sys_stat_args *uap, register_t *retval) | |
239 | { | 243 | { | |
240 | /* { | 244 | /* { | |
241 | syscallarg(const char *) path; | 245 | syscallarg(const char *) path; | |
242 | syscallarg(struct ibcs2_stat *) st; | 246 | syscallarg(struct ibcs2_stat *) st; | |
243 | } */ | 247 | } */ | |
244 | struct stat sb; | 248 | struct stat sb; | |
245 | struct ibcs2_stat ibcs2_st; | 249 | struct ibcs2_stat ibcs2_st; | |
246 | int error; | 250 | int error; | |
247 | 251 | |||
248 | error = do_sys_stat(SCARG(uap, path), FOLLOW, &sb); | 252 | error = do_sys_stat(SCARG(uap, path), FOLLOW, &sb); | |
249 | if (error != 0) | 253 | if (error != 0) | |
250 | return error; | 254 | return error; | |
251 | 255 | |||
252 | bsd_stat2ibcs_stat(&sb, &ibcs2_st); | 256 | bsd_stat2ibcs_stat(&sb, &ibcs2_st); | |
253 | return copyout(&ibcs2_st, SCARG(uap, st), sizeof (ibcs2_st)); | 257 | return copyout(&ibcs2_st, SCARG(uap, st), sizeof (ibcs2_st)); | |
254 | } | 258 | } | |
255 | 259 | |||
256 | int | 260 | int | |
257 | ibcs2_sys_lstat(struct lwp *l, const struct ibcs2_sys_lstat_args *uap, register_t *retval) | 261 | ibcs2_sys_lstat(struct lwp *l, const struct ibcs2_sys_lstat_args *uap, register_t *retval) | |
258 | { | 262 | { | |
259 | /* { | 263 | /* { | |
260 | syscallarg(const char *) path; | 264 | syscallarg(const char *) path; | |
261 | syscallarg(struct ibcs2_stat *) st; | 265 | syscallarg(struct ibcs2_stat *) st; | |
262 | } */ | 266 | } */ | |
263 | struct stat sb; | 267 | struct stat sb; | |
264 | struct ibcs2_stat ibcs2_st; | 268 | struct ibcs2_stat ibcs2_st; | |
265 | int error; | 269 | int error; | |
266 | 270 | |||
267 | error = do_sys_stat(SCARG(uap, path), NOFOLLOW, &sb); | 271 | error = do_sys_stat(SCARG(uap, path), NOFOLLOW, &sb); | |
268 | if (error != 0) | 272 | if (error != 0) | |
269 | return error; | 273 | return error; | |
270 | 274 | |||
271 | bsd_stat2ibcs_stat(&sb, &ibcs2_st); | 275 | bsd_stat2ibcs_stat(&sb, &ibcs2_st); | |
272 | return copyout((void *)&ibcs2_st, (void *)SCARG(uap, st), | 276 | return copyout((void *)&ibcs2_st, (void *)SCARG(uap, st), | |
273 | sizeof (ibcs2_st)); | 277 | sizeof (ibcs2_st)); | |
274 | } | 278 | } | |
275 | 279 | |||
276 | int | 280 | int | |
277 | ibcs2_sys_fstat(struct lwp *l, const struct ibcs2_sys_fstat_args *uap, register_t *retval) | 281 | ibcs2_sys_fstat(struct lwp *l, const struct ibcs2_sys_fstat_args *uap, register_t *retval) | |
278 | { | 282 | { | |
279 | /* { | 283 | /* { | |
280 | syscallarg(int) fd; | 284 | syscallarg(int) fd; | |
281 | syscallarg(struct ibcs2_stat *) st; | 285 | syscallarg(struct ibcs2_stat *) st; | |
282 | } */ | 286 | } */ | |
283 | struct stat sb; | 287 | struct stat sb; | |
284 | struct ibcs2_stat ibcs2_st; | 288 | struct ibcs2_stat ibcs2_st; | |
285 | int error; | 289 | int error; | |
286 | 290 | |||
287 | error = do_sys_fstat(SCARG(uap, fd), &sb); | 291 | error = do_sys_fstat(SCARG(uap, fd), &sb); | |
288 | if (error != 0) | 292 | if (error != 0) | |
289 | return error; | 293 | return error; | |
290 | 294 | |||
291 | bsd_stat2ibcs_stat(&sb, &ibcs2_st); | 295 | bsd_stat2ibcs_stat(&sb, &ibcs2_st); | |
292 | return copyout(&ibcs2_st, SCARG(uap, st), sizeof (ibcs2_st)); | 296 | return copyout(&ibcs2_st, SCARG(uap, st), sizeof (ibcs2_st)); | |
293 | } | 297 | } | |
294 | 298 | |||
295 | int | 299 | int | |
296 | ibcs2_sys_utssys(struct lwp *l, const struct ibcs2_sys_utssys_args *uap, register_t *retval) | 300 | ibcs2_sys_utssys(struct lwp *l, const struct ibcs2_sys_utssys_args *uap, register_t *retval) | |
297 | { | 301 | { | |
298 | /* { | 302 | /* { | |
299 | syscallarg(int) a1; | 303 | syscallarg(int) a1; | |
300 | syscallarg(int) a2; | 304 | syscallarg(int) a2; | |
301 | syscallarg(int) flag; | 305 | syscallarg(int) flag; | |
302 | } */ | 306 | } */ | |
303 | 307 | |||
304 | switch (SCARG(uap, flag)) { | 308 | switch (SCARG(uap, flag)) { | |
305 | case 0: /* uname(struct utsname *) */ | 309 | case 0: /* uname(struct utsname *) */ | |
306 | { | 310 | { | |
307 | struct ibcs2_utsname sut; | 311 | struct ibcs2_utsname sut; | |
308 | 312 | |||
309 | memset(&sut, 0, ibcs2_utsname_len); | 313 | memset(&sut, 0, ibcs2_utsname_len); | |
310 | memcpy(sut.sysname, ostype, sizeof(sut.sysname) - 1); | 314 | memcpy(sut.sysname, ostype, sizeof(sut.sysname) - 1); | |
311 | memcpy(sut.nodename, hostname, sizeof(sut.nodename)); | 315 | memcpy(sut.nodename, hostname, sizeof(sut.nodename)); | |
312 | sut.nodename[sizeof(sut.nodename)-1] = '\0'; | 316 | sut.nodename[sizeof(sut.nodename)-1] = '\0'; | |
313 | memcpy(sut.release, osrelease, sizeof(sut.release) - 1); | 317 | memcpy(sut.release, osrelease, sizeof(sut.release) - 1); | |
314 | strlcpy(sut.version, "1", sizeof(sut.version)); | 318 | strlcpy(sut.version, "1", sizeof(sut.version)); | |
315 | memcpy(sut.machine, machine, sizeof(sut.machine) - 1); | 319 | memcpy(sut.machine, machine, sizeof(sut.machine) - 1); | |
316 | 320 | |||
317 | return copyout((void *)&sut, (void *)SCARG(uap, a1), | 321 | return copyout((void *)&sut, (void *)SCARG(uap, a1), | |
318 | ibcs2_utsname_len); | 322 | ibcs2_utsname_len); | |
319 | } | 323 | } | |
320 | 324 | |||
321 | case 2: /* ustat(dev_t, struct ustat *) */ | 325 | case 2: /* ustat(dev_t, struct ustat *) */ | |
322 | { | 326 | { | |
323 | struct ibcs2_ustat xu; | 327 | struct ibcs2_ustat xu; | |
324 | 328 | |||
325 | xu.f_tfree = 20000; /* XXX fixme */ | 329 | xu.f_tfree = 20000; /* XXX fixme */ | |
326 | xu.f_tinode = 32000; | 330 | xu.f_tinode = 32000; | |
327 | xu.f_fname[0] = 0; | 331 | xu.f_fname[0] = 0; | |
328 | xu.f_fpack[0] = 0; | 332 | xu.f_fpack[0] = 0; | |
329 | return copyout((void *)&xu, (void *)SCARG(uap, a2), | 333 | return copyout((void *)&xu, (void *)SCARG(uap, a2), | |
330 | ibcs2_ustat_len); | 334 | ibcs2_ustat_len); | |
331 | } | 335 | } | |
332 | 336 | |||
333 | default: | 337 | default: | |
334 | return ENOSYS; | 338 | return ENOSYS; | |
335 | } | 339 | } | |
336 | } | 340 | } |