print errno when init can't be executed
[unix-history] / usr / src / sys / kern / vfs_vnops.c
index d6eae21..1e92578 100644 (file)
@@ -1,51 +1,26 @@
-/*     vfs_vnops.c     4.26    82/08/03        */
-
-#include "../h/param.h"
-#include "../h/systm.h"
-#include "../h/dir.h"
-#include "../h/user.h"
-#include "../h/fs.h"
-#include "../h/file.h"
-#include "../h/conf.h"
-#include "../h/inode.h"
-#include "../h/reg.h"
-#include "../h/acct.h"
-#include "../h/mount.h"
-#include "../h/socket.h"
-#include "../h/socketvar.h"
-#include "../h/proc.h"
-
 /*
 /*
- * Openi called to allow handler
- * of special files to initialize and
- * validate before actual IO.
+ * Copyright (c) 1982, 1986 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ *
+ *     @(#)vfs_vnops.c 7.1 (Berkeley) %G%
  */
  */
-openi(ip, mode)
-       register struct inode *ip;
-{
-       dev_t dev;
-       register unsigned int maj;
-
-       dev = (dev_t)ip->i_rdev;
-       maj = major(dev);
-       switch (ip->i_mode&IFMT) {
 
 
-       case IFCHR:
-               if (maj >= nchrdev)
-                       goto bad;
-               (*cdevsw[maj].d_open)(dev, mode);
-               break;
+#include "../machine/reg.h"
 
 
-       case IFBLK:
-               if (maj >= nblkdev)
-                       goto bad;
-               (*bdevsw[maj].d_open)(dev, mode);
-       }
-       return;
-
-bad:
-       u.u_error = ENXIO;
-}
+#include "param.h"
+#include "systm.h"
+#include "dir.h"
+#include "user.h"
+#include "fs.h"
+#include "file.h"
+#include "conf.h"
+#include "inode.h"
+#include "acct.h"
+#include "mount.h"
+#include "socket.h"
+#include "socketvar.h"
+#include "proc.h"
 
 /*
  * Check mode permission on inode pointer.
 
 /*
  * Check mode permission on inode pointer.
@@ -65,28 +40,59 @@ access(ip, mode)
        int mode;
 {
        register m;
        int mode;
 {
        register m;
+       register gid_t *gp;
 
        m = mode;
        if (m == IWRITE) {
 
        m = mode;
        if (m == IWRITE) {
+               /*
+                * Disallow write attempts on read-only
+                * file systems; unless the file is a block
+                * or character device resident on the
+                * file system.
+                */
                if (ip->i_fs->fs_ronly != 0) {
                if (ip->i_fs->fs_ronly != 0) {
-                       u.u_error = EROFS;
-                       return (1);
+                       if ((ip->i_mode & IFMT) != IFCHR &&
+                           (ip->i_mode & IFMT) != IFBLK) {
+                               u.u_error = EROFS;
+                               return (1);
+                       }
                }
                }
-               if (ip->i_flag&ITEXT)           /* try to free text */
+               /*
+                * If there's shared text associated with
+                * the inode, try to free it up once.  If
+                * we fail, we can't allow writing.
+                */
+               if (ip->i_flag&ITEXT)
                        xrele(ip);
                if (ip->i_flag & ITEXT) {
                        u.u_error = ETXTBSY;
                        return (1);
                }
        }
                        xrele(ip);
                if (ip->i_flag & ITEXT) {
                        u.u_error = ETXTBSY;
                        return (1);
                }
        }
+       /*
+        * If you're the super-user,
+        * you always get access.
+        */
        if (u.u_uid == 0)
                return (0);
        if (u.u_uid == 0)
                return (0);
+       /*
+        * Access check is based on only
+        * one of owner, group, public.
+        * If not owner, then check group.
+        * If not a member of the group, then
+        * check public access.
+        */
        if (u.u_uid != ip->i_uid) {
                m >>= 3;
        if (u.u_uid != ip->i_uid) {
                m >>= 3;
-               if (ip->i_gid >= NGRPS ||
-                   (u.u_grps[ip->i_gid/(sizeof(int)*8)] &
-                    (1 << ip->i_gid%(sizeof(int)*8)) == 0))
-                       m >>= 3;
+               if (u.u_gid == ip->i_gid)
+                       goto found;
+               gp = u.u_groups;
+               for (; gp < &u.u_groups[NGROUPS] && *gp != NOGROUP; gp++)
+                       if (ip->i_gid == *gp)
+                               goto found;
+               m >>= 3;
+found:
+               ;
        }
        if ((ip->i_mode&m) != 0)
                return (0);
        }
        if ((ip->i_mode&m) != 0)
                return (0);
@@ -103,12 +109,17 @@ access(ip, mode)
  * return inode pointer.
  */
 struct inode *
  * return inode pointer.
  */
 struct inode *
-owner(follow)
+owner(fname, follow)
+       caddr_t fname;
        int follow;
 {
        register struct inode *ip;
        int follow;
 {
        register struct inode *ip;
+       register struct nameidata *ndp = &u.u_nd;
 
 
-       ip = namei(uchar, 0, follow);
+       ndp->ni_nameiop = LOOKUP | follow;
+       ndp->ni_segflg = UIO_USERSPACE;
+       ndp->ni_dirp = fname;
+       ip = namei(ndp);
        if (ip == NULL)
                return (NULL);
        if (u.u_uid == ip->i_uid)
        if (ip == NULL)
                return (NULL);
        if (u.u_uid == ip->i_uid)