|
|
researchv10 Norman
/* sys3.c 4.9 81/03/08 */
#include "sys/param.h"
#include "sys/systm.h"
#include "sys/buf.h"
#include "sys/user.h"
#include "sys/inode.h"
#include "sys/file.h"
#include "sys/conf.h"
#include "sys/stat.h"
/*
* the fstat system call.
*/
fstat()
{
register struct file *fp;
register struct a {
int fdes;
struct stat *sb;
} *uap;
register struct inode *ip;
uap = (struct a *)u.u_ap;
fp = getf(uap->fdes);
if(fp == NULL) {
u.u_error = EBADF;
return;
}
ip = fp->f_inode;
plock(ip);
iupdat(ip, &time, &time, 0);
(*fstypsw[ip->i_fstyp]->t_stat)(ip, uap->sb);
prele(ip);
}
/*
* the stat system call. This version follows links.
*/
stat()
{
register struct inode *ip;
register struct a {
char *fname;
struct stat *sb;
} *uap;
uap = (struct a *)u.u_ap;
ip = namei(uap->fname, SEGUDATA, &nilargnamei, 1);
if(ip == NULL)
return;
iupdat(ip, &time, &time, 0);
(*fstypsw[ip->i_fstyp]->t_stat)(ip, uap->sb);
iput(ip);
}
/*
* the lstat system call. This version does not follow links.
*/
lstat()
{
register struct inode *ip;
register struct a {
char *fname;
struct stat *sb;
} *uap;
uap = (struct a *)u.u_ap;
ip = namei(uap->fname, SEGUDATA, &nilargnamei, 0);
if(ip == NULL)
return;
iupdat(ip, &time, &time, 0);
(*fstypsw[ip->i_fstyp]->t_stat)(ip, uap->sb);
iput(ip);
}
/*
* readlink -- return target name of a symbolic link
*/
readlink()
{
register struct inode *ip;
register struct a {
char *name;
char *buf;
int count;
} *uap;
uap = (struct a *)u.u_ap;
ip = namei(uap->name, SEGUDATA, &nilargnamei, 0);
if (ip == NULL)
return;
if ((ip->i_mode&IFMT) != IFLNK) {
u.u_error = ENXIO;
goto out;
}
u.u_offset = ltoL(0);
u.u_base = uap->buf;
u.u_count = uap->count;
u.u_segflg = SEGUDATA;
readi(ip);
out:
iput(ip);
u.u_r.r_val1 = uap->count - u.u_count;
}
/*
* symlink -- make a symbolic link
*/
symlink()
{
register struct a {
char *target;
char *linkname;
} *uap;
register struct inode *ip;
register nc;
struct argnamei nmarg;
uap = (struct a *)u.u_ap;
if ((nc = fustrlen(uap->target)) < 0) {
u.u_error = EFAULT;
return;
}
nc--; /* fustrlen includes NUL at end */
nmarg = nilargnamei;
nmarg.flag = NI_NXCREAT;
nmarg.un.mode = IFLNK|0777;
ip = namei(uap->linkname, SEGUDATA, &nmarg, 0);
if (ip == NULL)
return;
u.u_base = uap->target;
u.u_count = nc;
u.u_offset = ltoL(0);
u.u_segflg = SEGUDATA;
writei(ip);
iput(ip);
}
/*
* the dup system call.
*/
dup()
{
register struct file *fp;
register struct a {
int fdes;
int fdes2;
} *uap;
register i, m;
uap = (struct a *)u.u_ap;
m = uap->fdes & ~077;
uap->fdes &= 077;
fp = getf(uap->fdes);
if(fp == NULL) {
u.u_error = EBADF;
return;
}
if ((m&0100) == 0) {
if ((i = ufalloc()) < 0)
return;
} else {
i = uap->fdes2;
if (i<0 || i>=NOFILE) {
u.u_error = EBADF;
return;
}
u.u_r.r_val1 = i;
}
if (i!=uap->fdes) {
if (u.u_ofile[i]!=NULL)
closef(u.u_ofile[i]);
u.u_ofile[i] = fp;
u.u_pofile[i] = 0;
fp->f_count++;
}
}
/* dirread(fd, buf, buflen) */
dirread()
{ struct a {
int fdes;
char *buf;
int len;
} *uap;
register struct file *fp;
register struct inode *ip;
uap = (struct a *)u.u_ap;
fp = getf(uap->fdes);
if(fp == NULL) {
u.u_error = EBADF;
return;
}
if((fp->f_flag&FREAD) == 0) {
u.u_error = EBADF;
return;
}
u.u_offset = fp->f_offset;
u.u_base = uap->buf;
ip = fp->f_inode;
plock(ip);
ip->i_flag |= IACC;
(*fstypsw[ip->i_fstyp]->t_dirread)(ip, uap->len);
fp->f_offset = u.u_offset;
prele(ip);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.