ultrix_pathname.c revision 1.11.2.3 1 /* $NetBSD: ultrix_pathname.c,v 1.11.2.3 2001/12/06 10:03:55 wdk Exp $ */
2
3 /*
4 * Copyright (c) 1992, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This software was developed by the Computer Systems Engineering group
8 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
9 * contributed to Berkeley.
10 *
11 * All advertising materials mentioning features or use of this software
12 * must display the following acknowledgement:
13 * This product includes software developed by the University of
14 * California, Lawrence Berkeley Laboratory.
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
24 * 3. All advertising materials mentioning features or use of this software
25 * must display the following acknowledgement:
26 * This product includes software developed by the University of
27 * California, Berkeley and its contributors.
28 * 4. Neither the name of the University nor the names of its contributors
29 * may be used to endorse or promote products derived from this software
30 * without specific prior written permission.
31 *
32 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
33 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
36 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
40 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
41 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
42 * SUCH DAMAGE.
43 *
44 *
45 * @(#)sun_misc.c 8.1 (Berkeley) 6/18/93
46 *
47 * from: Header: sun_misc.c,v 1.16 93/04/07 02:46:27 torek Exp
48 */
49
50
51 /*
52 * Ultrix emulation filesystem-namespace compatibility module.
53 *
54 * Ultrix system calls that examine the filesysten namespace
55 * are implemented here. Each system call has a wrapper that
56 * first checks if the given file exists at a special `emulation'
57 * pathname: the given path, prefixex with '/emul/ultrix', and
58 * if that pathname exists, it is used instead of the providd pathname.
59 *
60 * Used to locate OS-specific files (shared libraries, config files,
61 * etc) used by emul processes at their `normal' pathnames, without
62 * polluting, or conflicting with, the native filesysten namespace.
63 */
64
65 #include <sys/cdefs.h>
66 __KERNEL_RCSID(0, "$NetBSD: ultrix_pathname.c,v 1.11.2.3 2001/12/06 10:03:55 wdk Exp $");
67
68 #include <sys/param.h>
69 #include <sys/systm.h>
70 #include <sys/namei.h>
71 #include <sys/file.h>
72 #include <sys/filedesc.h>
73 #include <sys/ioctl.h>
74 #include <sys/mount.h>
75 #include <sys/stat.h>
76 #include <sys/vnode.h>
77 #include <sys/syscallargs.h>
78 #include <sys/proc.h>
79
80 #include <compat/ultrix/ultrix_syscallargs.h>
81 #include <compat/common/compat_util.h>
82
83 static int ultrixstatfs __P((struct statfs *sp, caddr_t buf));
84
85 int
86 ultrix_sys_creat(l, v, retval)
87 struct lwp *l;
88 void *v;
89 register_t *retval;
90 {
91 struct ultrix_sys_creat_args *uap = v;
92 struct sys_open_args ap;
93 struct proc *p = l->l_proc;
94
95 caddr_t sg = stackgap_init(p->p_emul);
96 CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
97
98 SCARG(&ap, path) = SCARG(uap, path);
99 SCARG(&ap, flags) = O_WRONLY | O_CREAT | O_TRUNC;
100 SCARG(&ap, mode) = SCARG(uap, mode);
101
102 return (sys_open(l, &ap, retval));
103 }
104
105
106 int
107 ultrix_sys_access(l, v, retval)
108 struct lwp *l;
109 void *v;
110 register_t *retval;
111 {
112 struct ultrix_sys_access_args *uap = v;
113 struct proc *p = l->l_proc;
114 caddr_t sg = stackgap_init(p->p_emul);
115 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
116
117 return (sys_access(l, uap, retval));
118 }
119
120 int
121 ultrix_sys_stat(l, v, retval)
122 struct lwp *l;
123 void *v;
124 register_t *retval;
125 {
126 struct ultrix_sys_stat_args *uap = v;
127 struct proc *p = l->l_proc;
128 caddr_t sg = stackgap_init(p->p_emul);
129 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
130
131 return (compat_43_sys_stat(l, uap, retval));
132 }
133
134 int
135 ultrix_sys_lstat(l, v, retval)
136 struct lwp *l;
137 void *v;
138 register_t *retval;
139 {
140 struct ultrix_sys_lstat_args *uap = v;
141 struct proc *p = l->l_proc;
142 caddr_t sg = stackgap_init(p->p_emul);
143 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
144
145 return (compat_43_sys_lstat(l, uap, retval));
146 }
147
148 int
149 ultrix_sys_execv(l, v, retval)
150 struct lwp *l;
151 void *v;
152 register_t *retval;
153 {
154 struct ultrix_sys_execv_args /* {
155 syscallarg(const char *) path;
156 syscallarg(char **) argv;
157 } */ *uap = v;
158 struct proc *p = l->l_proc;
159 struct sys_execve_args ap;
160 caddr_t sg;
161
162 sg = stackgap_init(p->p_emul);
163 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
164
165 SCARG(&ap, path) = SCARG(uap, path);
166 SCARG(&ap, argp) = SCARG(uap, argp);
167 SCARG(&ap, envp) = NULL;
168
169 return (sys_execve(l, &ap, retval));
170 }
171
172 int
173 ultrix_sys_execve(l, v, retval)
174 struct lwp *l;
175 void *v;
176 register_t *retval;
177 {
178 struct ultrix_sys_execve_args /* {
179 syscallarg(const char *) path;
180 syscallarg(char **) argv;
181 syscallarg(char **) envp;
182 } */ *uap = v;
183 struct proc *p = l->l_proc;
184 struct sys_execve_args ap;
185 caddr_t sg;
186
187 sg = stackgap_init(p->p_emul);
188 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
189
190 SCARG(&ap, path) = SCARG(uap, path);
191 SCARG(&ap, argp) = SCARG(uap, argp);
192 SCARG(&ap, envp) = SCARG(uap, envp);
193
194 return (sys_execve(l, &ap, retval));
195 }
196
197 int
198 ultrix_sys_open(l, v, retval)
199 struct lwp *l;
200 void *v;
201 register_t *retval;
202 {
203 struct ultrix_sys_open_args *uap = v;
204 struct proc *p = l->l_proc;
205 int q, r;
206 int noctty;
207 int ret;
208
209 caddr_t sg = stackgap_init(p->p_emul);
210
211 /* convert open flags into NetBSD flags */
212 q = SCARG(uap, flags);
213 noctty = q & 0x8000;
214 r = (q & (0x0001 | 0x0002 | 0x0008 | 0x0040 | 0x0200 | 0x0400 | 0x0800));
215 r |= ((q & (0x0004 | 0x1000 | 0x4000)) ? O_NONBLOCK : 0);
216 r |= ((q & 0x0080) ? O_SHLOCK : 0);
217 r |= ((q & 0x0100) ? O_EXLOCK : 0);
218 r |= ((q & 0x2000) ? O_FSYNC : 0);
219
220 if (r & O_CREAT)
221 CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
222 else
223 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
224 SCARG(uap, flags) = r;
225 ret = sys_open(l, (struct sys_open_args *)uap, retval);
226
227 if (!ret && !noctty && SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) {
228 struct filedesc *fdp = p->p_fd;
229 struct file *fp;
230
231 fp = fd_getfile(fdp, *retval);
232
233 /* ignore any error, just give it a try */
234 if (fp != NULL && fp->f_type == DTYPE_VNODE)
235 (fp->f_ops->fo_ioctl)(fp, TIOCSCTTY, (caddr_t)0, p);
236 }
237 return ret;
238 }
239
240
241 struct ultrix_statfs {
242 long f_type; /* type of info, zero for now */
243 long f_bsize; /* fundamental file system block size */
244 long f_blocks; /* total blocks in file system */
245 long f_bfree; /* free blocks */
246 long f_bavail; /* free blocks available to non-super-user */
247 long f_files; /* total file nodes in file system */
248 long f_ffree; /* free file nodes in fs */
249 fsid_t f_fsid; /* file system id */
250 long f_spare[7]; /* spare for later */
251 };
252
253 /*
254 * Custruct ultrix statfs result from native.
255 * XXX should this be the same as returned by Ultrix getmnt(2)?
256 * XXX Ultrix predates DEV_BSIZE. Is conversion of disk space from 1k
257 * block units to DEV_BSIZE necessary?
258 */
259 static int
260 ultrixstatfs(sp, buf)
261 struct statfs *sp;
262 caddr_t buf;
263 {
264 struct ultrix_statfs ssfs;
265
266 memset(&ssfs, 0, sizeof ssfs);
267 ssfs.f_type = 0;
268 ssfs.f_bsize = sp->f_bsize;
269 ssfs.f_blocks = sp->f_blocks;
270 ssfs.f_bfree = sp->f_bfree;
271 ssfs.f_bavail = sp->f_bavail;
272 ssfs.f_files = sp->f_files;
273 ssfs.f_ffree = sp->f_ffree;
274 ssfs.f_fsid = sp->f_fsid;
275 return copyout((caddr_t)&ssfs, buf, sizeof ssfs);
276 }
277
278
279 int
280 ultrix_sys_statfs(l, v, retval)
281 struct lwp *l;
282 void *v;
283 register_t *retval;
284 {
285 struct ultrix_sys_statfs_args *uap = v;
286 struct proc *p = l->l_proc;
287 struct mount *mp;
288 struct statfs *sp;
289 int error;
290 struct nameidata nd;
291
292 caddr_t sg = stackgap_init(p->p_emul);
293 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
294
295 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
296 if ((error = namei(&nd)) != 0)
297 return (error);
298
299 mp = nd.ni_vp->v_mount;
300 sp = &mp->mnt_stat;
301 vrele(nd.ni_vp);
302 if ((error = VFS_STATFS(mp, sp, p)) != 0)
303 return (error);
304 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
305 return ultrixstatfs(sp, (caddr_t)SCARG(uap, buf));
306 }
307
308 /*
309 * sys_fstatfs() takes an fd, not a path, and so needs no emul
310 * pathname processing; but it's similar enough to sys_statfs() that
311 * it goes here anyway.
312 */
313 int
314 ultrix_sys_fstatfs(l, v, retval)
315 struct lwp *l;
316 void *v;
317 register_t *retval;
318 {
319 struct ultrix_sys_fstatfs_args *uap = v;
320 struct proc *p = l->l_proc;
321 struct file *fp;
322 struct mount *mp;
323 struct statfs *sp;
324 int error;
325
326 /* getvnode() will use the descriptor for us */
327 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
328 return (error);
329 mp = ((struct vnode *)fp->f_data)->v_mount;
330 sp = &mp->mnt_stat;
331 if ((error = VFS_STATFS(mp, sp, p)) != 0)
332 goto out;
333 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
334 error = ultrixstatfs(sp, (caddr_t)SCARG(uap, buf));
335 out:
336 FILE_UNUSE(fp, p);
337 return (error);
338 }
339
340 int
341 ultrix_sys_mknod(l, v, retval)
342 struct lwp *l;
343 void *v;
344 register_t *retval;
345 {
346 struct ultrix_sys_mknod_args *uap = v;
347 struct proc *p = l->l_proc;
348
349 caddr_t sg = stackgap_init(p->p_emul);
350 CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
351
352 if (S_ISFIFO(SCARG(uap, mode)))
353 return sys_mkfifo(l, uap, retval);
354
355 return sys_mknod(l, (struct sys_mknod_args *)uap, retval);
356 }
357