1 /* $NetBSD: ultrix_pathname.c,v 1.14 2002/03/16 20:43:58 christos 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.14 2002/03/16 20:43:58 christos 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, 0); 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, 0); 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, 0); 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, 0); 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, 0); 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, 0); 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, 0); 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, 0); 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, 0); 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