Ausam/sys/ken/sys2.c

Find at most related files.
including files from this version of Unix.

#
#include "../defines.h"
#include "../param.h"
#ifdef	AUSAML
#include	"../lnode.h"
#endif	AUSAML
#include "../systm.h"
#include "../file.h"
#include "../user.h"
#include "../reg.h"
#include "../inode.h"
#include "../proc.h"

/*
 * read system call
 */
read()
{
	rdwr(FREAD);
}

/*
 * write system call
 */
write()
{
	rdwr(FWRITE);
}

/*
 * common code for read and write calls:
 * check permissions, set base, count, and offset,
 * and switch out to readi, writei, or pipe code.
 */
rdwr(mode)
{
	register *fp, *ip, m;			/* fix025 */

	m = mode;
	fp = getf(u.u_ar0[R0]);
	if(fp == NULL)
		return;
	if((fp->f_flag&m) == 0) {
		u.u_error = EBADF;
		return;
	}
	u.u_base = u.u_arg[0];
	u.u_count = u.u_arg[1];
	u.u_segflg = SEG_USD;
	if(fp->f_flag&FPIPE) {
		if(m==FREAD)
			readp(fp); else
			writep(fp);
	} else {
		ip = fp->f_inode;				/* fix025 */
		u.u_offset = fp->f_offset; /* fix000 */
		if( (ip->i_mode & (IFCHR&IFBLK)) == 0 )		/* fix025 */
			plock(ip);				/* fix025 */
		if(m==FREAD)
			readi(ip); else				/* fix025 */
			writei(ip);				/* fix025 */
		if( (ip->i_mode & (IFCHR&IFBLK)) == 0 )		/* fix025 */
			prele(ip);				/* fix025 */
		fp->f_offset =+ u.u_arg[1].unsignd - u.u_count.unsignd; /* fix000 */
	}
	u.u_ar0[R0] = u.u_arg[1]-u.u_count;
}

/*
 * open system call
 */
open()
{
	register *ip;
	extern uchar;

	ip = namei(&uchar, 0);
	if(ip == NULL)
		return;
	u.u_arg[1]++;
	open1(ip, u.u_arg[1], 0);
}

/*
 * creat system call
 */
creat()
{
	register *ip,*lp;
	extern uchar;

#ifdef	AUSAML
	if( (lp = u.u_procp->p_lnode) && (lp->l_flags & DLIMIT) )
	{
		/* he can't write so don't let create */
		u.u_error = EDISKLIM;
		return;
	}
#endif	AUSAML
	ip = namei(&uchar, 1);
	if(ip == NULL)
	{
		if(u.u_error)
			return;
		if ( (u.u_cdir->i_nlink == 0) && (fubyte( u.u_arg[0] ) != '/') )	/* fix006 */
		{
			u.u_error = ENOENT;						/* fix006 */
err:											/* fix006 */
			iput( u.u_pdir );	/* namei left parent dir locked */	/* fix006 */
			return;								/* fix006 */
		}									/* fix006 */
		ip = maknode(u.u_arg[1]&07777&(~ISVTX));
		if (ip==NULL)
			return;
		open1(ip, FWRITE, 2);
	}
	else
	{
		open1(ip, FWRITE, 1);
	}
}

/*
 * common code for open and creat.
 * Check permissions, allocate an open file structure,
 * and call the device open routine if any.
 */
open1(ip, mode, trf)
int *ip;
{
	register struct file *fp;
	register *rip, m;
	int i;

	rip = ip;
	m = mode;
	if(trf != 2) {
		if(m&FREAD)
			access(rip, IREAD);
		if(m&FWRITE) {
			access(rip, IWRITE);
			if((rip->i_mode&IFMT) == IFDIR)
				u.u_error = EISDIR;
		}
	}
	if(u.u_error)
		goto out;
	if(trf == 1)				/* fix025 */
		itrunc(rip);
	prele(rip);
	if ((fp = falloc()) == NULL)
		goto out;
	fp->f_flag = m&(FREAD|FWRITE);
	fp->f_inode = rip;
	i = u.u_ar0[R0];
	openi(rip, m&FWRITE);
	if(u.u_error == 0)
#ifndef	LOCKING
		return;
#else	LOCKING
	{
		if(ip->i_mode&ILPROTOCOL
		 && ip->i_mode&IAUTOLOCK
		 && (ip->i_mode&IFMT) != IFDIR)
		{
			lock(rip, (m&FWRITE) ? WLOCK : RLOCK);
			if(u.u_error)
				panic("lock?");
		}
		return;
	}
#endif	LOCKING
	u.u_ofile[i] = NULL;
	fp->f_count--;

out:
	iput(rip);
}

/*
 * close system call
 */
close()
{
	register *fp;

	fp = getf(u.u_ar0[R0]);
	if(fp == NULL)
		return;
	u.u_ofile[u.u_ar0[R0]] = NULL;
	closef(fp);
}

/*
 * seek system call
 */
seek()
{
	long n; /* fix000 */
	register *fp, t;

	fp = getf(u.u_ar0[R0]);
	if(fp == NULL)
		return;
	if(fp->f_flag&FPIPE) {
		u.u_error = ESPIPE;
		return;
	}
	t = u.u_arg[1];
	if(t > 2) {
		n.loint = u.u_arg[0]<<9;	/* fix000 */
		n.hiint = u.u_arg[0]>>7;	/* fix000 */
		if(t == 3)
			n.hiint =& 0777;	/* fix000 */
	} else {
		if( t==0 )			/* fix000 */
			n = u.u_arg[0].unsignd;	/* fix000 */
		else	n = u.u_arg[0];		/* fix000 */
	}
	switch(t) {

	case 1:
	case 4:
		n =+ fp->f_offset;		/* fix000 */
		break;

	default:
		n.hiint =+ fp->f_inode->i_size0&0377;	/* fix000 */
		n =+ fp->f_inode->i_size1.unsignd;	/* fix000 */

	case 0:
	case 3:
		;
	}
	if(n.hiint & ~0777)				/* fix025 */
		u.u_error = EFBIG;			/* fix025 */
	else						/* fix025 */
	{
		fp->f_offset = n; /* fix000 */
	}
}

/*
 * tell system call				   fix034
 */
tell()						/* fix034 */
{						/* fix034 */
	register *fp;				/* fix034 */
						/* fix034 */
	fp = getf(u.u_ar0[R0]);			/* fix034 */
	if(fp == NULL)				/* fix034 */
		return;				/* fix034 */
	u.u_ar0[R0] = fp->f_offset.hiint;	/* fix034 */
	u.u_ar0[R1] = fp->f_offset.loint;	/* fix034 */
}						/* fix034 */

/*
 * link system call
 */
link()
{
	register *ip, *xp;
	extern uchar;

	ip = namei(&uchar, 0);
	if(ip == NULL)
		return;
	if(ip->i_nlink >= 127) {
		u.u_error = EMLINK;
		goto out;
	}
	if((ip->i_mode&IFMT)==IFDIR && !suser())
		goto out;
	/*
	 * unlock to avoid possibly hanging the namei.
	 * Sadly, this means races. (Suppose someone	fix025
	 * deletes the file in the meantime ?)		fix025
	 * Nor can it be locked again later because	fix025
	 * then there will be deadly embraces.		fix025
	 */
	prele(ip);				/* fix025 */
	u.u_dirp = u.u_arg[1];
	xp = namei(&uchar, 1);
	if(xp != NULL) {
		u.u_error = EEXIST;
		iput(xp);
	}
	if(u.u_error)
		goto out;
	if(u.u_pdir->i_dev != ip->i_dev) {
		iput(u.u_pdir);
		u.u_error = EXDEV;
		goto out;
	}
	wdir(ip);
	ip->i_nlink++;
	ip->i_flag =| IUPD;

out:
	iput(ip);
}

/*
 * mknod system call
 */
mknod()
{
	register *ip;
	extern uchar;

	if(suser()) {
		ip = namei(&uchar, 1);
		if(ip != NULL) {
			u.u_error = EEXIST;
			goto out;
		}
	}
	if(u.u_error)
		return;
	ip = maknode(u.u_arg[1]);
	if (ip==NULL)
		return;
	ip->i_addr[0] = u.u_arg[2];

out:
	iput(ip);
}




/*
 * sleep system call
 * not to be confused with the sleep internal routine.
 */
sslep()
{
#ifdef	NEW_SLEEP

	register unsigned *p;

	p = &u.u_procp->p_stl;
	*p = u.u_ar0[R0].unsignd;	/* sleep for 'r0' seconds */
	while( *p )
		sleep(p,PSLEP);		/* sleep till time up */
#endif

#ifndef	NEW_SLEEP

	long  d;						/* fix000 */

	spl7();
	d = time + u.u_ar0[R0].unsignd;				/* fix000 */
	while( d > time ){					/* fix000 */
		if( tout <= time || tout > d )  tout = d;	/* fix000 */
		sleep(&tout, PSLEP);				/* fix000 */
	}
	spl0();
#endif
}
#ifdef	ACCESS

/*
 * access system call
 *
 *	sys access ; name ; mode
 *	access( name , mode )
 *
 *	char *name;
 *	int mode
 *
 *	mode specifies type of access(------RWX) to be checked for
 *	u.u_error is set by errors including permission violations !!
 */
saccess()
{
	extern uchar;
	register svuid;
#ifdef	GROUP_ACCESS
	register svgid;
#endif	GROUP_ACCESS
	register *ip;

	svuid = u.u_uid;
	u.u_uid = u.u_ruid;
#ifdef	GROUP_ACCESS
	svgid = u.u_gid;
	u.u_gid = u.u_rgid;
#endif	GROUP_ACCESS
	ip = namei(&uchar, 0);
	if (ip != NULL) {
		if (u.u_arg[1]&(IREAD>>6))
			access(ip, IREAD);
		if (u.u_arg[1]&(IWRITE>>6))
			access(ip, IWRITE);
		if (u.u_arg[1]&(IEXEC>>6))
			access(ip, IEXEC);
		iput(ip);
	}
	u.u_uid = svuid;
#ifdef	GROUP_ACCESS
	u.u_gid = svgid;
#endif	GROUP_ACCESS
}
#endif	ACCESS