1 /*	kern_resource.c	3.1	10/14/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 /*
13  * Perform process accounting functions.
14  */
15 
16 sysacct()
17 {
18 	register struct inode *ip;
19 	register struct a {
20 		char	*fname;
21 	} *uap;
22 
23 	uap = (struct a *)u.u_ap;
24 	if (suser()) {
25 		if (uap->fname==NULL) {
26 			if (acctp) {
27 				plock(acctp);
28 				iput(acctp);
29 				acctp = NULL;
30 			}
31 			return;
32 		}
33 		if (acctp) {
34 			u.u_error = EBUSY;
35 			return;
36 		}
37 		ip = namei(uchar, 0);
38 		if(ip == NULL)
39 			return;
40 		if((ip->i_mode & IFMT) != IFREG) {
41 			u.u_error = EACCES;
42 			iput(ip);
43 			return;
44 		}
45 		acctp = ip;
46 		prele(ip);
47 	}
48 }
49 
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 
59 	if ((ip=acctp)==NULL)
60 		return;
61 	plock(ip);
62 	for (i=0; i<sizeof(acctbuf.ac_comm); i++)
63 		acctbuf.ac_comm[i] = u.u_comm[i];
64 	acctbuf.ac_utime = compress(u.u_vm.vm_utime);
65 	acctbuf.ac_stime = compress(u.u_vm.vm_stime);
66 	acctbuf.ac_etime = compress(time - u.u_start);
67 	acctbuf.ac_btime = u.u_start;
68 	acctbuf.ac_uid = u.u_ruid;
69 	acctbuf.ac_gid = u.u_rgid;
70 	acctbuf.ac_mem = 0;
71 	acctbuf.ac_io = 0;
72 	acctbuf.ac_tty = u.u_ttyd;
73 	acctbuf.ac_flag = u.u_acflag;
74 	siz = ip->i_size;
75 	u.u_offset = siz;
76 	u.u_base = (caddr_t)&acctbuf;
77 	u.u_count = sizeof(acctbuf);
78 	u.u_segflg = 1;
79 	u.u_error = 0;
80 	writei(ip);
81 	if(u.u_error)
82 		ip->i_size = siz;
83 	prele(ip);
84 }
85 
86 /*
87  * Produce a pseudo-floating point representation
88  * with 3 bits base-8 exponent, 13 bits fraction.
89  */
90 compress(t)
91 register time_t t;
92 {
93 	register exp = 0, round = 0;
94 
95 	while (t >= 8192) {
96 		exp++;
97 		round = t&04;
98 		t >>= 3;
99 	}
100 	if (round) {
101 		t++;
102 		if (t >= 8192) {
103 			t >>= 3;
104 			exp++;
105 		}
106 	}
107 	return((exp<<13) + t);
108 }
109 
110 /*
111  * lock user into core as much
112  * as possible. swapping may still
113  * occur if core grows.
114  */
115 syslock()
116 {
117 	register struct proc *p;
118 	register struct a {
119 		int	flag;
120 	} *uap;
121 
122 	uap = (struct a *)u.u_ap;
123 	if(suser()) {
124 		p = u.u_procp;
125 		p->p_flag &= ~SULOCK;
126 		if(uap->flag)
127 			p->p_flag |= SULOCK;
128 	}
129 }
130