+
+/*
+ * Apply an advisory lock on a file descriptor.
+ */
+flock()
+{
+ register struct a {
+ int fd;
+ int how;
+ } *uap = (struct a *)u.u_ap;
+ register struct file *fp;
+ register u_char *pf;
+ int cmd;
+
+ fp = getf(uap->fd);
+ if (fp == NULL)
+ return;
+ cmd = uap->how;
+ pf = (u_char *)&u.u_pofile[uap->fd];
+ if (cmd & LOCK_UN) {
+ unlockf(fp, pf);
+ return;
+ }
+ /*
+ * No reason to write lock a file we've already
+ * write locked, similarly with a read lock.
+ */
+ if ((*pf & UF_EXLOCK) && (cmd & LOCK_EX) ||
+ (*pf & UF_SHLOCK) && (cmd & LOCK_SH))
+ return;
+ switch (fp->f_type) {
+
+ case DTYPE_INODE:
+ u.u_error = ino_lock((struct inode *)fp->f_data, pf, cmd);
+ break;
+
+ case DTYPE_SOCKET:
+ u.u_error = soo_lock((struct socket *)fp->f_data, pf, cmd);
+ break;
+
+ default:
+ panic("lockf");
+ }
+}
+
+unlockf(fp, pf)
+ register struct file *fp;
+ register u_char *pf;
+{
+
+ if ((*pf & (UF_SHLOCK|UF_EXLOCK)) == 0)
+ return;
+ switch (fp->f_type) {
+
+ case DTYPE_INODE:
+ ino_unlock((struct inode *)fp->f_data, *pf);
+ break;
+
+ case DTYPE_SOCKET:
+ soo_unlock((struct socket *)fp->f_data, *pf);
+ break;
+
+ default:
+ panic("unlockf");
+ }
+ *pf &= ~(UF_SHLOCK|UF_EXLOCK);
+}