BBN-V6/ken/sys2.c
#
#include "../h/param.h"
#include "../h/systm.h"
#include "../h/user.h"
#include "../h/reg.h"
#include "../h/file.h"
#include "../h/inode.h"
#include "../h/conf.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, m;
register struct inode *ip;
extern int awakei();
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 NETWORK
if( fp->f_flag & FNET )
{
if( m == FREAD )
netread( fp, fp->f_netnode[ f_rdnode ] ); /* AGN */
else
netwrite( fp->f_netnode[ f_wrtnode ],
&u.u_base,
&u.u_count,
0
);
}
else
#endif
if(fp->f_flag&FPIPE) {
/* the following line put in for await/capac
* S.Y. Chiu 12Sept78
*/
awakei(fp->f_inode,-1); /* awake other end of pipe */
/* pass 0 flag to readp so it will call awakei
(BBN:mek 11/20/78 ) */
if(m==FREAD)
readp(fp,0); else
writep(fp);
} else {
u.u_offset[1] = fp->f_offset[1];
u.u_offset[0] = fp->f_offset[0];
ip = fp->f_inode;
if(m==FREAD)
readi(ip); else
writei(ip);
dpadd(fp->f_offset, u.u_arg[1]-u.u_count);
if (((ip->i_mode&IFMT) == 0) || ((ip->i_mode&IFMT) == IFDIR))
dpadd(u.u_io, 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
*/
creat()
{
register *ip;
extern uchar;
ip = namei(&uchar, 1);
if(ip == NULL) {
if(u.u_error)
return;
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( m < 1 || m > 7 )
{
m = (FREAD|FWRITE);
mode--;
}
if(trf != 2) {
if(m&FREAD)
access(rip, IREAD);
if(m&FEXCLU)
access(rip, IEXOPN);
if(m&(FWRITE|FEXCLU)) {
access(rip, IWRITE);
if((rip->i_mode&IFMT) == IFDIR)
u.u_error = EISDIR;
}
}
if(u.u_error)
goto out;
#ifdef NETWORK
if ( ((rip->i_mode & IFMT) == IFCHR) && (rip->i_addr[0].d_major <= 0177777) )
{
/* normal net open */
netopen( rip,mode );
return;
}
#endif
if(trf)
itrunc(rip);
prele(rip);
if ((fp = falloc()) == NULL)
goto out;
fp->f_flag = m&(FREAD|FWRITE|FEXCLU);
fp->f_inode = rip;
i = u.u_ar0[R0];
openi(rip, m&FWRITE);
if(u.u_error == 0)
{ if (m&FEXCLU)
rip->i_flag =| IEXCLU;
return;
}
u.u_ofile[i] = NULL;
fp->f_count--;
out:
iput(rip);
}
/*
* close system call
*
* Modified 2/78 (BBN:jfh) to disable (see awaitr.c)
*
*/
close()
{
register *fp;
fp = getf(u.u_ar0[R0]);
if(fp == NULL)
return;
awtdis(u.u_ar0[R0]); /* disable */
u.u_error=0; /* ignore any error (may not have been enb) */
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 NETWORK
if( fp->f_flag&FNET)
{
u.u_error = ESNET;
return;
}
#endif
if(fp->f_flag&(FPIPE|FPORT)) { /* "|FPORT" added at Rand - jsz 3/76 */
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&255) >= 255) { /* khd: mask off high bits */
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 =| IACC; /* IUPD to IACC jsq BBN 4-12-79 */
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()
{
char *d[2];
spl7();
d[0] = time[0];
d[1] = time[1];
dpadd(d, u.u_ar0[R0]);
while(dpcmp(d[0], d[1], time[0], time[1]) > 0) {
if(dpcmp(tout[0], tout[1], time[0], time[1]) <= 0 ||
dpcmp(tout[0], tout[1], d[0], d[1]) > 0) {
tout[0] = d[0];
tout[1] = d[1];
}
sleep(tout, 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;
}
/*
* reboot system primitive -- local mod
* put here to keep number of file modifications down
*/
reboot()
{
if (!suser()) { u.u_error = EPERM; return; }
/* arguments: major device, code for disk boot, inumber if (code) */
boot(u.u_ar0[R0], u.u_ar0[R4], u.u_ar0[R3]); /* in m70.s */
u.u_error = ENODEV; /* boot failed: nonexistent device */
}