|
|
1.1 root 1: #include <sys/stat.h>
2: #include <errno.h>
3: #include <sys/types.h>
4:
5: #include <linux/kernel.h>
6: #include <linux/sched.h>
7: #include <asm/segment.h>
8:
9: extern int rw_char(int rw,int dev, char * buf, int count);
10: extern int read_pipe(struct m_inode * inode, char * buf, int count);
11: extern int write_pipe(struct m_inode * inode, char * buf, int count);
12: extern int block_read(int dev, off_t * pos, char * buf, int count);
13: extern int block_write(int dev, off_t * pos, char * buf, int count);
14: extern int file_read(struct m_inode * inode, struct file * filp,
15: char * buf, int count);
16: extern int file_write(struct m_inode * inode, struct file * filp,
17: char * buf, int count);
18:
19: int sys_lseek(unsigned int fd,off_t offset, int origin)
20: {
21: struct file * file;
22: int tmp;
23:
24: if (fd >= NR_OPEN || !(file=current->filp[fd]) || !(file->f_inode)
25: || !IS_BLOCKDEV(MAJOR(file->f_inode->i_dev)))
26: return -EBADF;
27: if (file->f_inode->i_pipe)
28: return -ESPIPE;
29: switch (origin) {
30: case 0:
31: if (offset<0) return -EINVAL;
32: file->f_pos=offset;
33: break;
34: case 1:
35: if (file->f_pos+offset<0) return -EINVAL;
36: file->f_pos += offset;
37: break;
38: case 2:
39: if ((tmp=file->f_inode->i_size+offset) < 0)
40: return -EINVAL;
41: file->f_pos = tmp;
42: break;
43: default:
44: return -EINVAL;
45: }
46: return file->f_pos;
47: }
48:
49: int sys_read(unsigned int fd,char * buf,int count)
50: {
51: struct file * file;
52: struct m_inode * inode;
53:
54: if (fd>=NR_OPEN || count<0 || !(file=current->filp[fd]))
55: return -EINVAL;
56: if (!count)
57: return 0;
58: verify_area(buf,count);
59: inode = file->f_inode;
60: if (inode->i_pipe)
61: return (file->f_mode&1)?read_pipe(inode,buf,count):-1;
62: if (S_ISCHR(inode->i_mode))
63: return rw_char(READ,inode->i_zone[0],buf,count);
64: if (S_ISBLK(inode->i_mode))
65: return block_read(inode->i_zone[0],&file->f_pos,buf,count);
66: if (S_ISDIR(inode->i_mode) || S_ISREG(inode->i_mode)) {
67: if (count+file->f_pos > inode->i_size)
68: count = inode->i_size - file->f_pos;
69: if (count<=0)
70: return 0;
71: return file_read(inode,file,buf,count);
72: }
73: printk("(Read)inode->i_mode=%06o\n\r",inode->i_mode);
74: return -EINVAL;
75: }
76:
77: int sys_write(unsigned int fd,char * buf,int count)
78: {
79: struct file * file;
80: struct m_inode * inode;
81:
82: if (fd>=NR_OPEN || count <0 || !(file=current->filp[fd]))
83: return -EINVAL;
84: if (!count)
85: return 0;
86: inode=file->f_inode;
87: if (inode->i_pipe)
88: return (file->f_mode&2)?write_pipe(inode,buf,count):-1;
89: if (S_ISCHR(inode->i_mode))
90: return rw_char(WRITE,inode->i_zone[0],buf,count);
91: if (S_ISBLK(inode->i_mode))
92: return block_write(inode->i_zone[0],&file->f_pos,buf,count);
93: if (S_ISREG(inode->i_mode))
94: return file_write(inode,file,buf,count);
95: printk("(Write)inode->i_mode=%06o\n\r",inode->i_mode);
96: return -EINVAL;
97: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.