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