SRI-NOSC/ken/sys2.c

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

#
#include "param.h"
#include "systm.h"
#include "user.h"
#include "proc.h"
#include "reg.h"
#include "file.h"
#include "inode.h"
#ifdef NETSYS
#include "conf.h"
#endif NETSYS

/*
 * 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, m;

	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 = 0;
#ifdef NETSYS
	if( fp->f_flag & FNET )
	{
		if( m == FREAD )
			netread( fp->f_netnode[ f_rdnode ] );
		else
			netwrite( fp->f_netnode[ f_wrtnode ]);
	}
	else
#endif NETSYS
	if(fp->f_flag&FPIPE) {
		if(m==FREAD)
			readp(fp); else
			writep(fp);
	} else {
		u.u_offset[1] = fp->f_offset[1];
		u.u_offset[0] = fp->f_offset[0];
		if(m==FREAD)
			readi(fp->f_inode); else
			writei(fp->f_inode);
		dpadd(fp->f_offset, u.u_arg[1]-u.u_count);
	}
	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
 *
 * bug fix reported May-June 1977
 * UNIX NEWS Vol 2, No. 5 p5-3
 * George Goble - Purdue University
 */
creat()
{
	register *ip;
	extern uchar;

	ip = namei(&uchar, 1);
	if(ip == NULL) {
		if(u.u_error)
			return;
		if( (u.u_cdir->i_nlink == 0)		/* bug fix */
		  && (fubyte(u.u_arg[0]) != '/') ) {	/* bug fix */
			u.u_error = ENOENT;             /* bug fix */
	err:            iput(u.u_pdir); /* namei left parent dir locked */
							/* bug fix */
			return;         /* bug fix */
		}
		ip = maknode(u.u_arg[1]&07777&(~ISVTX));
		if (ip==NULL)
			goto err;       /* bug fix */
		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;
#ifdef NETSYS
	if( m < 1 || m > 3 )
	{
		m = (FREAD|FWRITE);
		mode--;
	}
#endif NETSYS
	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;
#ifdef NETSYS
	if ( ((rip->i_mode & IFMT) == IFCHR)
		&& (rip->i_addr[0].d_major <= 0177777) )
	{
		/* normal net open */
		netopen( rip,mode );
		return;
	}
#endif NETSYS
	if(trf)
		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)
		return;
	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()
{
	int n[2];
	register *fp, t;

	fp = getf(u.u_ar0[R0]);
	if(fp == NULL)
		return;
#ifdef NETSYS
	if( fp->f_flag&FNET) 
	{
		u.u_error = ESNET;
		return;
	}
#endif NETSYS
	if(fp->f_flag&FPIPE) {
		u.u_error = ESPIPE;
		return;
	}
	t = u.u_arg[1];
	if(t > 2) {
		n[1] = u.u_arg[0]<<9;
		n[0] = u.u_arg[0]>>7;
		if(t == 3)
			n[0] =& 0777;
	} else {
		n[1] = u.u_arg[0];
		n[0] = 0;
		if(t!=0 && n[1]<0)
			n[0] = -1;
	}
	switch(t) {

	case 1:
	case 4:
		n[0] =+ fp->f_offset[0];
		dpadd(n, fp->f_offset[1]);
		break;

	default:
		n[0] =+ fp->f_inode->i_size0&0377;
		dpadd(n, fp->f_inode->i_size1);

	case 0:
	case 3:
		;
	}
	fp->f_offset[1] = n[1];
	fp->f_offset[0] = n[0];
}

/*
 * 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
	 */
	ip->i_flag =& ~ILOCK;
	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()
{
	/*
	 * modified 31Oct77 by J.S.Kravitz and R.J.Balocca to
	 * make sleep better (no unneeded swaps)
	 *
	 * note that sleep now changes 'alarm' value, it is not
	 * a good idea to enter sleep with an alarm set... not
	 * a common mode of programming anyway
	 */
	alarm ();	/* set up alarm clock with parameters from user */
	spl6();
	while (u.u_procp->p_clktim)
		sleep (&u.u_procp->p_clktim, PSLEP);
	spl0();
}

/*
 * access system call
 */
saccess()
{
	extern uchar;
	register svuid, svgid;
	register *ip;

	svuid = u.u_uid;
	svgid = u.u_gid;
	u.u_uid = u.u_ruid;
	u.u_gid = u.u_rgid;
	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;
	u.u_gid = svgid;
}

#ifdef NETSYS
/*
 *	tell the ncpdaemon to reset all he knows about a host 
 */
net_reset()
{

	struct
	{
		char  net_op;
		char  net_rsthost;
	}nreset;


	register char *ip;
	extern uchar;

	if (!suser())
	{
		return;			/* suser sets u.u_error to EPERM */
	}
	nreset.net_op = 4;	/* assign reset opcode for daemon */
	nreset.net_rsthost = u.u_ar0[R0];	/* assign host number*/
	switch ( to_ncp (&nreset, 2, 0) )	/* send instruction to daemon */
	{
	case 0:
		u.u_ar0[R0] = 0;
		return;

	case 1:
		u.u_error = ENCPBUF;
		return;

	default:	/* -1 and anything else we dont know about */
		u.u_error = ENCPNO;
		return;
	}
}
#endif NETSYS