|
|
1.1.1.2 root 1: /*
2: * linux/fs/fcntl.c
3: *
1.1.1.7 root 4: * Copyright (C) 1991, 1992 Linus Torvalds
1.1.1.2 root 5: */
6:
1.1.1.4 root 7: #include <asm/segment.h>
8:
1.1.1.7 root 9: #include <linux/sched.h>
10: #include <linux/kernel.h>
11: #include <linux/errno.h>
1.1.1.6 root 12: #include <linux/stat.h>
13: #include <linux/fcntl.h>
1.1.1.4 root 14: #include <linux/string.h>
15:
1.1 root 16: extern int sys_close(int fd);
1.1.1.8 ! root 17: extern int fcntl_getlk(unsigned int, struct flock *);
! 18: extern int fcntl_setlk(unsigned int, unsigned int, struct flock *);
1.1 root 19:
20: static int dupfd(unsigned int fd, unsigned int arg)
21: {
22: if (fd >= NR_OPEN || !current->filp[fd])
23: return -EBADF;
24: if (arg >= NR_OPEN)
25: return -EINVAL;
26: while (arg < NR_OPEN)
27: if (current->filp[arg])
28: arg++;
29: else
30: break;
31: if (arg >= NR_OPEN)
32: return -EMFILE;
33: current->close_on_exec &= ~(1<<arg);
34: (current->filp[arg] = current->filp[fd])->f_count++;
35: return arg;
36: }
37:
38: int sys_dup2(unsigned int oldfd, unsigned int newfd)
39: {
1.1.1.5 root 40: if (oldfd >= NR_OPEN || !current->filp[oldfd])
41: return -EBADF;
1.1.1.3 root 42: if (newfd == oldfd)
43: return newfd;
1.1 root 44: sys_close(newfd);
45: return dupfd(oldfd,newfd);
46: }
47:
48: int sys_dup(unsigned int fildes)
49: {
50: return dupfd(fildes,0);
51: }
52:
53: int sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
54: {
55: struct file * filp;
1.1.1.8 ! root 56: extern int sock_fcntl (struct file *, unsigned int cmd,
! 57: unsigned long arg);
1.1 root 58: if (fd >= NR_OPEN || !(filp = current->filp[fd]))
59: return -EBADF;
60: switch (cmd) {
61: case F_DUPFD:
62: return dupfd(fd,arg);
63: case F_GETFD:
64: return (current->close_on_exec>>fd)&1;
65: case F_SETFD:
66: if (arg&1)
67: current->close_on_exec |= (1<<fd);
68: else
69: current->close_on_exec &= ~(1<<fd);
70: return 0;
71: case F_GETFL:
72: return filp->f_flags;
73: case F_SETFL:
74: filp->f_flags &= ~(O_APPEND | O_NONBLOCK);
75: filp->f_flags |= arg & (O_APPEND | O_NONBLOCK);
76: return 0;
1.1.1.8 ! root 77: case F_GETLK:
! 78: return fcntl_getlk(fd, (struct flock *) arg);
! 79: case F_SETLK:
! 80: return fcntl_setlk(fd, cmd, (struct flock *) arg);
! 81: case F_SETLKW:
! 82: return fcntl_setlk(fd, cmd, (struct flock *) arg);
1.1 root 83: default:
1.1.1.8 ! root 84: /* sockets need a few special fcntls. */
! 85: if (S_ISSOCK (filp->f_inode->i_mode))
! 86: {
! 87: return (sock_fcntl (filp, cmd, arg));
! 88: }
1.1.1.3 root 89: return -EINVAL;
1.1 root 90: }
91: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.