duplicate TIOCGPGRP for controller - minus the check for controlling terminal
[unix-history] / usr / src / sys / kern / kern_time.c
index 1f79805..7896e17 100644 (file)
@@ -1,20 +1,28 @@
 /*
 /*
- * Copyright (c) 1982 Regents of the University of California.
- * All rights reserved.  The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
+ * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
+ * All rights reserved.
  *
  *
- *     @(#)kern_time.c 6.9 (Berkeley) %G%
+ * 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.
+ *
+ *     @(#)kern_time.c 7.11 (Berkeley) %G%
  */
 
  */
 
-#include "../machine/reg.h"
-
 #include "param.h"
 #include "param.h"
-#include "dir.h"               /* XXX */
-#include "user.h"
+#include "syscontext.h"
 #include "kernel.h"
 #include "kernel.h"
-#include "inode.h"
 #include "proc.h"
 
 #include "proc.h"
 
+
 /* 
  * Time of day and interval timer support.
  *
 /* 
  * Time of day and interval timer support.
  *
  * timers when they expire.
  */
 
  * timers when they expire.
  */
 
-gettimeofday()
-{
-       register struct a {
+/* ARGSUSED */
+gettimeofday(p, uap, retval)
+       struct proc *p;
+       register struct args {
                struct  timeval *tp;
                struct  timezone *tzp;
                struct  timeval *tp;
                struct  timezone *tzp;
-       } *uap = (struct a *)u.u_ap;
+       } *uap;
+       int *retval;
+{
        struct timeval atv;
        struct timeval atv;
+       int error = 0;
 
 
-       microtime(&atv);
-       u.u_error = copyout((caddr_t)&atv, (caddr_t)uap->tp, sizeof (atv));
-       if (u.u_error)
-               return;
-       if (uap->tzp == 0)
-               return;
-       /* SHOULD HAVE PER-PROCESS TIMEZONE */
-       u.u_error = copyout((caddr_t)&tz, (caddr_t)uap->tzp, sizeof (tz));
+       if (uap->tp) {
+               microtime(&atv);
+               if (error = copyout((caddr_t)&atv, (caddr_t)uap->tp,
+                   sizeof (atv)))
+                       RETURN (error);
+       }
+       if (uap->tzp)
+               error = copyout((caddr_t)&tz, (caddr_t)uap->tzp,
+                   sizeof (tz));
+       RETURN (error);
 }
 
 }
 
-settimeofday()
-{
-       register struct a {
+settimeofday(p, uap, retval)
+       struct proc *p;
+       struct args {
                struct  timeval *tv;
                struct  timezone *tzp;
                struct  timeval *tv;
                struct  timezone *tzp;
-       } *uap = (struct a *)u.u_ap;
+       } *uap;
+       int *retval;
+{
        struct timeval atv;
        struct timezone atz;
        struct timeval atv;
        struct timezone atz;
+       int error, s;
 
 
-       u.u_error = copyin((caddr_t)uap->tv, (caddr_t)&atv,
-               sizeof (struct timeval));
-       if (u.u_error)
-               return;
-       setthetime(&atv);
-       if (uap->tzp && suser()) {
-               u.u_error = copyin((caddr_t)uap->tzp, (caddr_t)&atz,
-                       sizeof (atz));
-               if (u.u_error == 0)
-                       tz = atz;
+       if (error = suser(u.u_cred, &u.u_acflag))
+               RETURN (error);
+       if (uap->tv) {
+               if (error = copyin((caddr_t)uap->tv, (caddr_t)&atv,
+                   sizeof (struct timeval)))
+                       RETURN (error);
+               /* WHAT DO WE DO ABOUT PENDING REAL-TIME TIMEOUTS??? */
+               boottime.tv_sec += atv.tv_sec - time.tv_sec;
+               s = splhigh(); time = atv; splx(s);
+               resettodr();
        }
        }
+       if (uap->tzp && (error = copyin((caddr_t)uap->tzp, (caddr_t)&atz,
+           sizeof (atz))) == 0)
+               tz = atz;
+       RETURN (error);
 }
 
 }
 
-setthetime(tv)
-       struct timeval *tv;
-{
-       int s;
-
-       if (!suser())
-               return;
-/* WHAT DO WE DO ABOUT PENDING REAL-TIME TIMEOUTS??? */
-       boottime.tv_sec += tv->tv_sec - time.tv_sec;
-       s = splhigh(); time = *tv; splx(s);
-       resettodr();
-}
-
-int adjtimedelta;
-extern int tickadj;
+extern int tickadj;                    /* "standard" clock skew, us./tick */
+int    tickdelta;                      /* current clock skew, us. per tick */
+long   timedelta;                      /* unapplied time correction, us. */
+long   bigadj = 1000000;               /* use 10x skew above bigadj us. */
 
 
-adjtime()
-{
-       register struct a {
+/* ARGSUSED */
+adjtime(p, uap, retval)
+       struct proc *p;
+       register struct args {
                struct timeval *delta;
                struct timeval *olddelta;
                struct timeval *delta;
                struct timeval *olddelta;
-       } *uap = (struct a *)u.u_ap;
+       } *uap;
+       int *retval;
+{
        struct timeval atv, oatv;
        struct timeval atv, oatv;
-       int s;
+       register long ndelta;
+       int s, error;
+
+       if (error = suser(u.u_cred, &u.u_acflag))
+               RETURN (error);
+       if (error =
+           copyin((caddr_t)uap->delta, (caddr_t)&atv, sizeof (struct timeval)))
+               RETURN (error);
+       ndelta = atv.tv_sec * 1000000 + atv.tv_usec;
+       if (timedelta == 0)
+               if (ndelta > bigadj)
+                       tickdelta = 10 * tickadj;
+               else
+                       tickdelta = tickadj;
+       if (ndelta % tickdelta)
+               ndelta = ndelta / tickadj * tickadj;
 
 
-       if (!suser()) 
-               return;
-       u.u_error = copyin((caddr_t)uap->delta, (caddr_t)&atv,
-               sizeof (struct timeval));
-       if (u.u_error)
-               return;
        s = splclock();
        if (uap->olddelta) {
        s = splclock();
        if (uap->olddelta) {
-               oatv.tv_sec = adjtimedelta / 1000000;
-               oatv.tv_usec = adjtimedelta % 1000000;
-               (void) copyout((caddr_t)&oatv, (caddr_t)uap->olddelta,
-                       sizeof (struct timeval));
+               oatv.tv_sec = timedelta / 1000000;
+               oatv.tv_usec = timedelta % 1000000;
        }
        }
-       adjtimedelta = atv.tv_sec * 1000000 + atv.tv_usec;
-       if (adjtimedelta % tickadj)
-               adjtimedelta = adjtimedelta / tickadj * tickadj;
+       timedelta = ndelta;
        splx(s);
        splx(s);
+
+       if (uap->olddelta)
+               (void) copyout((caddr_t)&oatv, (caddr_t)uap->olddelta,
+                       sizeof (struct timeval));
+       RETURN (0);
 }
 
 /*
 }
 
 /*
@@ -130,19 +153,20 @@ adjtime()
  * real time timers .it_interval.  Rather, we compute the next time in
  * absolute time the timer should go off.
  */
  * real time timers .it_interval.  Rather, we compute the next time in
  * absolute time the timer should go off.
  */
-getitimer()
-{
-       register struct a {
+/* ARGSUSED */
+getitimer(p, uap, retval)
+       struct proc *p;
+       register struct args {
                u_int   which;
                struct  itimerval *itv;
                u_int   which;
                struct  itimerval *itv;
-       } *uap = (struct a *)u.u_ap;
+       } *uap;
+       int *retval;
+{
        struct itimerval aitv;
        int s;
 
        struct itimerval aitv;
        int s;
 
-       if (uap->which > 2) {
-               u.u_error = EINVAL;
-               return;
-       }
+       if (uap->which > ITIMER_PROF)
+               RETURN (EINVAL);
        s = splclock();
        if (uap->which == ITIMER_REAL) {
                /*
        s = splclock();
        if (uap->which == ITIMER_REAL) {
                /*
@@ -151,7 +175,7 @@ getitimer()
                 * has passed return 0, else return difference between
                 * current time and time for the timer to go off.
                 */
                 * has passed return 0, else return difference between
                 * current time and time for the timer to go off.
                 */
-               aitv = u.u_procp->p_realtimer;
+               aitv = p->p_realtimer;
                if (timerisset(&aitv.it_value))
                        if (timercmp(&aitv.it_value, &time, <))
                                timerclear(&aitv.it_value);
                if (timerisset(&aitv.it_value))
                        if (timercmp(&aitv.it_value, &time, <))
                                timerclear(&aitv.it_value);
@@ -160,40 +184,35 @@ getitimer()
        } else
                aitv = u.u_timer[uap->which];
        splx(s);
        } else
                aitv = u.u_timer[uap->which];
        splx(s);
-       u.u_error = copyout((caddr_t)&aitv, (caddr_t)uap->itv,
-           sizeof (struct itimerval));
-       splx(s);
+       RETURN (copyout((caddr_t)&aitv, (caddr_t)uap->itv,
+           sizeof (struct itimerval)));
 }
 
 }
 
-setitimer()
-{
-       register struct a {
+/* ARGSUSED */
+setitimer(p, uap, retval)
+       struct proc *p;
+       register struct args {
                u_int   which;
                struct  itimerval *itv, *oitv;
                u_int   which;
                struct  itimerval *itv, *oitv;
-       } *uap = (struct a *)u.u_ap;
-       struct itimerval aitv, *aitvp;
-       int s;
-       register struct proc *p = u.u_procp;
+       } *uap;
+       int *retval;
+{
+       struct itimerval aitv;
+       register struct itimerval *itvp;
+       int s, error;
 
 
-       if (uap->which > 2) {
-               u.u_error = EINVAL;
-               return;
-       }
-       aitvp = uap->itv;
-       if (uap->oitv) {
-               uap->itv = uap->oitv;
-               getitimer();
-       }
-       if (aitvp == 0)
-               return;
-       u.u_error = copyin((caddr_t)aitvp, (caddr_t)&aitv,
-           sizeof (struct itimerval));
-       if (u.u_error)
-               return;
-       if (itimerfix(&aitv.it_value) || itimerfix(&aitv.it_interval)) {
-               u.u_error = EINVAL;
-               return;
-       }
+       if (uap->which > ITIMER_PROF)
+               RETURN (EINVAL);
+       itvp = uap->itv;
+       if (itvp && (error = copyin((caddr_t)itvp, (caddr_t)&aitv,
+           sizeof(struct itimerval))))
+               RETURN (error);
+       if ((uap->itv = uap->oitv) && (error = getitimer(p, uap, retval)))
+               RETURN (error);
+       if (itvp == 0)
+               return (0);
+       if (itimerfix(&aitv.it_value) || itimerfix(&aitv.it_interval))
+               RETURN (EINVAL);
        s = splclock();
        if (uap->which == ITIMER_REAL) {
                untimeout(realitexpire, (caddr_t)p);
        s = splclock();
        if (uap->which == ITIMER_REAL) {
                untimeout(realitexpire, (caddr_t)p);
@@ -205,6 +224,7 @@ setitimer()
        } else
                u.u_timer[uap->which] = aitv;
        splx(s);
        } else
                u.u_timer[uap->which] = aitv;
        splx(s);
+       RETURN (0);
 }
 
 /*
 }
 
 /*