This source file includes following definitions.
- proc_match
- proc_lookupbase
- proc_readbase
1
2
3
4
5
6
7
8
9 #include <asm/segment.h>
10
11 #include <linux/errno.h>
12 #include <linux/sched.h>
13 #include <linux/proc_fs.h>
14 #include <linux/stat.h>
15
16 static int proc_readbase(struct inode *, struct file *, struct dirent *, int);
17 static int proc_lookupbase(struct inode *,const char *,int,struct inode **);
18
19 static struct file_operations proc_base_operations = {
20 NULL,
21 NULL,
22 NULL,
23 proc_readbase,
24 NULL,
25 NULL,
26 NULL,
27 NULL,
28 NULL
29 };
30
31
32
33
34 struct inode_operations proc_base_inode_operations = {
35 &proc_base_operations,
36 NULL,
37 proc_lookupbase,
38 NULL,
39 NULL,
40 NULL,
41 NULL,
42 NULL,
43 NULL,
44 NULL,
45 NULL,
46 NULL,
47 NULL,
48 NULL,
49 NULL
50 };
51
52 static struct proc_dir_entry base_dir[] = {
53 { 1,2,".." },
54 { 2,1,"." },
55 { 3,3,"mem" },
56 { 4,3,"cwd" },
57 { 5,4,"root" },
58 { 6,3,"exe" },
59 { 7,2,"fd" },
60 { 8,3,"lib" },
61 { 9,7,"environ" },
62 { 10,7,"cmdline" },
63 { 11,4,"stat" },
64 { 12,5,"statm" }
65 };
66
67 #define NR_BASE_DIRENTRY ((sizeof (base_dir))/(sizeof (base_dir[0])))
68
69 int proc_match(int len,const char * name,struct proc_dir_entry * de)
70 {
71 register int same __asm__("ax");
72
73 if (!de || !de->low_ino)
74 return 0;
75
76 if (!len && (de->name[0]=='.') && (de->name[1]=='\0'))
77 return 1;
78 if (de->namelen != len)
79 return 0;
80 __asm__("cld\n\t"
81 "fs ; repe ; cmpsb\n\t"
82 "setz %%al"
83 :"=a" (same)
84 :"0" (0),"S" ((long) name),"D" ((long) de->name),"c" (len)
85 :"cx","di","si");
86 return same;
87 }
88
89 static int proc_lookupbase(struct inode * dir,const char * name, int len,
90 struct inode ** result)
91 {
92 unsigned int pid;
93 int i, ino;
94
95 *result = NULL;
96 if (!dir)
97 return -ENOENT;
98 if (!S_ISDIR(dir->i_mode)) {
99 iput(dir);
100 return -ENOENT;
101 }
102 ino = dir->i_ino;
103 pid = ino >> 16;
104 i = NR_BASE_DIRENTRY;
105 while (i-- > 0 && !proc_match(len,name,base_dir+i))
106 ;
107 if (i < 0) {
108 iput(dir);
109 return -ENOENT;
110 }
111 if (base_dir[i].low_ino == 1)
112 ino = 1;
113 else
114 ino = (pid << 16) + base_dir[i].low_ino;
115 for (i = 0 ; i < NR_TASKS ; i++)
116 if (task[i] && task[i]->pid == pid)
117 break;
118 if (!pid || i >= NR_TASKS) {
119 iput(dir);
120 return -ENOENT;
121 }
122 if (!(*result = iget(dir->i_sb,ino))) {
123 iput(dir);
124 return -ENOENT;
125 }
126 iput(dir);
127 return 0;
128 }
129
130 static int proc_readbase(struct inode * inode, struct file * filp,
131 struct dirent * dirent, int count)
132 {
133 struct proc_dir_entry * de;
134 unsigned int pid, ino;
135 int i,j;
136
137 if (!inode || !S_ISDIR(inode->i_mode))
138 return -EBADF;
139 ino = inode->i_ino;
140 pid = ino >> 16;
141 for (i = 0 ; i < NR_TASKS ; i++)
142 if (task[i] && task[i]->pid == pid)
143 break;
144 if (!pid || i >= NR_TASKS)
145 return 0;
146 if (((unsigned) filp->f_pos) < NR_BASE_DIRENTRY) {
147 de = base_dir + filp->f_pos;
148 filp->f_pos++;
149 i = de->namelen;
150 ino = de->low_ino;
151 if (ino != 1)
152 ino |= (pid << 16);
153 put_fs_long(ino, &dirent->d_ino);
154 put_fs_word(i,&dirent->d_reclen);
155 put_fs_byte(0,i+dirent->d_name);
156 j = i;
157 while (i--)
158 put_fs_byte(de->name[i], i+dirent->d_name);
159 return j;
160 }
161 return 0;
162 }