Ausam/sys/ken/sys2.c
#
#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