return -EINVAL;
}
- /* required for strict SunOS emulation */
- if (O_NONBLOCK != O_NDELAY)
- if (arg & O_NDELAY)
- arg |= O_NONBLOCK;
+ lock_kernel();
+ if ((arg ^ filp->f_flags) & FASYNC) {
+ if (filp->f_op && filp->f_op->fasync) {
+ error = filp->f_op->fasync(fd, filp, (arg & FASYNC) != 0);
+ if (error < 0)
+ goto out;
+ }
+ }
filp->f_flags = (arg & SETFL_MASK) | (filp->f_flags & ~SETFL_MASK);
- return 0;
+ out:
+ unlock_kernel();
+ return error;
}
+ static void f_modown(struct file *filp, unsigned long pid,
+ uid_t uid, uid_t euid, int force)
+ {
+ write_lock_irq(&filp->f_owner.lock);
+ if (force || !filp->f_owner.pid) {
+ filp->f_owner.pid = pid;
+ filp->f_owner.uid = uid;
+ filp->f_owner.euid = euid;
+ }
+ write_unlock_irq(&filp->f_owner.lock);
+ }
+
+ int f_setown(struct file *filp, unsigned long arg, int force)
+ {
+ int err;
+
+ err = security_ops->file_set_fowner(filp);
+ if (err)
+ return err;
+
+ f_modown(filp, arg, current->uid, current->euid, force);
+ return 0;
+ }
+
+ void f_delown(struct file *filp)
+ {
+ f_modown(filp, 0, 0, 0, 1);
+ }
+
static long do_fcntl(unsigned int fd, unsigned int cmd,
unsigned long arg, struct file * filp)
{