+struct vnode *acctp;
+struct vnode *savacctp;
+
+/*
+ * Enable or disable process accounting.
+ *
+ * If a non-null filename is given, that file is used to store accounting
+ * records on process exit. If a null filename is given process accounting
+ * is suspended. If accounting is enabled, the system checks the amount
+ * of freespace on the filesystem at timeval intervals. If the amount of
+ * freespace is below acctsuspend percent, accounting is suspended. If
+ * accounting has been suspended, and freespace rises above acctresume,
+ * accounting is resumed.
+ */
+struct acct_args {
+ char *fname;
+};
+acct(p, uap, retval)
+ struct proc *p;
+ struct acct_args *uap;
+ int *retval;
+{
+ register struct vnode *vp;
+ extern void acctwatch __P((void *));
+ struct vnode *oacctp;
+ int error;
+ struct nameidata nd;
+
+ if (error = suser(p->p_ucred, &p->p_acflag))
+ return (error);
+ if (savacctp) {
+ acctp = savacctp;
+ savacctp = NULL;
+ }
+ if (uap->fname == NULL) {
+ if (vp = acctp) {
+ acctp = NULL;
+ error = vn_close(vp, FWRITE, p->p_ucred, p);
+ untimeout(acctwatch, NULL);
+ }
+ return (error);
+ }
+ NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->fname, p);
+ if (error = vn_open(&nd, FWRITE, 0644))
+ return (error);
+ vp = nd.ni_vp;
+ VOP_UNLOCK(vp);
+ if (vp->v_type != VREG) {
+ (void) vn_close(vp, FWRITE, p->p_ucred, p);
+ return (EACCES);
+ }
+ oacctp = acctp;
+ acctp = vp;
+ if (oacctp)
+ error = vn_close(oacctp, FWRITE, p->p_ucred, p);
+ acctwatch(NULL);
+ return (error);
+}