xref: /csrg-svn/sys/kern/kern_resource.c (revision 7376)
1 /*	kern_resource.c	4.9	82/07/12	*/
2 
3 #include "../h/param.h"
4 #include "../h/systm.h"
5 #include "../h/acct.h"
6 #include "../h/dir.h"
7 #include "../h/user.h"
8 #include "../h/inode.h"
9 #include "../h/proc.h"
10 #include "../h/seg.h"
11 
12 struct	inode *acctp;
13 
14 /*
15  * Perform process accounting functions.
16  */
17 sysacct()
18 {
19 	register struct inode *ip;
20 	register struct a {
21 		char	*fname;
22 	} *uap;
23 
24 	uap = (struct a *)u.u_ap;
25 	if (suser()) {
26 		if (uap->fname==NULL) {
27 			if (ip = acctp) {
28 				irele(ip);
29 				acctp = NULL;
30 			}
31 			return;
32 		}
33 		ip = namei(uchar, 0, 1);
34 		if(ip == NULL)
35 			return;
36 		if((ip->i_mode & IFMT) != IFREG) {
37 			u.u_error = EACCES;
38 			iput(ip);
39 			return;
40 		}
41 		if (acctp && (acctp->i_number != ip->i_number ||
42 		    acctp->i_dev != ip->i_dev))
43 			irele(acctp);
44 		acctp = ip;
45 		iunlock(ip);
46 	}
47 }
48 
49 struct	acct acctbuf;
50 /*
51  * On exit, write a record on the accounting file.
52  */
53 acct()
54 {
55 	register i;
56 	register struct inode *ip;
57 	off_t siz;
58 	register struct acct *ap = &acctbuf;
59 
60 	if ((ip=acctp)==NULL)
61 		return;
62 	ilock(ip);
63 	for (i=0; i<sizeof(ap->ac_comm); i++)
64 		ap->ac_comm[i] = u.u_comm[i];
65 	ap->ac_utime = compress((long)u.u_vm.vm_utime);
66 	ap->ac_stime = compress((long)u.u_vm.vm_stime);
67 	ap->ac_etime = compress((long)(time - u.u_start));
68 	ap->ac_btime = u.u_start;
69 	ap->ac_uid = u.u_ruid;
70 	ap->ac_gid = u.u_rgid;
71 	ap->ac_mem = 0;
72 	if (i = u.u_vm.vm_utime + u.u_vm.vm_stime)
73 		ap->ac_mem = (u.u_vm.vm_ixrss + u.u_vm.vm_idsrss) / i;
74 	ap->ac_io = compress((long)(u.u_vm.vm_inblk + u.u_vm.vm_oublk));
75 	if (u.u_ttyp)
76 		ap->ac_tty = u.u_ttyd;
77 	else
78 		ap->ac_tty = NODEV;
79 	ap->ac_flag = u.u_acflag;
80 	siz = ip->i_size;
81 	u.u_offset = siz;
82 	u.u_base = (caddr_t)ap;
83 	u.u_count = sizeof(acctbuf);
84 	u.u_segflg = 1;
85 	u.u_error = 0;
86 	writei(ip);
87 	if(u.u_error)
88 		ip->i_size = siz;
89 	iunlock(ip);
90 }
91 
92 /*
93  * Produce a pseudo-floating point representation
94  * with 3 bits base-8 exponent, 13 bits fraction.
95  */
96 compress(t)
97 register long t;
98 {
99 	register exp = 0, round = 0;
100 
101 	while (t >= 8192) {
102 		exp++;
103 		round = t&04;
104 		t >>= 3;
105 	}
106 	if (round) {
107 		t++;
108 		if (t >= 8192) {
109 			t >>= 3;
110 			exp++;
111 		}
112 	}
113 	return((exp<<13) + t);
114 }
115