This source file includes following definitions.
- sys_lseek
- sys_llseek
- sys_read
- sys_write
1
2
3
4
5
6
7 #include <linux/types.h>
8 #include <linux/errno.h>
9 #include <linux/stat.h>
10 #include <linux/kernel.h>
11 #include <linux/sched.h>
12 #include <linux/mm.h>
13
14 #include <asm/segment.h>
15
16 asmlinkage int sys_lseek(unsigned int fd, off_t offset, unsigned int origin)
17 {
18 struct file * file;
19 int tmp = -1;
20
21 if (fd >= NR_OPEN || !(file=current->files->fd[fd]) || !(file->f_inode))
22 return -EBADF;
23 if (origin > 2)
24 return -EINVAL;
25 if (file->f_op && file->f_op->lseek)
26 return file->f_op->lseek(file->f_inode,file,offset,origin);
27
28
29 switch (origin) {
30 case 0:
31 tmp = offset;
32 break;
33 case 1:
34 tmp = file->f_pos + offset;
35 break;
36 case 2:
37 if (!file->f_inode)
38 return -EINVAL;
39 tmp = file->f_inode->i_size + offset;
40 break;
41 }
42 if (tmp < 0)
43 return -EINVAL;
44 if (tmp != file->f_pos) {
45 file->f_pos = tmp;
46 file->f_reada = 0;
47 file->f_version = ++event;
48 }
49 return file->f_pos;
50 }
51
52 asmlinkage int sys_llseek(unsigned int fd, unsigned long offset_high,
53 unsigned long offset_low, loff_t * result,
54 unsigned int origin)
55 {
56 struct file * file;
57 loff_t tmp = -1;
58 loff_t offset;
59 int err;
60
61 if (fd >= NR_OPEN || !(file=current->files->fd[fd]) || !(file->f_inode))
62 return -EBADF;
63 if (origin > 2)
64 return -EINVAL;
65 if ((err = verify_area(VERIFY_WRITE, result, sizeof(loff_t))))
66 return err;
67 offset = (loff_t) (((unsigned long long) offset_high << 32) | offset_low);
68
69
70
71 if (file->f_op && file->f_op->lseek) {
72 if (offset != (long) offset)
73 return -EINVAL;
74 return file->f_op->lseek(file->f_inode,file,offset,origin);
75 }
76
77 switch (origin) {
78 case 0:
79 tmp = offset;
80 break;
81 case 1:
82 tmp = file->f_pos + offset;
83 break;
84 case 2:
85 if (!file->f_inode)
86 return -EINVAL;
87 tmp = file->f_inode->i_size + offset;
88 break;
89 }
90 if (tmp < 0)
91 return -EINVAL;
92 if (tmp != file->f_pos) {
93 file->f_pos = tmp;
94 file->f_reada = 0;
95 file->f_version = ++event;
96 }
97 memcpy_tofs(result, &file->f_pos, sizeof(loff_t));
98 return 0;
99 }
100
101 asmlinkage int sys_read(unsigned int fd,char * buf,unsigned int count)
102 {
103 int error;
104 struct file * file;
105 struct inode * inode;
106
107 if (fd>=NR_OPEN || !(file=current->files->fd[fd]) || !(inode=file->f_inode))
108 return -EBADF;
109 if (!(file->f_mode & 1))
110 return -EBADF;
111 if (!file->f_op || !file->f_op->read)
112 return -EINVAL;
113 if (!count)
114 return 0;
115 error = verify_area(VERIFY_WRITE,buf,count);
116 if (error)
117 return error;
118 return file->f_op->read(inode,file,buf,count);
119 }
120
121 asmlinkage int sys_write(unsigned int fd,char * buf,unsigned int count)
122 {
123 int error;
124 struct file * file;
125 struct inode * inode;
126 int written;
127
128 if (fd>=NR_OPEN || !(file=current->files->fd[fd]) || !(inode=file->f_inode))
129 return -EBADF;
130 if (!(file->f_mode & 2))
131 return -EBADF;
132 if (!file->f_op || !file->f_op->write)
133 return -EINVAL;
134 if (!count)
135 return 0;
136 error = verify_area(VERIFY_READ,buf,count);
137 if (error)
138 return error;
139 written = file->f_op->write(inode,file,buf,count);
140
141
142
143
144 if (written > 0 && !suser() && (inode->i_mode & (S_ISUID | S_ISGID))) {
145 struct iattr newattrs;
146 newattrs.ia_mode = inode->i_mode & ~(S_ISUID | S_ISGID);
147 newattrs.ia_valid = ATTR_MODE;
148 notify_change(inode, &newattrs);
149 }
150 return written;
151 }