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