This source file includes following definitions.
- proc_lookupfd
- proc_readfd
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_readfd(struct inode *, struct file *, struct dirent *, int);
17 static int proc_lookupfd(struct inode *,const char *,int,struct inode **);
18
19 static struct file_operations proc_fd_operations = {
20 NULL,
21 NULL,
22 NULL,
23 proc_readfd,
24 NULL,
25 NULL,
26 NULL,
27 NULL,
28 NULL,
29 NULL
30 };
31
32
33
34
35 struct inode_operations proc_fd_inode_operations = {
36 &proc_fd_operations,
37 NULL,
38 proc_lookupfd,
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 int proc_lookupfd(struct inode * dir,const char * name, int len,
54 struct inode ** result)
55 {
56 unsigned int ino, pid, fd, c;
57 struct task_struct * p;
58 struct super_block * sb;
59 int i;
60
61 *result = NULL;
62 ino = dir->i_ino;
63 pid = ino >> 16;
64 ino &= 0x0000ffff;
65 if (!dir)
66 return -ENOENT;
67 sb = dir->i_sb;
68 if (!pid || ino != PROC_PID_FD || !S_ISDIR(dir->i_mode)) {
69 iput(dir);
70 return -ENOENT;
71 }
72 if (!len || (name[0] == '.' && (len == 1 ||
73 (name[1] == '.' && len == 2)))) {
74 if (len < 2) {
75 *result = dir;
76 return 0;
77 }
78 if (!(*result = iget(sb,(pid << 16)+PROC_PID_INO))) {
79 iput(dir);
80 return -ENOENT;
81 }
82 iput(dir);
83 return 0;
84 }
85 iput(dir);
86 fd = 0;
87 while (len-- > 0) {
88 c = *name - '0';
89 name++;
90 if (c > 9) {
91 fd = 0xfffff;
92 break;
93 }
94 fd *= 10;
95 fd += c;
96 if (fd & 0xffff0000) {
97 fd = 0xfffff;
98 break;
99 }
100 }
101 for (i = 0 ; i < NR_TASKS ; i++)
102 if ((p = task[i]) && p->pid == pid)
103 break;
104 if (!pid || i >= NR_TASKS)
105 return -ENOENT;
106
107 if (fd >= NR_OPEN || !p->files->fd[fd] || !p->files->fd[fd]->f_inode)
108 return -ENOENT;
109
110 ino = (pid << 16) + (PROC_PID_FD_DIR << 8) + fd;
111
112 if (!(*result = iget(sb,ino)))
113 return -ENOENT;
114 return 0;
115 }
116
117 static int proc_readfd(struct inode * inode, struct file * filp,
118 struct dirent * dirent, int count)
119 {
120 struct task_struct * p;
121 unsigned int fd, pid, ino;
122 int i,j;
123
124 if (!inode || !S_ISDIR(inode->i_mode))
125 return -EBADF;
126 ino = inode->i_ino;
127 pid = ino >> 16;
128 ino &= 0x0000ffff;
129 if (ino != PROC_PID_FD)
130 return 0;
131 while (1) {
132 fd = filp->f_pos;
133 filp->f_pos++;
134 if (fd < 2) {
135 i = j = fd+1;
136 if (!fd)
137 fd = inode->i_ino;
138 else
139 fd = (inode->i_ino & 0xffff0000) | PROC_PID_INO;
140 put_fs_long(fd, &dirent->d_ino);
141 put_fs_word(i, &dirent->d_reclen);
142 put_fs_byte(0, i+dirent->d_name);
143 while (i--)
144 put_fs_byte('.', i+dirent->d_name);
145 return j;
146 }
147 fd -= 2;
148 for (i = 1 ; i < NR_TASKS ; i++)
149 if ((p = task[i]) && p->pid == pid)
150 break;
151 if (i >= NR_TASKS)
152 return 0;
153 if (fd >= NR_OPEN)
154 break;
155
156 if (!p->files->fd[fd] || !p->files->fd[fd]->f_inode)
157 continue;
158
159 j = 10;
160 i = 1;
161 while (fd >= j) {
162 j *= 10;
163 i++;
164 }
165 j = i;
166 ino = (pid << 16) + (PROC_PID_FD_DIR << 8) + fd;
167
168 put_fs_long(ino, &dirent->d_ino);
169 put_fs_word(i, &dirent->d_reclen);
170 put_fs_byte(0, i+dirent->d_name);
171 while (i--) {
172 put_fs_byte('0'+(fd % 10), i+dirent->d_name);
173 fd /= 10;
174 }
175 return j;
176 }
177 return 0;
178 }