|
|
1.1.1.2 root 1: /*
2: * linux/fs/read_write.c
3: *
4: * (C) 1991 Linus Torvalds
5: */
6:
1.1 root 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:
1.1.1.2 root 15: extern int rw_char(int rw,int dev, char * buf, int count, off_t * pos);
1.1 root 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)
1.1.1.2 root 31: || !IS_SEEKABLE(MAJOR(file->f_inode->i_dev)))
1.1 root 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)
1.1.1.3 ! root 67: return (file->f_mode&1)?read_pipe(inode,buf,count):-EIO;
1.1 root 68: if (S_ISCHR(inode->i_mode))
1.1.1.2 root 69: return rw_char(READ,inode->i_zone[0],buf,count,&file->f_pos);
1.1 root 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)
1.1.1.3 ! root 94: return (file->f_mode&2)?write_pipe(inode,buf,count):-EIO;
1.1 root 95: if (S_ISCHR(inode->i_mode))
1.1.1.2 root 96: return rw_char(WRITE,inode->i_zone[0],buf,count,&file->f_pos);
1.1 root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.