diff options
Diffstat (limited to 'src/fs/read_write.c')
-rw-r--r-- | src/fs/read_write.c | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/src/fs/read_write.c b/src/fs/read_write.c new file mode 100644 index 0000000..341274a --- /dev/null +++ b/src/fs/read_write.c | |||
@@ -0,0 +1,103 @@ | |||
1 | /* | ||
2 | * linux/fs/read_write.c | ||
3 | * | ||
4 | * (C) 1991 Linus Torvalds | ||
5 | */ | ||
6 | |||
7 | #include <sys/stat.h> | ||
8 | #include <errno.h> | ||
9 | #include <sys/types.h> | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/sched.h> | ||
13 | #include <asm/segment.h> | ||
14 | |||
15 | extern int rw_char(int rw,int dev, char * buf, int count, off_t * pos); | ||
16 | extern int read_pipe(struct m_inode * inode, char * buf, int count); | ||
17 | extern int write_pipe(struct m_inode * inode, char * buf, int count); | ||
18 | extern int block_read(int dev, off_t * pos, char * buf, int count); | ||
19 | extern int block_write(int dev, off_t * pos, char * buf, int count); | ||
20 | extern int file_read(struct m_inode * inode, struct file * filp, | ||
21 | char * buf, int count); | ||
22 | extern int file_write(struct m_inode * inode, struct file * filp, | ||
23 | char * buf, int count); | ||
24 | |||
25 | int sys_lseek(unsigned int fd,off_t offset, int origin) | ||
26 | { | ||
27 | struct file * file; | ||
28 | int tmp; | ||
29 | |||
30 | if (fd >= NR_OPEN || !(file=current->filp[fd]) || !(file->f_inode) | ||
31 | || !IS_SEEKABLE(MAJOR(file->f_inode->i_dev))) | ||
32 | return -EBADF; | ||
33 | if (file->f_inode->i_pipe) | ||
34 | return -ESPIPE; | ||
35 | switch (origin) { | ||
36 | case 0: | ||
37 | if (offset<0) return -EINVAL; | ||
38 | file->f_pos=offset; | ||
39 | break; | ||
40 | case 1: | ||
41 | if (file->f_pos+offset<0) return -EINVAL; | ||
42 | file->f_pos += offset; | ||
43 | break; | ||
44 | case 2: | ||
45 | if ((tmp=file->f_inode->i_size+offset) < 0) | ||
46 | return -EINVAL; | ||
47 | file->f_pos = tmp; | ||
48 | break; | ||
49 | default: | ||
50 | return -EINVAL; | ||
51 | } | ||
52 | return file->f_pos; | ||
53 | } | ||
54 | |||
55 | int sys_read(unsigned int fd,char * buf,int count) | ||
56 | { | ||
57 | struct file * file; | ||
58 | struct m_inode * inode; | ||
59 | |||
60 | if (fd>=NR_OPEN || count<0 || !(file=current->filp[fd])) | ||
61 | return -EINVAL; | ||
62 | if (!count) | ||
63 | return 0; | ||
64 | verify_area(buf,count); | ||
65 | inode = file->f_inode; | ||
66 | if (inode->i_pipe) | ||
67 | return (file->f_mode&1)?read_pipe(inode,buf,count):-EIO; | ||
68 | if (S_ISCHR(inode->i_mode)) | ||
69 | return rw_char(READ,inode->i_zone[0],buf,count,&file->f_pos); | ||
70 | if (S_ISBLK(inode->i_mode)) | ||
71 | return block_read(inode->i_zone[0],&file->f_pos,buf,count); | ||
72 | if (S_ISDIR(inode->i_mode) || S_ISREG(inode->i_mode)) { | ||
73 | if (count+file->f_pos > inode->i_size) | ||
74 | count = inode->i_size - file->f_pos; | ||
75 | if (count<=0) | ||
76 | return 0; | ||
77 | return file_read(inode,file,buf,count); | ||
78 | } | ||
79 | printk("(Read)inode->i_mode=%06o\n\r",inode->i_mode); | ||
80 | return -EINVAL; | ||
81 | } | ||
82 | |||
83 | int sys_write(unsigned int fd,char * buf,int count) | ||
84 | { | ||
85 | struct file * file; | ||
86 | struct m_inode * inode; | ||
87 | |||
88 | if (fd>=NR_OPEN || count <0 || !(file=current->filp[fd])) | ||
89 | return -EINVAL; | ||
90 | if (!count) | ||
91 | return 0; | ||
92 | inode=file->f_inode; | ||
93 | if (inode->i_pipe) | ||
94 | return (file->f_mode&2)?write_pipe(inode,buf,count):-EIO; | ||
95 | if (S_ISCHR(inode->i_mode)) | ||
96 | return rw_char(WRITE,inode->i_zone[0],buf,count,&file->f_pos); | ||
97 | if (S_ISBLK(inode->i_mode)) | ||
98 | return block_write(inode->i_zone[0],&file->f_pos,buf,count); | ||
99 | if (S_ISREG(inode->i_mode)) | ||
100 | return file_write(inode,file,buf,count); | ||
101 | printk("(Write)inode->i_mode=%06o\n\r",inode->i_mode); | ||
102 | return -EINVAL; | ||
103 | } | ||