1 /* kern_resource.c 4.8 82/06/10 */ 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 if (acctp) { 34 u.u_error = EBUSY; 35 return; 36 } 37 ip = namei(uchar, 0, 1); 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 iunlock(ip); 47 } 48 } 49 50 struct acct acctbuf; 51 /* 52 * On exit, write a record on the accounting file. 53 */ 54 acct() 55 { 56 register i; 57 register struct inode *ip; 58 off_t siz; 59 register struct acct *ap = &acctbuf; 60 61 if ((ip=acctp)==NULL) 62 return; 63 ilock(ip); 64 for (i=0; i<sizeof(ap->ac_comm); i++) 65 ap->ac_comm[i] = u.u_comm[i]; 66 ap->ac_utime = compress((long)u.u_vm.vm_utime); 67 ap->ac_stime = compress((long)u.u_vm.vm_stime); 68 ap->ac_etime = compress((long)(time - u.u_start)); 69 ap->ac_btime = u.u_start; 70 ap->ac_uid = u.u_ruid; 71 ap->ac_gid = u.u_rgid; 72 ap->ac_mem = 0; 73 if (i = u.u_vm.vm_utime + u.u_vm.vm_stime) 74 ap->ac_mem = (u.u_vm.vm_ixrss + u.u_vm.vm_idsrss) / i; 75 ap->ac_io = compress((long)(u.u_vm.vm_inblk + u.u_vm.vm_oublk)); 76 ap->ac_tty = u.u_ttyd; 77 ap->ac_flag = u.u_acflag; 78 siz = ip->i_size; 79 u.u_offset = siz; 80 u.u_base = (caddr_t)ap; 81 u.u_count = sizeof(acctbuf); 82 u.u_segflg = 1; 83 u.u_error = 0; 84 writei(ip); 85 if(u.u_error) 86 ip->i_size = siz; 87 iunlock(ip); 88 } 89 90 /* 91 * Produce a pseudo-floating point representation 92 * with 3 bits base-8 exponent, 13 bits fraction. 93 */ 94 compress(t) 95 register long t; 96 { 97 register exp = 0, round = 0; 98 99 while (t >= 8192) { 100 exp++; 101 round = t&04; 102 t >>= 3; 103 } 104 if (round) { 105 t++; 106 if (t >= 8192) { 107 t >>= 3; 108 exp++; 109 } 110 } 111 return((exp<<13) + t); 112 } 113