+
+flock()
+{
+ struct a {
+ int fd;
+ int how;
+ } *uap;
+ register struct file *fp;
+ register int cmd, flags;
+
+ uap = (struct a *)u.u_ap;
+ fp = getf(uap->fd);
+ if (fp == NULL)
+ return;
+ if (fp->f_type == DTYPE_SOCKET) { /* XXX */
+ u.u_error = EINVAL;
+ return;
+ }
+ cmd = uap->how;
+ flags = u.u_pofile[uap->fd] & (RDLOCK|WRLOCK);
+ if (cmd&FUNLOCK) {
+ if (flags == 0) {
+ u.u_error = EINVAL;
+ return;
+ }
+ funlocki(fp->f_inode, flags);
+ u.u_pofile[uap->fd] &= ~(RDLOCK|WRLOCK);
+ return;
+ }
+ /*
+ * No reason to write lock a file we've already
+ * write locked, similarly with a read lock.
+ */
+ if ((flags&WRLOCK) && (cmd&FWRLOCK) ||
+ (flags&RDLOCK) && (cmd&FRDLOCK))
+ return;
+ u.u_pofile[uap->fd] = flocki(fp->f_inode, u.u_pofile[uap->fd], cmd);
+}
+
+truncate()
+{
+ struct a {
+ char *fname;
+ int length;
+ } *uap = (struct a *)u.u_ap;
+ struct inode *ip;
+
+ ip = namei(uchar, 0, 1);
+ if (ip == NULL)
+ return;
+ if (access(ip, IWRITE))
+ goto bad;
+ if ((ip->i_mode&IFMT) == IFDIR) {
+ u.u_error = EISDIR;
+ goto bad;
+ }
+ itrunc(ip, uap->length);
+ return;
+bad:
+ iput(ip);
+}
+
+ftruncate()
+{
+ struct a {
+ int fd;
+ int length;
+ } *uap = (struct a *)u.u_ap;
+ struct inode *ip;
+ struct file *fp;
+
+ fp = getf(uap->fd);
+ if (fp == NULL)
+ return;
+ if (fp->f_type == DTYPE_SOCKET) {
+ u.u_error = EINVAL;
+ return;
+ }
+ if ((fp->f_flag&FWRITE) == 0) {
+ u.u_error = EINVAL;
+ return;
+ }
+ ip = fp->f_inode;
+ ilock(ip);
+ itrunc(ip, uap->length);
+}
+
+rename()
+{
+#ifdef notdef
+ struct a {
+ char *from;
+ char *to;
+ } *uap;
+#endif
+
+}
+
+/*
+ * Make a new file.
+ */
+struct inode *
+maknode(mode)
+ int mode;
+{
+ register struct inode *ip;
+ ino_t ipref;
+
+ if ((mode & IFMT) == IFDIR)
+ ipref = dirpref(u.u_pdir->i_fs);
+ else
+ ipref = u.u_pdir->i_number;
+ ip = ialloc(u.u_pdir, ipref, mode);
+ if (ip == NULL) {
+ iput(u.u_pdir);
+ return (NULL);
+ }
+#ifdef QUOTA
+ if (ip->i_dquot != NODQUOT)
+ panic("maknode: dquot");
+#endif
+ ip->i_flag |= IACC|IUPD|ICHG;
+ if ((mode & IFMT) == 0)
+ mode |= IFREG;
+ ip->i_mode = mode & ~u.u_cmask;
+ ip->i_nlink = 1;
+ ip->i_uid = u.u_uid;
+ ip->i_gid = u.u_pdir->i_gid;
+#ifdef QUOTA
+ ip->i_dquot = inoquota(ip);
+#endif
+
+ /*
+ * Make sure inode goes to disk before directory entry.
+ */
+ iupdat(ip, &time.tv_sec, &time.tv_sec, 1);
+ direnter(ip);
+ if (u.u_error) {
+ /*
+ * write error occurred trying to update directory
+ * so must deallocate the inode
+ */
+ ip->i_nlink = 0;
+ ip->i_flag |= ICHG;
+ iput(ip);
+ return (NULL);
+ }
+ return (ip);
+}