set/get timeouts using timevals
[unix-history] / usr / src / sys / kern / kern_prot.c
index dbc3d08..4ff5fbc 100644 (file)
@@ -1,20 +1,10 @@
 /*
 /*
- * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
+ * Copyright (c) 1982, 1986, 1989, 1990 Regents of the University of California.
  * All rights reserved.
  *
  * All rights reserved.
  *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * %sccs.include.redist.c%
  *
  *
- *     @(#)kern_prot.c 7.10 (Berkeley) %G%
+ *     @(#)kern_prot.c 7.13 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
 #include "proc.h"
 #include "timeb.h"
 #include "times.h"
 #include "proc.h"
 #include "timeb.h"
 #include "times.h"
-#include "reboot.h"
-#include "buf.h"
-#include "../ufs/quota.h"
 #include "malloc.h"
 
 #include "malloc.h"
 
-#include "machine/reg.h"
-
-getpid()
+/* ARGSUSED */
+getpid(p, uap, retval)
+       struct proc *p;
+       void *uap;
+       int *retval;
 {
 
 {
 
-       u.u_r.r_val1 = u.u_procp->p_pid;
-       u.u_r.r_val2 = u.u_procp->p_ppid;
+       *retval = p->p_pid;
+#ifdef COMPAT_43
+       retval[1] = p->p_ppid;
+#endif
+       return (0);
 }
 
 }
 
-getpgrp()
+/* ARGSUSED */
+getppid(p, uap, retval)
+       struct proc *p;
+       void *uap;
+       int *retval;
 {
 {
-       register struct a {
+
+       *retval = p->p_ppid;
+       return (0);
+}
+
+getpgrp(p, uap, retval)
+       struct proc *p;
+       struct args {
                int     pid;
                int     pid;
-       } *uap = (struct a *)u.u_ap;
-       register struct proc *p;
+       } *uap;
+       int *retval;
+{
 
 
-       if (uap->pid == 0)
-               p = u.u_procp;
-       else if ((p = pfind(uap->pid)) == 0) {
-               u.u_error = ESRCH;
-               return;
-       }
-       u.u_r.r_val1 = p->p_pgrp->pg_id;
+       if (uap->pid != 0 && (p = pfind(uap->pid)) == 0)
+               return (ESRCH);
+       *retval = p->p_pgrp->pg_id;
+       return (0);
 }
 
 }
 
-getuid()
+/* ARGSUSED */
+getuid(p, uap, retval)
+       struct proc *p;
+       void *uap;
+       int *retval;
 {
 
 {
 
-       u.u_r.r_val1 = u.u_procp->p_ruid;
-       u.u_r.r_val2 = u.u_cred->cr_uid;
+       *retval = p->p_ruid;
+#ifdef COMPAT_43
+       retval[1] = u.u_cred->cr_uid;
+#endif
+       return (0);
 }
 
 }
 
-getgid()
+/* ARGSUSED */
+geteuid(p, uap, retval)
+       struct proc *p;
+       void *uap;
+       int *retval;
 {
 
 {
 
-       u.u_r.r_val1 = u.u_procp->p_rgid;
-       u.u_r.r_val2 = u.u_cred->cr_groups[0];
+       *retval = u.u_cred->cr_uid;
+       return (0);
 }
 
 }
 
-getgroups()
+/* ARGSUSED */
+getgid(p, uap, retval)
+       struct proc *p;
+       void *uap;
+       int *retval;
 {
 {
-       register struct a {
+
+       *retval = p->p_rgid;
+#ifdef COMPAT_43
+       retval[1] = u.u_cred->cr_groups[0];
+#endif
+       return (0);
+}
+
+/*
+ * Get effective group ID.
+ * The "egid" is groups[0], and thus could be obtained via getgroups;
+ * this is somewhat painful to do correctly in a library function,
+ * this the existence of this syscall.
+ */
+/* ARGSUSED */
+getegid(p, uap, retval)
+       struct proc *p;
+       void *uap;
+       int *retval;
+{
+
+       *retval = u.u_cred->cr_groups[0];
+       return (0);
+}
+
+getgroups(p, uap, retval)
+       struct proc *p;
+       register struct arg {
                u_int   gidsetsize;
                u_int   gidsetsize;
-               int     *gidset;
-       } *uap = (struct a *)u.u_ap;
+               int     *gidset;                /* XXX not yet POSIX */
+       } *uap;
+       int *retval;
+{
        register gid_t *gp;
        register int *lp;
        int groups[NGROUPS];
        register gid_t *gp;
        register int *lp;
        int groups[NGROUPS];
+       int error;
 
        if (uap->gidsetsize == 0) {
 
        if (uap->gidsetsize == 0) {
-               u.u_r.r_val1 = u.u_cred->cr_ngroups;
-               return;
-       }
-       if (uap->gidsetsize < u.u_cred->cr_ngroups) {
-               u.u_error = EINVAL;
-               return;
+               *retval = u.u_cred->cr_ngroups;
+               return (0);
        }
        }
+       if (uap->gidsetsize < u.u_cred->cr_ngroups)
+               return (EINVAL);
        uap->gidsetsize = u.u_cred->cr_ngroups;
        gp = u.u_cred->cr_groups;
        for (lp = groups; lp < &groups[uap->gidsetsize]; )
                *lp++ = *gp++;
        uap->gidsetsize = u.u_cred->cr_ngroups;
        gp = u.u_cred->cr_groups;
        for (lp = groups; lp < &groups[uap->gidsetsize]; )
                *lp++ = *gp++;
-       u.u_error = copyout((caddr_t)groups, (caddr_t)uap->gidset,
-           uap->gidsetsize * sizeof (groups[0]));
-       if (u.u_error)
-               return;
-       u.u_r.r_val1 = uap->gidsetsize;
+       if (error = copyout((caddr_t)groups, (caddr_t)uap->gidset,
+           uap->gidsetsize * sizeof (groups[0])))
+               return (error);
+       *retval = uap->gidsetsize;
+       return (0);
 }
 
 }
 
-setsid()
+/* ARGSUSED */
+setsid(p, uap, retval)
+       struct proc *p;
+       void *uap;
+       int *retval;
 {
 {
-       register struct proc *p = u.u_procp;
 
 
-       if ((p->p_pgid == p->p_pid) || pgfind(p->p_pid))
-               u.u_error = EPERM;
-       else {
+       if (p->p_pgid == p->p_pid || pgfind(p->p_pid)) {
+               return (EPERM);
+       else {
                pgmv(p, p->p_pid, 1);
                pgmv(p, p->p_pid, 1);
-               u.u_r.r_val1 = p->p_pid;
+               *retval = p->p_pid;
+               return (0);
        }
        }
-       return;
 }
 
 /*
 }
 
 /*
- * set process group
+ * set process group (setpgrp/setpgid)
  *
  * caller does setpgrp(pid, pgid)
  *
  *
  * caller does setpgrp(pid, pgid)
  *
@@ -127,66 +174,86 @@ setsid()
  *     there must exist some pid in same session having pgid (EPERM)
  * pid must not be session leader (EPERM)
  */
  *     there must exist some pid in same session having pgid (EPERM)
  * pid must not be session leader (EPERM)
  */
-setpgrp()
-{
-       register struct a {
+/* ARGSUSED */
+setpgrp(cp, uap, retval)
+       struct proc *cp;
+       register struct args {
                int     pid;
                int     pgid;
                int     pid;
                int     pgid;
-       } *uap = (struct a *)u.u_ap;
+       } *uap;
+       int *retval;
+{
        register struct proc *p;
        register struct pgrp *pgrp;
 
        register struct proc *p;
        register struct pgrp *pgrp;
 
-       if (uap->pid == 0)
-               p = u.u_procp;
-       else if ((p = pfind(uap->pid)) == 0 || !inferior(p)) {
-               u.u_error = ESRCH;
-               return;
-       }
-       else if (p != u.u_procp) { 
-               if (p->p_session != u.u_procp->p_session) {
-                       u.u_error = EPERM;
-                       return;
-               }
-               if (p->p_flag&SEXEC) {
-                       u.u_error = EACCES;
-                       return;
-               }
-       }
-       if (SESS_LEADER(p)) {
-               u.u_error = EPERM;
-               return;
-       }
+       if (uap->pid != 0) {
+               if ((p = pfind(uap->pid)) == 0 || !inferior(p))
+                       return (ESRCH);
+               if (p->p_session != cp->p_session)
+                       return (EPERM);
+               if (p->p_flag&SEXEC)
+                       return (EACCES);
+       } else
+               p = cp;
+       if (SESS_LEADER(p))
+               return (EPERM);
        if (uap->pgid == 0)
                uap->pgid = p->p_pid;
        else if ((uap->pgid != p->p_pid) &&
                (((pgrp = pgfind(uap->pgid)) == 0) || 
                   pgrp->pg_mem == NULL ||
        if (uap->pgid == 0)
                uap->pgid = p->p_pid;
        else if ((uap->pgid != p->p_pid) &&
                (((pgrp = pgfind(uap->pgid)) == 0) || 
                   pgrp->pg_mem == NULL ||
-                  pgrp->pg_session != u.u_procp->p_session)) {
-               u.u_error = EPERM;
-               return;
-       }
+                  pgrp->pg_session != u.u_procp->p_session))
+               return (EPERM);
        /*
        /*
-        * done checking, now doit
+        * done checking, now do it
         */
        pgmv(p, uap->pgid, 0);
         */
        pgmv(p, uap->pgid, 0);
+       return (0);
 }
 
 }
 
-setreuid()
+/* ARGSUSED */
+setuid(p, uap, retval)
+       register struct proc *p;
+       struct args {
+               int     uid;
+       } *uap;
+       int *retval;
 {
 {
-       struct a {
-               int     ruid;
+       register uid_t uid;
+       int error;
+
+       uid = uap->uid;
+       if (uid != p->p_ruid && (error = suser(u.u_cred, &u.u_acflag)))
+               return (error);
+       /*
+        * Everything's okay, do it.
+        * Copy credentials so other references do not
+        * see our changes.
+        */
+       if (u.u_cred->cr_ref > 1)
+               u.u_cred = crcopy(u.u_cred);
+       u.u_cred->cr_uid = uid;
+       p->p_uid = uid;
+       p->p_ruid = uid;
+       p->p_svuid = uid;
+       return (0);
+}
+
+/* ARGSUSED */
+seteuid(p, uap, retval)
+       register struct proc *p;
+       struct args {
                int     euid;
        } *uap;
                int     euid;
        } *uap;
-       register struct proc *p = u.u_procp;
-       register int ruid, euid;
+       int *retval;
+{
+       register uid_t euid;
+       int error;
 
 
-       uap = (struct a *)u.u_ap;
-       ruid = uap->ruid;
-       if (ruid == -1)
-               return;
        euid = uap->euid;
        euid = uap->euid;
-       if (euid == -1)
-               return;
+       if (euid != p->p_ruid && euid != p->p_svuid &&
+           (error = suser(u.u_cred, &u.u_acflag)))
+               return (error);
        /*
         * Everything's okay, do it.
         * Copy credentials so other references do not
        /*
         * Everything's okay, do it.
         * Copy credentials so other references do not
@@ -196,56 +263,137 @@ setreuid()
                u.u_cred = crcopy(u.u_cred);
        u.u_cred->cr_uid = euid;
        p->p_uid = euid;
                u.u_cred = crcopy(u.u_cred);
        u.u_cred->cr_uid = euid;
        p->p_uid = euid;
-       p->p_ruid = ruid;
+       return (0);
 }
 
 }
 
-setregid()
+/* ARGSUSED */
+setgid(p, uap, retval)
+       struct proc *p;
+       struct args {
+               int     gid;
+       } *uap;
+       int *retval;
 {
 {
-       register struct a {
-               int     rgid;
+       register gid_t gid;
+       int error;
+
+       gid = uap->gid;
+       if (gid != p->p_rgid && (error = suser(u.u_cred, &u.u_acflag)))
+               return (error);
+       if (u.u_cred->cr_ref > 1)
+               u.u_cred = crcopy(u.u_cred);
+       p->p_rgid = gid;
+       u.u_cred->cr_groups[0] = gid;
+       p->p_svgid = gid;               /* ??? */
+       return (0);
+}
+
+/* ARGSUSED */
+setegid(p, uap, retval)
+       struct proc *p;
+       struct args {
                int     egid;
        } *uap;
                int     egid;
        } *uap;
-       register int rgid, egid;
-       register struct proc *p = u.u_procp;
+       int *retval;
+{
+       register gid_t egid;
+       int error;
 
 
-       uap = (struct a *)u.u_ap;
-       rgid = uap->rgid;
-       if (rgid == -1)
-               return;
        egid = uap->egid;
        egid = uap->egid;
-       if (egid == -1)
-               return;
+       if (egid != p->p_rgid && egid != p->p_svgid &&
+           (error = suser(u.u_cred, &u.u_acflag)))
+               return (error);
        if (u.u_cred->cr_ref > 1)
                u.u_cred = crcopy(u.u_cred);
        if (u.u_cred->cr_ref > 1)
                u.u_cred = crcopy(u.u_cred);
-       p->p_rgid = rgid;
        u.u_cred->cr_groups[0] = egid;
        u.u_cred->cr_groups[0] = egid;
+       return (0);
 }
 
 }
 
-setgroups()
+#ifdef COMPAT_43
+/* ARGSUSED */
+osetreuid(p, uap, retval)
+       register struct proc *p;
+       struct args {
+               int     ruid;
+               int     euid;
+       } *uap;
+       int *retval;
 {
 {
-       register struct a {
+       register uid_t ruid, euid;
+       int error;
+
+       if (uap->ruid == -1)
+           (error = suser(u.u_cred, &u.u_acflag)))
+               return (error);
+       if (uap->euid == -1)
+           euid != p->p_svuid && (error = suser(u.u_cred, &u.u_acflag)))
+               return (error);
+       /*
+        * Everything's okay, do it.
+        * Copy credentials so other references do not
+        * see our changes.
+        */
+       if (u.u_cred->cr_ref > 1)
+               u.u_cred = crcopy(u.u_cred);
+       u.u_cred->cr_uid = euid;
+       p->p_uid = euid;
+       p->p_ruid = ruid;
+       return (0);
+}
+
+/* ARGSUSED */
+osetregid(p, uap, retval)
+       struct proc *p;
+       struct args {
+               int     rgid;
+               int     egid;
+       } *uap;
+       int *retval;
+{
+       register gid_t rgid, egid;
+       int error;
+
+       if (uap->rgid == -1)
+           (error = suser(u.u_cred, &u.u_acflag)))
+               return (error);
+       if (uap->egid == -1)
+           egid != p->p_svgid && (error = suser(u.u_cred, &u.u_acflag)))
+               return (error);
+       if (u.u_cred->cr_ref > 1)
+               u.u_cred = crcopy(u.u_cred);
+       p->p_rgid = rgid;
+       u.u_cred->cr_groups[0] = egid;
+       return (0);
+}
+#endif
+
+/* ARGSUSED */
+setgroups(p, uap, retval)
+       struct proc *p;
+       struct args {
                u_int   gidsetsize;
                int     *gidset;
                u_int   gidsetsize;
                int     *gidset;
-       } *uap = (struct a *)u.u_ap;
+       } *uap;
+       int *retval;
+{
        register gid_t *gp;
        register int *lp;
        register gid_t *gp;
        register int *lp;
-       int ngrp, groups[NGROUPS];
+       int error, ngrp, groups[NGROUPS];
 
 
-       if (u.u_error = suser(u.u_cred, &u.u_acflag))
-               return;
+       if (error = suser(u.u_cred, &u.u_acflag))
+               return (error);
        ngrp = uap->gidsetsize;
        ngrp = uap->gidsetsize;
-       if (ngrp > NGROUPS) {
-               u.u_error = EINVAL;
-               return;
-       }
-       u.u_error = copyin((caddr_t)uap->gidset, (caddr_t)groups,
+       if (ngrp > NGROUPS)
+               return (EINVAL);
+       error = copyin((caddr_t)uap->gidset, (caddr_t)groups,
            uap->gidsetsize * sizeof (groups[0]));
            uap->gidsetsize * sizeof (groups[0]));
-       if (u.u_error)
-               return;
+       if (error)
+               return (error);
        gp = u.u_cred->cr_groups;
        for (lp = groups; lp < &groups[uap->gidsetsize]; )
                *gp++ = *lp++;
        u.u_cred->cr_ngroups = ngrp;
        gp = u.u_cred->cr_groups;
        for (lp = groups; lp < &groups[uap->gidsetsize]; )
                *gp++ = *lp++;
        u.u_cred->cr_ngroups = ngrp;
+       return (0);
 }
 
 /*
 }
 
 /*
@@ -292,7 +440,7 @@ crget()
        MALLOC(cr, struct ucred *, sizeof(*cr), M_CRED, M_WAITOK);
        bzero((caddr_t)cr, sizeof(*cr));
        cr->cr_ref = 1;
        MALLOC(cr, struct ucred *, sizeof(*cr), M_CRED, M_WAITOK);
        bzero((caddr_t)cr, sizeof(*cr));
        cr->cr_ref = 1;
-       return(cr);
+       return (cr);
 }
 
 /*
 }
 
 /*
@@ -302,7 +450,7 @@ crget()
 crfree(cr)
        struct ucred *cr;
 {
 crfree(cr)
        struct ucred *cr;
 {
-       int     s = splimp();
+       int s = splimp();
 
        if (--cr->cr_ref != 0) {
                (void) splx(s);
 
        if (--cr->cr_ref != 0) {
                (void) splx(s);
@@ -325,7 +473,7 @@ crcopy(cr)
        *newcr = *cr;
        crfree(cr);
        newcr->cr_ref = 1;
        *newcr = *cr;
        crfree(cr);
        newcr->cr_ref = 1;
-       return(newcr);
+       return (newcr);
 }
 
 /*
 }
 
 /*
@@ -340,40 +488,46 @@ crdup(cr)
        newcr = crget();
        *newcr = *cr;
        newcr->cr_ref = 1;
        newcr = crget();
        *newcr = *cr;
        newcr->cr_ref = 1;
-       return(newcr);
+       return (newcr);
 }
 
 /*
  * Get login name, if available.
  */
 }
 
 /*
  * Get login name, if available.
  */
-getlogin()
-{
-       struct a {
+/* ARGSUSED */
+getlogin(p, uap, retval)
+       struct proc *p;
+       struct args {
                char    *namebuf;
                u_int   namelen;
                char    *namebuf;
                u_int   namelen;
-       } *uap = (struct a *)u.u_ap;
+       } *uap;
+       int *retval;
+{
 
 
-       if (uap->namelen > sizeof (u.u_procp->p_logname))
-               uap->namelen = sizeof (u.u_procp->p_logname);
-       u.u_error = copyout((caddr_t)u.u_procp->p_logname, 
-                            (caddr_t)uap->namebuf, uap->namelen);
+       if (uap->namelen > sizeof (p->p_logname))
+               uap->namelen = sizeof (p->p_logname);
+       return (copyout((caddr_t)p->p_logname, (caddr_t)uap->namebuf,
+           uap->namelen));
 }
 
 /*
  * Set login name.
  */
 }
 
 /*
  * Set login name.
  */
-setlogin()
-{
-       struct a {
+/* ARGSUSED */
+setlogin(p, uap, retval)
+       struct proc *p;
+       struct args {
                char    *namebuf;
                char    *namebuf;
-       } *uap = (struct a *)u.u_ap;
+       } *uap;
+       int *retval;
+{
        int error;
 
        int error;
 
-       if (u.u_error = suser(u.u_cred, &u.u_acflag))
-               return;
-       error = copyinstr((caddr_t)uap->namebuf, (caddr_t)u.u_procp->p_logname,
-           sizeof (u.u_procp->p_logname) - 1, (int *) 0);
+       if (error = suser(u.u_cred, &u.u_acflag))
+               return (error);
+       error = copyinstr((caddr_t)uap->namebuf, (caddr_t)p->p_logname,
+           sizeof (p->p_logname) - 1, (int *) 0);
        if (error == ENOENT)            /* name too long */
                error = EINVAL;
        if (error == ENOENT)            /* name too long */
                error = EINVAL;
-       u.u_error = error;
+       return (error);
 }
 }