4 * Copyright (C) 1991, 1992 Linus Torvalds
6 * /proc link-file handling code
9 #include <asm/uaccess.h>
11 #include <linux/errno.h>
12 #include <linux/sched.h>
15 #include <linux/file.h>
16 #include <linux/proc_fs.h>
17 #include <linux/stat.h>
19 static int proc_readlink(struct dentry
*, char *, int);
20 static struct dentry
* proc_follow_link(struct dentry
*, struct dentry
*, unsigned int);
23 * links can't do much...
25 static struct file_operations proc_fd_link_operations
= {
26 NULL
, /* lseek - default */
27 NULL
, /* read - bad */
28 NULL
, /* write - bad */
29 NULL
, /* readdir - bad */
30 NULL
, /* poll - default */
31 NULL
, /* ioctl - default */
33 NULL
, /* very special open code */
35 NULL
, /* no special release code */
36 NULL
/* can't fsync */
39 struct inode_operations proc_link_inode_operations
= {
40 &proc_fd_link_operations
,/* file-operations */
50 proc_readlink
, /* readlink */
51 proc_follow_link
, /* follow_link */
57 proc_permission
, /* permission */
62 static struct dentry
* proc_follow_link(struct dentry
*dentry
,
66 struct inode
*inode
= dentry
->d_inode
;
67 struct task_struct
*p
;
68 struct dentry
* result
;
72 /* We don't need a base pointer in the /proc filesystem */
75 error
= permission(inode
, MAY_EXEC
);
76 result
= ERR_PTR(error
);
84 result
= ERR_PTR(-ENOENT
);
85 read_lock(&tasklist_lock
);
86 p
= find_task_by_pid(pid
);
92 if (!p
->fs
|| !p
->fs
->pwd
)
98 if (!p
->fs
|| !p
->fs
->root
)
100 result
= p
->fs
->root
;
104 struct vm_area_struct
* vma
;
109 if ((vma
->vm_flags
& VM_EXECUTABLE
) &&
111 result
= vma
->vm_file
->f_dentry
;
119 if (ino
& PROC_PID_FD_DIR
) {
122 file
= fcheck_task(p
, ino
);
123 if (!file
|| !file
->f_dentry
)
125 result
= file
->f_dentry
;
130 result
= dget(result
);
133 read_unlock(&tasklist_lock
);
140 * This pretty-prints the pathname of a dentry,
141 * clarifying sockets etc.
143 static int do_proc_readlink(struct dentry
*dentry
, char * buffer
, int buflen
)
145 struct inode
* inode
;
146 char * tmp
= (char*)__get_free_page(GFP_KERNEL
), *path
, *pattern
;
149 /* Check for special dentries.. */
151 inode
= dentry
->d_inode
;
152 if (inode
&& IS_ROOT(dentry
)) {
153 if (S_ISSOCK(inode
->i_mode
))
154 pattern
= "socket:[%lu]";
155 if (S_ISFIFO(inode
->i_mode
))
156 pattern
= "pipe:[%lu]";
160 len
= sprintf(tmp
, pattern
, inode
->i_ino
);
163 path
= d_path(dentry
, tmp
, PAGE_SIZE
);
164 len
= tmp
+ PAGE_SIZE
- 1 - path
;
170 copy_to_user(buffer
, path
, buflen
);
171 free_page((unsigned long)tmp
);
175 static int proc_readlink(struct dentry
* dentry
, char * buffer
, int buflen
)
179 dentry
= proc_follow_link(dentry
, NULL
, 1);
180 error
= PTR_ERR(dentry
);
181 if (!IS_ERR(dentry
)) {
184 error
= do_proc_readlink(dentry
, buffer
, buflen
);