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
*);
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 */
56 proc_permission
/* permission */
59 static struct dentry
* proc_follow_link(struct dentry
*dentry
,
62 struct inode
*inode
= dentry
->d_inode
;
63 struct task_struct
*p
;
64 struct dentry
* result
;
68 /* We don't need a base pointer in the /proc filesystem */
71 error
= permission(inode
, MAY_EXEC
);
72 result
= ERR_PTR(error
);
80 result
= ERR_PTR(-ENOENT
);
81 read_lock(&tasklist_lock
);
82 p
= find_task_by_pid(pid
);
88 if (!p
->fs
|| !p
->fs
->pwd
)
94 if (!p
->fs
|| !p
->fs
->root
)
100 struct vm_area_struct
* vma
;
105 if ((vma
->vm_flags
& VM_EXECUTABLE
) &&
107 result
= vma
->vm_file
->f_dentry
;
115 if (ino
& PROC_PID_FD_DIR
) {
118 file
= fcheck_task(p
, ino
);
119 if (!file
|| !file
->f_dentry
)
121 result
= file
->f_dentry
;
126 result
= dget(result
);
129 read_unlock(&tasklist_lock
);
136 * This pretty-prints the pathname of a dentry,
137 * clarifying sockets etc.
139 static int do_proc_readlink(struct dentry
*dentry
, char * buffer
, int buflen
)
141 struct inode
* inode
;
142 char * tmp
= (char*)__get_free_page(GFP_KERNEL
), *path
, *pattern
;
145 /* Check for special dentries.. */
147 inode
= dentry
->d_inode
;
148 if (inode
&& dentry
->d_parent
== dentry
) {
149 if (S_ISSOCK(inode
->i_mode
))
150 pattern
= "socket:[%lu]";
151 if (S_ISFIFO(inode
->i_mode
))
152 pattern
= "pipe:[%lu]";
156 len
= sprintf(tmp
, pattern
, inode
->i_ino
);
159 path
= d_path(dentry
, tmp
, PAGE_SIZE
);
160 len
= tmp
+ PAGE_SIZE
- path
;
166 copy_to_user(buffer
, path
, buflen
);
167 free_page((unsigned long)tmp
);
171 static int proc_readlink(struct dentry
* dentry
, char * buffer
, int buflen
)
175 dentry
= proc_follow_link(dentry
, NULL
);
176 error
= PTR_ERR(dentry
);
177 if (!IS_ERR(dentry
)) {
180 error
= do_proc_readlink(dentry
, buffer
, buflen
);