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 NULL,
52 NULL
53 };
54
55 static int proc_lookupfd(struct inode * dir, const char * name, int len,
56 struct inode ** result)
57 {
58 unsigned int ino, pid, fd, c;
59 struct task_struct * p;
60 struct super_block * sb;
61 int i;
62
63 *result = NULL;
64 ino = dir->i_ino;
65 pid = ino >> 16;
66 ino &= 0x0000ffff;
67 if (!dir)
68 return -ENOENT;
69 sb = dir->i_sb;
70 if (!pid || ino != PROC_PID_FD || !S_ISDIR(dir->i_mode)) {
71 iput(dir);
72 return -ENOENT;
73 }
74 if (!len || (name[0] == '.' && (len == 1 ||
75 (name[1] == '.' && len == 2)))) {
76 if (len < 2) {
77 *result = dir;
78 return 0;
79 }
80 if (!(*result = proc_get_inode(sb, (pid << 16)+PROC_PID_INO, &proc_pid))) {
81 iput(dir);
82 return -ENOENT;
83 }
84 iput(dir);
85 return 0;
86 }
87 iput(dir);
88 fd = 0;
89 while (len-- > 0) {
90 c = *name - '0';
91 name++;
92 if (c > 9) {
93 fd = 0xfffff;
94 break;
95 }
96 fd *= 10;
97 fd += c;
98 if (fd & 0xffff0000) {
99 fd = 0xfffff;
100 break;
101 }
102 }
103 for (i = 0 ; i < NR_TASKS ; i++)
104 if ((p = task[i]) && p->pid == pid)
105 break;
106 if (!pid || i >= NR_TASKS)
107 return -ENOENT;
108
109 if (fd >= NR_OPEN || !p->files->fd[fd] || !p->files->fd[fd]->f_inode)
110 return -ENOENT;
111
112 ino = (pid << 16) + (PROC_PID_FD_DIR << 8) + fd;
113
114 if (!(*result = proc_get_inode(sb, ino, NULL)))
115 return -ENOENT;
116 return 0;
117 }
118
119 #define NUMBUF 10
120
121 static int proc_readfd(struct inode * inode, struct file * filp,
122 void * dirent, filldir_t filldir)
123 {
124 char buf[NUMBUF];
125 int task_nr;
126 struct task_struct * p;
127 unsigned int fd, pid, ino;
128 unsigned long i,j;
129
130 if (!inode || !S_ISDIR(inode->i_mode))
131 return -EBADF;
132 ino = inode->i_ino;
133 pid = ino >> 16;
134 ino &= 0x0000ffff;
135 if (ino != PROC_PID_FD)
136 return 0;
137
138 for (fd = filp->f_pos; fd < 2; fd++, filp->f_pos++) {
139 unsigned long ino = inode->i_ino;
140 if (fd)
141 ino = (ino & 0xffff0000) | PROC_PID_INO;
142 if (filldir(dirent, "..", fd+1, fd, ino) < 0)
143 return 0;
144 }
145
146 task_nr = 1;
147 for (;;) {
148 if ((p = task[task_nr]) && p->pid == pid)
149 break;
150 if (++task_nr >= NR_TASKS)
151 return 0;
152 }
153
154 for (fd -= 2 ; fd < NR_OPEN; fd++, filp->f_pos++) {
155 if (!p->files)
156 break;
157 if (!p->files->fd[fd] || !p->files->fd[fd]->f_inode)
158 continue;
159
160 j = NUMBUF;
161 i = fd;
162 do {
163 j--;
164 buf[j] = '0' + (i % 10);
165 i /= 10;
166 } while (i);
167
168 ino = (pid << 16) + (PROC_PID_FD_DIR << 8) + fd;
169 if (filldir(dirent, buf+j, NUMBUF-j, fd+2, ino) < 0)
170 break;
171
172
173 if (p != task[task_nr] || p->pid != pid)
174 break;
175 }
176 return 0;
177 }