BSD 4_3 release
[unix-history] / usr / src / sys / sys / kern_acct.c
index 06d09ad..8e506f2 100644 (file)
@@ -1,15 +1,20 @@
-/*     kern_acct.c     6.1     83/07/29        */
+/*
+ * 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.
+ *
+ *     @(#)kern_acct.c 7.1 (Berkeley) 6/5/86
+ */
 
 
-#include "../h/param.h"
-#include "../h/systm.h"
-#include "../h/dir.h"
-#include "../h/user.h"
-#include "../h/inode.h"
-#include "../h/fs.h"
-#include "../h/kernel.h"
-#include "../h/acct.h"
-#include "../h/nami.h"
-#include "../h/uio.h"
+#include "param.h"
+#include "systm.h"
+#include "dir.h"
+#include "user.h"
+#include "inode.h"
+#include "fs.h"
+#include "kernel.h"
+#include "acct.h"
+#include "uio.h"
 
 /*
  * SHOULD REPLACE THIS WITH A DRIVER THAT CAN BE READ TO SIMPLIFY.
 
 /*
  * SHOULD REPLACE THIS WITH A DRIVER THAT CAN BE READ TO SIMPLIFY.
@@ -26,6 +31,7 @@ sysacct()
        register struct a {
                char    *fname;
        } *uap = (struct a *)u.u_ap;
        register struct a {
                char    *fname;
        } *uap = (struct a *)u.u_ap;
+       register struct nameidata *ndp = &u.u_nd;
 
        if (suser()) {
                if (savacctp) {
 
        if (suser()) {
                if (savacctp) {
@@ -39,14 +45,22 @@ sysacct()
                        }
                        return;
                }
                        }
                        return;
                }
-               ip = namei(uchar, LOOKUP, 1);
-               if(ip == NULL)
+               ndp->ni_nameiop = LOOKUP | FOLLOW;
+               ndp->ni_segflg = UIO_USERSPACE;
+               ndp->ni_dirp = uap->fname;
+               ip = namei(ndp);
+               if (ip == NULL)
                        return;
                        return;
-               if((ip->i_mode & IFMT) != IFREG) {
+               if ((ip->i_mode&IFMT) != IFREG) {
                        u.u_error = EACCES;
                        iput(ip);
                        return;
                }
                        u.u_error = EACCES;
                        iput(ip);
                        return;
                }
+               if (ip->i_fs->fs_ronly) {
+                       u.u_error = EROFS;
+                       iput(ip);
+                       return;
+               }
                if (acctp && (acctp->i_number != ip->i_number ||
                    acctp->i_dev != ip->i_dev))
                        irele(acctp);
                if (acctp && (acctp->i_number != ip->i_number ||
                    acctp->i_dev != ip->i_dev))
                        irele(acctp);
@@ -67,7 +81,9 @@ acct()
        register int i;
        register struct inode *ip;
        register struct fs *fs;
        register int i;
        register struct inode *ip;
        register struct fs *fs;
+       register struct rusage *ru;
        off_t siz;
        off_t siz;
+       struct timeval t;
        register struct acct *ap = &acctbuf;
 
        if (savacctp) {
        register struct acct *ap = &acctbuf;
 
        if (savacctp) {
@@ -90,17 +106,23 @@ acct()
        ilock(ip);
        for (i = 0; i < sizeof (ap->ac_comm); i++)
                ap->ac_comm[i] = u.u_comm[i];
        ilock(ip);
        for (i = 0; i < sizeof (ap->ac_comm); i++)
                ap->ac_comm[i] = u.u_comm[i];
-       ap->ac_utime = compress((long)u.u_ru.ru_utime.tv_sec);
-       ap->ac_stime = compress((long)u.u_ru.ru_stime.tv_sec);
-       ap->ac_etime = compress((long)time.tv_sec - u.u_start);
-       ap->ac_btime = u.u_start;
+       ru = &u.u_ru;
+       ap->ac_utime = compress(ru->ru_utime.tv_sec, ru->ru_utime.tv_usec);
+       ap->ac_stime = compress(ru->ru_stime.tv_sec, ru->ru_stime.tv_usec);
+       t = time;
+       timevalsub(&t, &u.u_start);
+       ap->ac_etime = compress(t.tv_sec, t.tv_usec);
+       ap->ac_btime = u.u_start.tv_sec;
        ap->ac_uid = u.u_ruid;
        ap->ac_gid = u.u_rgid;
        ap->ac_uid = u.u_ruid;
        ap->ac_gid = u.u_rgid;
-       ap->ac_mem = 0;
-       if (i = u.u_ru.ru_utime.tv_sec + u.u_ru.ru_stime.tv_sec)
-               ap->ac_mem =
-                   (u.u_ru.ru_ixrss + u.u_ru.ru_idrss + u.u_ru.ru_isrss) / i;
-       ap->ac_io = compress((long)(u.u_ru.ru_inblock + u.u_ru.ru_oublock));
+       t = ru->ru_stime;
+       timevaladd(&t, &ru->ru_utime);
+       if (i = t.tv_sec * hz + t.tv_usec / tick)
+               ap->ac_mem = (ru->ru_ixrss+ru->ru_idrss+ru->ru_isrss) / i;
+       else
+               ap->ac_mem = 0;
+       ap->ac_mem >>= CLSIZELOG2;
+       ap->ac_io = compress(ru->ru_inblock + ru->ru_oublock, (long)0);
        if (u.u_ttyp)
                ap->ac_tty = u.u_ttyd;
        else
        if (u.u_ttyp)
                ap->ac_tty = u.u_ttyd;
        else
@@ -120,11 +142,15 @@ acct()
  * Produce a pseudo-floating point representation
  * with 3 bits base-8 exponent, 13 bits fraction.
  */
  * Produce a pseudo-floating point representation
  * with 3 bits base-8 exponent, 13 bits fraction.
  */
-compress(t)
+compress(t, ut)
        register long t;
        register long t;
+       long ut;
 {
        register exp = 0, round = 0;
 
 {
        register exp = 0, round = 0;
 
+       t = t * AHZ;  /* compiler will convert only this format to a shift */
+       if (ut)
+               t += ut / (1000000 / AHZ);
        while (t >= 8192) {
                exp++;
                round = t&04;
        while (t >= 8192) {
                exp++;
                round = t&04;