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 *, void *, filldir_t);
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 NULL
30 };
31
32
33
34
35 struct inode_operations proc_base_inode_operations = {
36 &proc_base_operations,
37 NULL,
38 proc_lookupbase,
39 NULL,
40 NULL,
41 NULL,
42 NULL,
43 NULL,
44 NULL,
45 NULL,
46 NULL,
47 NULL,
48 NULL,
49 NULL,
50 NULL
51 };
52
53 static struct proc_dir_entry base_dir[] = {
54 { PROC_PID_INO, 1, "." },
55 { PROC_ROOT_INO, 2, ".." },
56 { PROC_PID_MEM, 3, "mem" },
57 { PROC_PID_CWD, 3, "cwd" },
58 { PROC_PID_ROOT, 4, "root" },
59 { PROC_PID_EXE, 3, "exe" },
60 { PROC_PID_FD, 2, "fd" },
61 { PROC_PID_ENVIRON, 7, "environ" },
62 { PROC_PID_CMDLINE, 7, "cmdline" },
63 { PROC_PID_STAT, 4, "stat" },
64 { PROC_PID_STATM, 5, "statm" },
65 { PROC_PID_MAPS, 4, "maps" }
66 };
67
68 #define NR_BASE_DIRENTRY ((sizeof (base_dir))/(sizeof (base_dir[0])))
69
70 int proc_match(int len,const char * name,struct proc_dir_entry * de)
71 {
72 if (!de || !de->low_ino)
73 return 0;
74
75 if (!len && (de->name[0]=='.') && (de->name[1]=='\0'))
76 return 1;
77 if (de->namelen != len)
78 return 0;
79 return !memcmp(name, de->name, len);
80 }
81
82 static int proc_lookupbase(struct inode * dir,const char * name, int len,
83 struct inode ** result)
84 {
85 struct proc_dir_entry * de = NULL;
86 unsigned int pid, ino;
87 int i;
88
89 *result = NULL;
90 if (!dir)
91 return -ENOENT;
92 if (!S_ISDIR(dir->i_mode)) {
93 iput(dir);
94 return -ENOENT;
95 }
96 ino = dir->i_ino;
97 pid = ino >> 16;
98 for (i = 0; i < NR_BASE_DIRENTRY; i++) {
99 if (!proc_match(len, name, base_dir+i))
100 continue;
101 de = base_dir+i;
102 break;
103 }
104 if (!de) {
105 iput(dir);
106 return -ENOENT;
107 }
108 if (de->low_ino == 1)
109 ino = 1;
110 else
111 ino = (pid << 16) + de->low_ino;
112 for (i = 0 ; i < NR_TASKS ; i++)
113 if (task[i] && task[i]->pid == pid)
114 break;
115 if (!pid || i >= NR_TASKS) {
116 iput(dir);
117 return -ENOENT;
118 }
119 if (!(*result = iget(dir->i_sb,ino))) {
120 iput(dir);
121 return -ENOENT;
122 }
123 iput(dir);
124 (*result)->u.generic_ip = de;
125 return 0;
126 }
127
128 static int proc_readbase(struct inode * inode, struct file * filp,
129 void * dirent, filldir_t filldir)
130 {
131 struct proc_dir_entry * de;
132 unsigned int pid, ino;
133 int i;
134
135 if (!inode || !S_ISDIR(inode->i_mode))
136 return -EBADF;
137 ino = inode->i_ino;
138 pid = ino >> 16;
139 for (i = 0 ; i < NR_TASKS ; i++)
140 if (task[i] && task[i]->pid == pid)
141 break;
142 if (!pid || i >= NR_TASKS)
143 return 0;
144 while (((unsigned) filp->f_pos) < NR_BASE_DIRENTRY) {
145 de = base_dir + filp->f_pos;
146 ino = de->low_ino;
147 if (ino != 1)
148 ino |= (pid << 16);
149 if (filldir(dirent, de->name, de->namelen, filp->f_pos, ino) < 0)
150 break;
151 filp->f_pos++;
152 }
153 return 0;
154 }