V10/sys/os/sys3.c

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

/*	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);
}