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