+ if (u.u_error)
+ return;
+ ip = maknode(IFLNK | 0777);
+ if (ip == NULL)
+ return;
+ u.u_error = rdwri(UIO_WRITE, ip, uap->target, nc, 0, 0, (int *)0);
+ iput(ip);
+}
+
+/*
+ * Unlink system call.
+ * Hard to avoid races here, especially
+ * in unlinking directories.
+ */
+unlink()
+{
+ register struct inode *ip, *pp;
+ struct a {
+ char *fname;
+ };
+ int unlinkingdot = 0;
+
+ pp = namei(uchar, 2, 0);
+ if (pp == NULL)
+ return;
+
+ /*
+ * Check for unlink(".")
+ * to avoid hanging on the iget
+ */
+ if (pp->i_number == u.u_dent.d_ino) {
+ ip = pp;
+ ip->i_count++;
+ unlinkingdot++;
+ } else
+ ip = iget(pp->i_dev, pp->i_fs, u.u_dent.d_ino);
+ if(ip == NULL)
+ goto out1;
+ if((ip->i_mode&IFMT)==IFDIR && !suser())
+ goto out;
+ /*
+ * Don't unlink a mounted file.
+ */
+ if (ip->i_dev != pp->i_dev) {
+ u.u_error = EBUSY;
+ goto out;
+ }
+ if (ip->i_flag&ITEXT)
+ xrele(ip); /* try once to free text */
+ if (dirremove()) {
+ ip->i_nlink--;
+ ip->i_flag |= ICHG;
+ }
+out:
+ if (unlinkingdot)
+ irele(ip);
+ else
+ iput(ip);
+out1:
+ iput(pp);
+}
+
+/*
+ * Seek system call
+ */
+lseek()
+{
+ register struct file *fp;
+ register struct a {
+ int fd;
+ off_t off;
+ int sbase;
+ } *uap;
+
+ uap = (struct a *)u.u_ap;
+ fp = getf(uap->fd);
+ if (fp == NULL)
+ return;
+ if (fp->f_type == DTYPE_SOCKET) {
+ u.u_error = ESPIPE;
+ return;
+ }
+ if (uap->sbase == FSEEK_RELATIVE)
+ uap->off += fp->f_offset;
+ else if (uap->sbase == FSEEK_EOF)
+ uap->off += fp->f_inode->i_size;
+ fp->f_offset = uap->off;
+ u.u_r.r_off = uap->off;
+}
+
+/*
+ * Access system call
+ */
+saccess()
+{
+ register svuid, svgid;
+ register struct inode *ip;
+ register struct a {
+ char *fname;
+ int fmode;
+ } *uap;
+
+ uap = (struct a *)u.u_ap;
+ svuid = u.u_uid;
+ svgid = u.u_gid;
+ u.u_uid = u.u_ruid;
+ u.u_gid = u.u_rgid;
+ ip = namei(uchar, 0, 1);
+ if (ip != NULL) {
+ if (uap->fmode&FACCESS_READ && access(ip, IREAD))
+ goto done;
+ if (uap->fmode&FACCESS_WRITE && access(ip, IWRITE))
+ goto done;
+ if (uap->fmode&FACCESS_EXECUTE && access(ip, IEXEC))
+ goto done;
+done:
+ iput(ip);
+ }
+ u.u_uid = svuid;
+ u.u_gid = svgid;
+}
+
+/*
+ * the fstat system call.
+ */
+fstat()
+{
+ register struct file *fp;
+ register struct a {
+ int fd;
+ struct stat *sb;
+ } *uap;
+
+ uap = (struct a *)u.u_ap;
+ fp = getf(uap->fd);
+ if (fp == NULL)
+ return;
+ if (fp->f_type == DTYPE_SOCKET)
+ u.u_error = sostat(fp->f_socket, uap->sb);
+ else
+ stat1(fp->f_inode, uap->sb);