4 * Copyright (C) 1991, 1992 Linus Torvalds
6 * proc fd directory handling functions
9 #include <asm/uaccess.h>
11 #include <linux/errno.h>
12 #include <linux/sched.h>
13 #include <linux/proc_fs.h>
14 #include <linux/stat.h>
16 static int proc_readfd(struct file
*, void *, filldir_t
);
17 static int proc_lookupfd(struct inode
*, struct dentry
*);
19 static struct file_operations proc_fd_operations
= {
20 NULL
, /* lseek - default */
21 NULL
, /* read - bad */
22 NULL
, /* write - bad */
23 proc_readfd
, /* readdir */
24 NULL
, /* poll - default */
25 NULL
, /* ioctl - default */
27 NULL
, /* no special open code */
28 NULL
, /* no special release code */
29 NULL
/* can't fsync */
33 * proc directories can do almost nothing..
35 struct inode_operations proc_fd_inode_operations
= {
36 &proc_fd_operations
, /* default base directory file-ops */
38 proc_lookupfd
, /* lookup */
47 NULL
, /* follow_link */
56 * NOTE! Normally we'd indicate that a file does not
57 * exist by creating a negative dentry and returning
58 * a successful return code. However, for this case
59 * we do not want to create negative dentries, because
60 * the state of the world can change behind our backs.
62 * Thus just return -ENOENT instead.
64 static int proc_lookupfd(struct inode
* dir
, struct dentry
* dentry
)
66 unsigned int ino
, pid
, fd
, c
;
67 struct task_struct
* p
;
68 struct super_block
* sb
;
79 if (!pid
|| ino
!= PROC_PID_FD
|| !S_ISDIR(dir
->i_mode
))
83 len
= dentry
->d_name
.len
;
84 name
= dentry
->d_name
.name
;
94 if (fd
& 0xffff0000) {
99 p
= find_task_by_pid(pid
);
104 * File handle is invalid if it is out of range, if the process
105 * has no files (Zombie) if the file is closed, or if its inode
112 !p
->files
->fd
[fd
]->f_dentry
)
115 ino
= (pid
<< 16) + (PROC_PID_FD_DIR
<< 8) + fd
;
117 inode
= proc_get_inode(sb
, ino
, NULL
);
121 d_add(dentry
, inode
);
127 static int proc_readfd(struct file
* filp
,
128 void * dirent
, filldir_t filldir
)
131 struct task_struct
* p
, **tarrayp
;
132 unsigned int fd
, pid
, ino
;
134 struct inode
*inode
= filp
->f_dentry
->d_inode
;
136 if (!inode
|| !S_ISDIR(inode
->i_mode
))
141 if (ino
!= PROC_PID_FD
)
144 for (fd
= filp
->f_pos
; fd
< 2; fd
++, filp
->f_pos
++) {
145 unsigned long ino
= inode
->i_ino
;
147 ino
= (ino
& 0xffff0000) | PROC_PID_INO
;
148 if (filldir(dirent
, "..", fd
+1, fd
, ino
) < 0)
152 p
= find_task_by_pid(pid
);
155 tarrayp
= p
->tarray_ptr
;
157 for (fd
-= 2 ; fd
< NR_OPEN
; fd
++, filp
->f_pos
++) {
160 if (!p
->files
->fd
[fd
] || !p
->files
->fd
[fd
]->f_dentry
)
167 buf
[j
] = '0' + (i
% 10);
171 ino
= (pid
<< 16) + (PROC_PID_FD_DIR
<< 8) + fd
;
172 if (filldir(dirent
, buf
+j
, NUMBUF
-j
, fd
+2, ino
) < 0)
175 /* filldir() might have slept, so we must re-validate "p" */
176 if (p
!= *tarrayp
|| p
->pid
!= pid
)