Ultrix-3.1/sys/sys/acct.c

Compare this file to the similar file:
Show the results in this format:


/**********************************************************************
 *   Copyright (c) Digital Equipment Corporation 1984, 1985, 1986.    *
 *   All Rights Reserved. 					      *
 *   Reference "/usr/src/COPYRIGHT" for applicable restrictions.      *
 **********************************************************************/

/*
 * SCCSID: @(#)acct.c	3.0	4/21/86
 */
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/acct.h>
#include <sys/dir.h>
#include <sys/user.h>
#include <sys/inode.h>
#include <sys/proc.h>
#include <sys/seg.h>
#include <sys/text.h>
#include <sys/lock.h>

#ifdef	ACCT

/*
 * Perform process accounting functions.
 */

sysacct()
{
	register struct inode *ip;
	register struct a {
		char	*fname;
	} *uap;

	uap = (struct a *)u.u_ap;
	if (suser()) {
		if (uap->fname==NULL) {
			if (acctp) {
				plock(acctp);
				iput(acctp);
				acctp = NULL;
			}
			return;
		}
		if (acctp) {
			u.u_error = EBUSY;
			return;
		}
#ifdef	UCB_SYMLINKS
		ip = namei(uchar, LOOKUP, 1);
#else	UCB_SYMLINKS
		ip = namei(uchar, LOOKUP);
#endif	UCB_SYMLINKS
		if(ip == NULL)
			return;
		if((ip->i_mode & IFMT) != IFREG) {
			u.u_error = EACCES;
			iput(ip);
			return;
		}
		acctp = ip;
		prele(ip);
	}
}
#endif	ACCT

/*
 * On exit, write a record on the accounting file.
 */
acct()
{
#ifdef	ACCT
	register i;
	register struct inode *ip;
	off_t siz;

	if ((ip=acctp)==NULL)
		return;
	plock(ip);
	for (i=0; i<sizeof(acctbuf.ac_comm); i++)
		acctbuf.ac_comm[i] = u.u_comm[i];
	acctbuf.ac_utime = compress(u.u_utime);
	acctbuf.ac_stime = compress(u.u_stime);
	acctbuf.ac_etime = compress(time - u.u_start);
	acctbuf.ac_btime = u.u_start;
	acctbuf.ac_uid = u.u_ruid;
	acctbuf.ac_gid = u.u_rgid;
	acctbuf.ac_mem = 0;
	acctbuf.ac_io = 0;
	acctbuf.ac_tty = u.u_ttyd;
	acctbuf.ac_flag = u.u_acflag;
	siz = ip->i_size;
	u.u_offset = siz;
	u.u_base = (caddr_t)&acctbuf;
	u.u_count = sizeof(acctbuf);
	u.u_segflg = 1;
	u.u_error = 0;
	u.u_limit = (daddr_t)5000;
	writei(ip);
	if(u.u_error)
		ip->i_size = siz;
	prele(ip);
#endif	ACCT
}

#ifdef	ACCT
/*
 * Produce a pseudo-floating point representation
 * with 3 bits base-8 exponent, 13 bits fraction.
 */
static
compress(t)
register time_t t;
{
	register exp = 0, round = 0;

	while (t >= 8192) {
		exp++;
		round = t&04;
		t >>= 3;
	}
	if (round) {
		t++;
		if (t >= 8192) {
			t >>= 3;
			exp++;
		}
	}
	return((exp<<13) + t);
}
#endif	ACCT

/*
 * lock user into core as much
 * as possible. swapping may still
 * occur if core grows.
 */

char	runlock;	/* used to tell sched when to call shuffle */

syslock()
{
	register struct proc *p;
	register struct a {
		int	flag;
	} *uap;
	register struct text *xp;

	uap = (struct a *)u.u_ap;
	if (suser()) {
		p = u.u_procp;
		xp = p->p_textp;
		switch(uap->flag) {
		case UNLOCK:		/* unlock a process */
			if (p->p_flag&(SULKMSK)) {
				punlock();
				return;
			}
			goto bad;

		case TXTLOCK:		/* lock text segment of a shared text */
			if ((p->p_flag&(SULOCKT)) || (u.u_procp->p_textp==NULL))
				goto bad;
			p->p_flag |= (SULOCKT);
			if (xp->x_lcount++ == 0) {
				runlock++;
				xp->x_ccount++;
			}
			break;

		case DATLOCK:		/* lock data segment of a shared text */
			if ((p->p_flag&(SULOCKD)) || (u.u_procp->p_textp==NULL))
				goto bad;
			p->p_flag |= (SULOCKD);
			runlock++;
			break;

	/* The v7 lock call will satisfy this case */
		case PROCLOCK:		/* lock text and data of a  process */
			if (p->p_flag&(SULKMSK))
				goto bad;
			p->p_flag |= (SULKMSK);
			if (u.u_procp->p_textp != NULL)
				if (xp->x_lcount++ == 0) {
					xp->x_ccount++;
				}
			runlock++;
			break;

		default:
			goto bad;
		}
		if (runlock==0)
			return;
		if (runout) {		/* wakeup sched to shuffle */
			runout = 0;
			wakeup((caddr_t)&runout);
		}
		sleep((caddr_t)&runlock,PZERO-1); /* shuffle will wake us up */
		return;

bad:
		u.u_error = EINVAL;
	}
}

punlock()
{
	struct text *xp;

	u.u_procp->p_flag &= ~(SULKMSK);
	if (((xp=u.u_procp->p_textp) != NULL) && ( --(xp->x_lcount) == 0))
		xccdec(xp);
	runlock++;
}