summaryrefslogtreecommitdiffstats
path: root/src/fs/read_write.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fs/read_write.c')
-rw-r--r--src/fs/read_write.c103
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
15extern int rw_char(int rw,int dev, char * buf, int count, off_t * pos);
16extern int read_pipe(struct m_inode * inode, char * buf, int count);
17extern int write_pipe(struct m_inode * inode, char * buf, int count);
18extern int block_read(int dev, off_t * pos, char * buf, int count);
19extern int block_write(int dev, off_t * pos, char * buf, int count);
20extern int file_read(struct m_inode * inode, struct file * filp,
21 char * buf, int count);
22extern int file_write(struct m_inode * inode, struct file * filp,
23 char * buf, int count);
24
25int 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
55int 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
83int 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}