-/* vfs_syscalls.c 4.14 81/11/16 */
+/* vfs_syscalls.c 4.18 82/02/27 */
#include "../h/param.h"
#include "../h/systm.h"
}
/*
- * Stat system call.
+ * Stat system call. This version does not follow links.
*/
stat()
{
} *uap;
uap = (struct a *)u.u_ap;
- ip = namei(uchar, 0);
+ ip = namei(uchar, 0, 0);
if (ip == NULL)
return;
stat1(ip, uap->sb);
iput(ip);
}
+/*
+ * Lstat system call. This version does follow links.
+ */
+lstat()
+{
+ register struct inode *ip;
+ register struct a {
+ char *fname;
+ struct stat *sb;
+ } *uap;
+
+ uap = (struct a *)u.u_ap;
+ ip = namei(uchar, 0, 1);
+ if (ip == NULL)
+ return;
+ stat1(ip, uap->sb, (off_t)0);
+ iput(ip);
+}
+
/*
* The basic routine for fstat and stat:
* get the inode and pass appropriate parts back.
ds.st_rdev = (dev_t)ip->i_un.i_rdev;
ds.st_size = ip->i_size;
/*
- * Next the dates in the disk
+ * next the dates in the disk
*/
bp = bread(ip->i_dev, itod(ip->i_number));
dp = bp->b_un.b_dino;
}
/*
- * Dup system call.
+ * Return target name of a symbolic link
+ */
+readlink()
+{
+ register struct inode *ip;
+ register struct a {
+ char *name;
+ char *buf;
+ int count;
+ } *uap;
+
+ ip = namei(uchar, 0, 0);
+ if (ip == NULL)
+ return;
+ if ((ip->i_mode&IFMT) != IFLNK) {
+ u.u_error = ENXIO;
+ goto out;
+ }
+ uap = (struct a *)u.u_ap;
+ u.u_offset = 0;
+ u.u_base = uap->buf;
+ u.u_count = uap->count;
+ u.u_segflg = 0;
+ 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 char *tp;
+ register c, nc;
+
+ uap = (struct a *)u.u_ap;
+ tp = uap->target;
+ nc = 0;
+ while (c = fubyte(tp)) {
+ if (c < 0) {
+ u.u_error = EFAULT;
+ return;
+ }
+ tp++;
+ nc++;
+ }
+ u.u_dirp = uap->linkname;
+ ip = namei(uchar, 1, 0);
+ if (ip) {
+ iput(ip);
+ u.u_error = EEXIST;
+ return;
+ }
+ ip = maknode(IFLNK | 0777);
+ if (ip == NULL)
+ return;
+ u.u_base = uap->target;
+ u.u_count = nc;
+ u.u_offset = 0;
+ u.u_segflg = 0;
+ writei(ip);
+ iput(ip);
+}
+
+/*
+ * the dup system call.
*/
dup()
{
}
if (i != uap->fdes) {
if (u.u_ofile[i]!=NULL)
- closef(u.u_ofile[i]);
+ closef(u.u_ofile[i], 0);
+ if (u.u_error)
+ return;
u.u_ofile[i] = fp;
fp->f_count++;
}
if (u.u_error)
return;
u.u_dirp = (caddr_t)uap->freg;
- ip = namei(uchar, 0);
+ ip = namei(uchar, 0, 1);
if (ip == NULL)
return;
if (ip->i_count!=1 || (ip->i_mode&IFMT) != IFDIR)
if (u.u_error)
return;
xumount(dev); /* remove unused sticky files from text table */
- update();
+ update(0);
for (mp = &mount[0]; mp < &mount[NMOUNT]; mp++)
if (mp->m_bufp != NULL && dev == mp->m_dev)
goto found;
if (!suser())
return(NODEV);
- ip = namei(uchar, 0);
+ ip = namei(uchar, 0, 1);
if (ip == NULL)
return(NODEV);
if ((ip->i_mode&IFMT) != IFBLK)