1*7376Skre /* kern_resource.c 4.9 82/07/12 */ 27Sbill 37Sbill #include "../h/param.h" 47Sbill #include "../h/systm.h" 57Sbill #include "../h/acct.h" 67Sbill #include "../h/dir.h" 77Sbill #include "../h/user.h" 87Sbill #include "../h/inode.h" 97Sbill #include "../h/proc.h" 107Sbill #include "../h/seg.h" 117Sbill 123098Swnj struct inode *acctp; 133098Swnj 147Sbill /* 157Sbill * Perform process accounting functions. 167Sbill */ 177Sbill sysacct() 187Sbill { 197Sbill register struct inode *ip; 207Sbill register struct a { 217Sbill char *fname; 227Sbill } *uap; 237Sbill 247Sbill uap = (struct a *)u.u_ap; 257Sbill if (suser()) { 267Sbill if (uap->fname==NULL) { 273109Swnj if (ip = acctp) { 287141Smckusick irele(ip); 297Sbill acctp = NULL; 307Sbill } 317Sbill return; 327Sbill } 335990Swnj ip = namei(uchar, 0, 1); 347Sbill if(ip == NULL) 357Sbill return; 367Sbill if((ip->i_mode & IFMT) != IFREG) { 377Sbill u.u_error = EACCES; 387Sbill iput(ip); 397Sbill return; 407Sbill } 41*7376Skre if (acctp && (acctp->i_number != ip->i_number || 42*7376Skre acctp->i_dev != ip->i_dev)) 43*7376Skre irele(acctp); 447Sbill acctp = ip; 457121Smckusick iunlock(ip); 467Sbill } 477Sbill } 487Sbill 493098Swnj struct acct acctbuf; 507Sbill /* 517Sbill * On exit, write a record on the accounting file. 527Sbill */ 537Sbill acct() 547Sbill { 557Sbill register i; 567Sbill register struct inode *ip; 577Sbill off_t siz; 583098Swnj register struct acct *ap = &acctbuf; 597Sbill 607Sbill if ((ip=acctp)==NULL) 617Sbill return; 624816Swnj ilock(ip); 633098Swnj for (i=0; i<sizeof(ap->ac_comm); i++) 643098Swnj ap->ac_comm[i] = u.u_comm[i]; 653098Swnj ap->ac_utime = compress((long)u.u_vm.vm_utime); 663098Swnj ap->ac_stime = compress((long)u.u_vm.vm_stime); 673098Swnj ap->ac_etime = compress((long)(time - u.u_start)); 683098Swnj ap->ac_btime = u.u_start; 693098Swnj ap->ac_uid = u.u_ruid; 703098Swnj ap->ac_gid = u.u_rgid; 713098Swnj ap->ac_mem = 0; 7289Sbill if (i = u.u_vm.vm_utime + u.u_vm.vm_stime) 733098Swnj ap->ac_mem = (u.u_vm.vm_ixrss + u.u_vm.vm_idsrss) / i; 743098Swnj ap->ac_io = compress((long)(u.u_vm.vm_inblk + u.u_vm.vm_oublk)); 75*7376Skre if (u.u_ttyp) 76*7376Skre ap->ac_tty = u.u_ttyd; 77*7376Skre else 78*7376Skre ap->ac_tty = NODEV; 793098Swnj ap->ac_flag = u.u_acflag; 807Sbill siz = ip->i_size; 817Sbill u.u_offset = siz; 823098Swnj u.u_base = (caddr_t)ap; 837Sbill u.u_count = sizeof(acctbuf); 847Sbill u.u_segflg = 1; 857Sbill u.u_error = 0; 867Sbill writei(ip); 877Sbill if(u.u_error) 887Sbill ip->i_size = siz; 897121Smckusick iunlock(ip); 907Sbill } 917Sbill 927Sbill /* 937Sbill * Produce a pseudo-floating point representation 947Sbill * with 3 bits base-8 exponent, 13 bits fraction. 957Sbill */ 967Sbill compress(t) 971784Sbill register long t; 987Sbill { 997Sbill register exp = 0, round = 0; 1007Sbill 1017Sbill while (t >= 8192) { 1027Sbill exp++; 1037Sbill round = t&04; 1047Sbill t >>= 3; 1057Sbill } 1067Sbill if (round) { 1077Sbill t++; 1087Sbill if (t >= 8192) { 1097Sbill t >>= 3; 1107Sbill exp++; 1117Sbill } 1127Sbill } 1137Sbill return((exp<<13) + t); 1147Sbill } 115