ultrix_pathname.c revision 1.18 1 /* $NetBSD: ultrix_pathname.c,v 1.18 2003/06/29 22:29:54 fvdl 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.18 2003/06/29 22:29:54 fvdl 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/sa.h>
78 #include <sys/syscallargs.h>
79 #include <sys/proc.h>
80
81 #include <compat/ultrix/ultrix_syscallargs.h>
82 #include <compat/common/compat_util.h>
83
84 static int ultrixstatfs __P((struct statfs *sp, caddr_t buf));
85
86 int
87 ultrix_sys_creat(l, v, retval)
88 struct lwp *l;
89 void *v;
90 register_t *retval;
91 {
92 struct ultrix_sys_creat_args *uap = v;
93 struct sys_open_args ap;
94 struct proc *p = l->l_proc;
95
96 caddr_t sg = stackgap_init(p, 0);
97 CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
98
99 SCARG(&ap, path) = SCARG(uap, path);
100 SCARG(&ap, flags) = O_WRONLY | O_CREAT | O_TRUNC;
101 SCARG(&ap, mode) = SCARG(uap, mode);
102
103 return (sys_open(l, &ap, retval));
104 }
105
106
107 int
108 ultrix_sys_access(l, v, retval)
109 struct lwp *l;
110 void *v;
111 register_t *retval;
112 {
113 struct ultrix_sys_access_args *uap = v;
114 struct proc *p = l->l_proc;
115 caddr_t sg = stackgap_init(p, 0);
116 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
117
118 return (sys_access(l, uap, retval));
119 }
120
121 int
122 ultrix_sys_stat(l, v, retval)
123 struct lwp *l;
124 void *v;
125 register_t *retval;
126 {
127 struct ultrix_sys_stat_args *uap = v;
128 struct proc *p = l->l_proc;
129 caddr_t sg = stackgap_init(p, 0);
130 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
131
132 return (compat_43_sys_stat(l, uap, retval));
133 }
134
135 int
136 ultrix_sys_lstat(l, v, retval)
137 struct lwp *l;
138 void *v;
139 register_t *retval;
140 {
141 struct ultrix_sys_lstat_args *uap = v;
142 struct proc *p = l->l_proc;
143 caddr_t sg = stackgap_init(p, 0);
144 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
145
146 return (compat_43_sys_lstat(l, uap, retval));
147 }
148
149 int
150 ultrix_sys_execv(l, v, retval)
151 struct lwp *l;
152 void *v;
153 register_t *retval;
154 {
155 struct ultrix_sys_execv_args /* {
156 syscallarg(const char *) path;
157 syscallarg(char **) argv;
158 } */ *uap = v;
159 struct proc *p = l->l_proc;
160 struct sys_execve_args ap;
161 caddr_t sg;
162
163 sg = stackgap_init(p, 0);
164 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
165
166 SCARG(&ap, path) = SCARG(uap, path);
167 SCARG(&ap, argp) = SCARG(uap, argp);
168 SCARG(&ap, envp) = NULL;
169
170 return (sys_execve(l, &ap, retval));
171 }
172
173 int
174 ultrix_sys_execve(l, v, retval)
175 struct lwp *l;
176 void *v;
177 register_t *retval;
178 {
179 struct ultrix_sys_execve_args /* {
180 syscallarg(const char *) path;
181 syscallarg(char **) argv;
182 syscallarg(char **) envp;
183 } */ *uap = v;
184 struct proc *p = l->l_proc;
185 struct sys_execve_args ap;
186 caddr_t sg;
187
188 sg = stackgap_init(p, 0);
189 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
190
191 SCARG(&ap, path) = SCARG(uap, path);
192 SCARG(&ap, argp) = SCARG(uap, argp);
193 SCARG(&ap, envp) = SCARG(uap, envp);
194
195 return (sys_execve(l, &ap, retval));
196 }
197
198 int
199 ultrix_sys_open(l, v, retval)
200 struct lwp *l;
201 void *v;
202 register_t *retval;
203 {
204 struct ultrix_sys_open_args *uap = v;
205 struct proc *p = l->l_proc;
206 int q, r;
207 int noctty;
208 int ret;
209
210 caddr_t sg = stackgap_init(p, 0);
211
212 /* convert open flags into NetBSD flags */
213 q = SCARG(uap, flags);
214 noctty = q & 0x8000;
215 r = (q & (0x0001 | 0x0002 | 0x0008 | 0x0040 | 0x0200 | 0x0400 | 0x0800));
216 r |= ((q & (0x0004 | 0x1000 | 0x4000)) ? O_NONBLOCK : 0);
217 r |= ((q & 0x0080) ? O_SHLOCK : 0);
218 r |= ((q & 0x0100) ? O_EXLOCK : 0);
219 r |= ((q & 0x2000) ? O_FSYNC : 0);
220
221 if (r & O_CREAT)
222 CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
223 else
224 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
225 SCARG(uap, flags) = r;
226 ret = sys_open(l, (struct sys_open_args *)uap, retval);
227
228 if (!ret && !noctty && SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) {
229 struct filedesc *fdp = p->p_fd;
230 struct file *fp;
231
232 fp = fd_getfile(fdp, *retval);
233
234 /* ignore any error, just give it a try */
235 if (fp != NULL && fp->f_type == DTYPE_VNODE)
236 (fp->f_ops->fo_ioctl)(fp, TIOCSCTTY, (caddr_t)0, p);
237 }
238 return ret;
239 }
240
241
242 struct ultrix_statfs {
243 long f_type; /* type of info, zero for now */
244 long f_bsize; /* fundamental file system block size */
245 long f_blocks; /* total blocks in file system */
246 long f_bfree; /* free blocks */
247 long f_bavail; /* free blocks available to non-super-user */
248 long f_files; /* total file nodes in file system */
249 long f_ffree; /* free file nodes in fs */
250 fsid_t f_fsid; /* file system id */
251 long f_spare[7]; /* spare for later */
252 };
253
254 /*
255 * Custruct ultrix statfs result from native.
256 * XXX should this be the same as returned by Ultrix getmnt(2)?
257 * XXX Ultrix predates DEV_BSIZE. Is conversion of disk space from 1k
258 * block units to DEV_BSIZE necessary?
259 */
260 static int
261 ultrixstatfs(sp, buf)
262 struct statfs *sp;
263 caddr_t buf;
264 {
265 struct ultrix_statfs ssfs;
266
267 memset(&ssfs, 0, sizeof ssfs);
268 ssfs.f_type = 0;
269 ssfs.f_bsize = sp->f_bsize;
270 ssfs.f_blocks = sp->f_blocks;
271 ssfs.f_bfree = sp->f_bfree;
272 ssfs.f_bavail = sp->f_bavail;
273 ssfs.f_files = sp->f_files;
274 ssfs.f_ffree = sp->f_ffree;
275 ssfs.f_fsid = sp->f_fsid;
276 return copyout((caddr_t)&ssfs, buf, sizeof ssfs);
277 }
278
279
280 int
281 ultrix_sys_statfs(l, v, retval)
282 struct lwp *l;
283 void *v;
284 register_t *retval;
285 {
286 struct ultrix_sys_statfs_args *uap = v;
287 struct proc *p = l->l_proc;
288 struct mount *mp;
289 struct statfs *sp;
290 int error;
291 struct nameidata nd;
292
293 caddr_t sg = stackgap_init(p, 0);
294 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
295
296 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
297 if ((error = namei(&nd)) != 0)
298 return (error);
299
300 mp = nd.ni_vp->v_mount;
301 sp = &mp->mnt_stat;
302 vrele(nd.ni_vp);
303 if ((error = VFS_STATFS(mp, sp, p)) != 0)
304 return (error);
305 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
306 return ultrixstatfs(sp, (caddr_t)SCARG(uap, buf));
307 }
308
309 /*
310 * sys_fstatfs() takes an fd, not a path, and so needs no emul
311 * pathname processing; but it's similar enough to sys_statfs() that
312 * it goes here anyway.
313 */
314 int
315 ultrix_sys_fstatfs(l, v, retval)
316 struct lwp *l;
317 void *v;
318 register_t *retval;
319 {
320 struct ultrix_sys_fstatfs_args *uap = v;
321 struct proc *p = l->l_proc;
322 struct file *fp;
323 struct mount *mp;
324 struct statfs *sp;
325 int error;
326
327 /* getvnode() will use the descriptor for us */
328 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
329 return (error);
330 mp = ((struct vnode *)fp->f_data)->v_mount;
331 sp = &mp->mnt_stat;
332 if ((error = VFS_STATFS(mp, sp, p)) != 0)
333 goto out;
334 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
335 error = ultrixstatfs(sp, (caddr_t)SCARG(uap, buf));
336 out:
337 FILE_UNUSE(fp, p);
338 return (error);
339 }
340
341 int
342 ultrix_sys_mknod(l, v, retval)
343 struct lwp *l;
344 void *v;
345 register_t *retval;
346 {
347 struct ultrix_sys_mknod_args *uap = v;
348 struct proc *p = l->l_proc;
349
350 caddr_t sg = stackgap_init(p, 0);
351 CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
352
353 if (S_ISFIFO(SCARG(uap, mode)))
354 return sys_mkfifo(l, uap, retval);
355
356 return sys_mknod(l, (struct sys_mknod_args *)uap, retval);
357 }
358