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