4 * Copyright (C) 1991, 1992 Linus Torvalds
6 * proc fd directory handling functions
8 * 01-May-98 Edgar Toernig <froese@gmx.de>
9 * Added support for more than 256 fds.
10 * Limit raised to 32768.
13 #include <linux/errno.h>
14 #include <linux/sched.h>
15 #include <linux/file.h>
16 #include <linux/proc_fs.h>
17 #include <linux/stat.h>
19 #include <asm/uaccess.h>
21 static int proc_readfd(struct file
*, void *, filldir_t
);
22 static struct dentry
*proc_lookupfd(struct inode
*, struct dentry
*);
24 static struct file_operations proc_fd_operations
= {
25 NULL
, /* lseek - default */
26 NULL
, /* read - bad */
27 NULL
, /* write - bad */
28 proc_readfd
, /* readdir */
29 NULL
, /* poll - default */
30 NULL
, /* ioctl - default */
32 NULL
, /* no special open code */
34 NULL
, /* no special release code */
35 NULL
/* can't fsync */
39 * proc directories can do almost nothing..
41 struct inode_operations proc_fd_inode_operations
= {
42 &proc_fd_operations
, /* default base directory file-ops */
44 proc_lookupfd
, /* lookup */
53 NULL
, /* follow_link */
59 proc_permission
, /* permission */
65 * NOTE! Normally we'd indicate that a file does not
66 * exist by creating a negative dentry and returning
67 * a successful return code. However, for this case
68 * we do not want to create negative dentries, because
69 * the state of the world can change behind our backs.
71 * Thus just return -ENOENT instead.
73 static struct dentry
*proc_lookupfd(struct inode
* dir
, struct dentry
* dentry
)
75 unsigned int ino
, pid
, fd
, c
;
76 struct task_struct
* p
;
87 if (!pid
|| ino
!= PROC_PID_FD
)
91 len
= dentry
->d_name
.len
;
92 name
= dentry
->d_name
.name
;
104 read_lock(&tasklist_lock
);
106 p
= find_task_by_pid(pid
);
108 file
= fcheck_task(p
, fd
);
109 read_unlock(&tasklist_lock
);
112 * File handle is invalid if it is out of range, if the process
113 * has no files (Zombie) if the file is closed, or if its inode
117 if (!file
|| !file
->f_dentry
)
120 ino
= (pid
<< 16) + PROC_PID_FD_DIR
+ fd
;
121 inode
= proc_get_inode(dir
->i_sb
, ino
, NULL
);
123 dentry
->d_op
= &proc_dentry_operations
;
124 d_add(dentry
, inode
);
133 static int proc_readfd(struct file
* filp
, void * dirent
, filldir_t filldir
)
135 struct inode
*inode
= filp
->f_dentry
->d_inode
;
136 struct task_struct
* p
, **tarrayp
;
137 unsigned int fd
, pid
, ino
;
145 if (ino
!= PROC_PID_FD
)
148 for (fd
= filp
->f_pos
; fd
< 2; fd
++, filp
->f_pos
++) {
151 ino
= (ino
& 0xffff0000) | PROC_PID_INO
;
152 if (filldir(dirent
, "..", fd
+1, fd
, ino
) < 0)
156 read_lock(&tasklist_lock
);
157 p
= find_task_by_pid(pid
);
160 tarrayp
= p
->tarray_ptr
;
162 for (fd
-= 2 ; p
->files
&& fd
< p
->files
->max_fds
; fd
++, filp
->f_pos
++)
164 struct file
* file
= fcheck_task(p
, fd
);
167 if (!file
|| !file
->f_dentry
)
174 buf
[j
] = '0' + (i
% 10);
178 /* Drop the task lock, as the filldir function may block */
179 read_unlock(&tasklist_lock
);
181 ino
= (pid
<< 16) + PROC_PID_FD_DIR
+ fd
;
182 if (filldir(dirent
, buf
+j
, NUMBUF
-j
, fd
+2, ino
) < 0)
185 read_lock(&tasklist_lock
);
186 /* filldir() might have slept, so we must re-validate "p" */
187 if (p
!= *tarrayp
|| p
->pid
!= pid
)
191 read_unlock(&tasklist_lock
);