* added 0.99 linux version
[mascara-docs.git] / i386 / linux / linux-0.99 / fs / proc / mem.c
blob28fd4be8cbf9aa00ff058fdc689ac77570b265a6
1 /*
2 * linux/fs/proc/mem.c
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 */
7 #include <linux/types.h>
8 #include <linux/errno.h>
9 #include <linux/sched.h>
10 #include <linux/kernel.h>
12 #include <asm/segment.h>
13 #include <asm/io.h>
16 * mem_write isn't really a good idea right now. It needs
17 * to check a lot more: if the process we try to write to
18 * dies in the middle right now, mem_write will overwrite
19 * kernel memory.. This disables it altogether.
21 #define mem_write NULL
23 static int mem_read(struct inode * inode, struct file * file,char * buf, int count)
25 unsigned long addr, pid, cr3;
26 char *tmp;
27 unsigned long pte, page;
28 int i;
30 if (count < 0)
31 return -EINVAL;
32 pid = inode->i_ino;
33 pid >>= 16;
34 cr3 = 0;
35 for (i = 1 ; i < NR_TASKS ; i++)
36 if (task[i] && task[i]->pid == pid) {
37 cr3 = task[i]->tss.cr3;
38 break;
40 if (!cr3)
41 return -EACCES;
42 addr = file->f_pos;
43 tmp = buf;
44 while (count > 0) {
45 if (current->signal & ~current->blocked)
46 break;
47 pte = *PAGE_DIR_OFFSET(cr3,addr);
48 if (!(pte & PAGE_PRESENT))
49 break;
50 pte &= PAGE_MASK;
51 pte += PAGE_PTR(addr);
52 page = *(unsigned long *) pte;
53 if (!(page & 1))
54 break;
55 page &= PAGE_MASK;
56 page += addr & ~PAGE_MASK;
57 i = PAGE_SIZE-(addr & ~PAGE_MASK);
58 if (i > count)
59 i = count;
60 memcpy_tofs(tmp,(void *) page,i);
61 addr += i;
62 tmp += i;
63 count -= i;
65 file->f_pos = addr;
66 return tmp-buf;
69 #ifndef mem_write
71 static int mem_write(struct inode * inode, struct file * file,char * buf, int count)
73 unsigned long addr, pid, cr3;
74 char *tmp;
75 unsigned long pte, page;
76 int i;
78 if (count < 0)
79 return -EINVAL;
80 addr = file->f_pos;
81 pid = inode->i_ino;
82 pid >>= 16;
83 cr3 = 0;
84 for (i = 1 ; i < NR_TASKS ; i++)
85 if (task[i] && task[i]->pid == pid) {
86 cr3 = task[i]->tss.cr3;
87 break;
89 if (!cr3)
90 return -EACCES;
91 tmp = buf;
92 while (count > 0) {
93 if (current->signal & ~current->blocked)
94 break;
95 pte = *PAGE_DIR_OFFSET(cr3,addr);
96 if (!(pte & PAGE_PRESENT))
97 break;
98 pte &= PAGE_MASK;
99 pte += PAGE_PTR(addr);
100 page = *(unsigned long *) pte;
101 if (!(page & PAGE_PRESENT))
102 break;
103 if (!(page & 2)) {
104 do_wp_page(0,addr,current,0);
105 continue;
107 page &= PAGE_MASK;
108 page += addr & ~PAGE_MASK;
109 i = PAGE_SIZE-(addr & ~PAGE_MASK);
110 if (i > count)
111 i = count;
112 memcpy_fromfs((void *) page,tmp,i);
113 addr += i;
114 tmp += i;
115 count -= i;
117 file->f_pos = addr;
118 if (tmp != buf)
119 return tmp-buf;
120 if (current->signal & ~current->blocked)
121 return -ERESTARTSYS;
122 return 0;
125 #endif
127 static int mem_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
129 switch (orig) {
130 case 0:
131 file->f_pos = offset;
132 return file->f_pos;
133 case 1:
134 file->f_pos += offset;
135 return file->f_pos;
136 default:
137 return -EINVAL;
141 static struct file_operations proc_mem_operations = {
142 mem_lseek,
143 mem_read,
144 mem_write,
145 NULL, /* mem_readdir */
146 NULL, /* mem_select */
147 NULL, /* mem_ioctl */
148 NULL, /* mmap */
149 NULL, /* no special open code */
150 NULL, /* no special release code */
151 NULL /* can't fsync */
154 struct inode_operations proc_mem_inode_operations = {
155 &proc_mem_operations, /* default base directory file-ops */
156 NULL, /* create */
157 NULL, /* lookup */
158 NULL, /* link */
159 NULL, /* unlink */
160 NULL, /* symlink */
161 NULL, /* mkdir */
162 NULL, /* rmdir */
163 NULL, /* mknod */
164 NULL, /* rename */
165 NULL, /* readlink */
166 NULL, /* follow_link */
167 NULL, /* bmap */
168 NULL, /* truncate */
169 NULL /* permission */