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 *, void *, filldir_t);
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 = proc_get_inode(sb, (pid << 16)+PROC_PID_INO, &proc_pid))) {
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 = proc_get_inode(sb, ino, NULL)))
113 return -ENOENT;
114 return 0;
115 }
116
117 #define NUMBUF 10
118
119 static int proc_readfd(struct inode * inode, struct file * filp,
120 void * dirent, filldir_t filldir)
121 {
122 char buf[NUMBUF];
123 int task_nr;
124 struct task_struct * p;
125 unsigned int fd, pid, ino;
126 unsigned long i,j;
127
128 if (!inode || !S_ISDIR(inode->i_mode))
129 return -EBADF;
130 ino = inode->i_ino;
131 pid = ino >> 16;
132 ino &= 0x0000ffff;
133 if (ino != PROC_PID_FD)
134 return 0;
135
136 for (fd = filp->f_pos; fd < 2; fd++, filp->f_pos++) {
137 unsigned long ino = inode->i_ino;
138 if (fd)
139 ino = (ino & 0xffff0000) | PROC_PID_INO;
140 if (filldir(dirent, "..", fd+1, fd, ino) < 0)
141 return 0;
142 }
143
144 task_nr = 1;
145 for (;;) {
146 if ((p = task[task_nr]) && p->pid == pid)
147 break;
148 if (++task_nr >= NR_TASKS)
149 return 0;
150 }
151
152 for (fd -= 2 ; fd < NR_OPEN; fd++, filp->f_pos++) {
153 if (!p->files)
154 break;
155 if (!p->files->fd[fd] || !p->files->fd[fd]->f_inode)
156 continue;
157
158 j = NUMBUF;
159 i = fd;
160 do {
161 j--;
162 buf[j] = '0' + (i % 10);
163 i /= 10;
164 } while (i);
165
166 ino = (pid << 16) + (PROC_PID_FD_DIR << 8) + fd;
167 if (filldir(dirent, buf+j, NUMBUF-j, fd+2, ino) < 0)
168 break;
169
170
171 if (p != task[task_nr] || p->pid != pid)
172 break;
173 }
174 return 0;
175 }