This source file includes following definitions.
- proc_follow_link
- proc_readlink
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/fs.h>
14 #include <linux/mm.h>
15 #include <linux/proc_fs.h>
16 #include <linux/stat.h>
17
18 static int proc_readlink(struct inode *, char *, int);
19 static int proc_follow_link(struct inode *, struct inode *, int, int,
20 struct inode **);
21
22
23
24
25
26 #undef PLAN9_SEMANTICS
27
28
29
30
31 static struct file_operations proc_fd_link_operations = {
32 NULL,
33 NULL,
34 NULL,
35 NULL,
36 NULL,
37 NULL,
38 NULL,
39 NULL,
40 NULL,
41 NULL
42 };
43
44 struct inode_operations proc_link_inode_operations = {
45 &proc_fd_link_operations,
46 NULL,
47 NULL,
48 NULL,
49 NULL,
50 NULL,
51 NULL,
52 NULL,
53 NULL,
54 NULL,
55 proc_readlink,
56 proc_follow_link,
57 NULL,
58 NULL,
59 NULL,
60 NULL,
61 NULL
62 };
63
64
65 static int proc_follow_link(struct inode * dir, struct inode * inode,
66 int flag, int mode, struct inode ** res_inode)
67 {
68 unsigned int pid, ino;
69 struct task_struct * p;
70 struct inode * new_inode;
71 int i, error;
72
73 *res_inode = NULL;
74 if (dir)
75 iput(dir);
76 if (!inode)
77 return -ENOENT;
78 if ((error = permission(inode, MAY_EXEC)) != 0){
79 iput(inode);
80 return error;
81 }
82 ino = inode->i_ino;
83 pid = ino >> 16;
84 ino &= 0x0000ffff;
85 for (i = 0 ; i < NR_TASKS ; i++)
86 if ((p = task[i]) && p->pid == pid)
87 break;
88 if (i >= NR_TASKS) {
89 iput(inode);
90 return -ENOENT;
91 }
92 new_inode = NULL;
93 switch (ino) {
94 case PROC_PID_CWD:
95 if (!p->fs)
96 break;
97 new_inode = p->fs->pwd;
98 break;
99 case PROC_PID_ROOT:
100 if (!p->fs)
101 break;
102 new_inode = p->fs->root;
103 break;
104 case PROC_PID_EXE: {
105 struct vm_area_struct * vma;
106 if (!p->mm)
107 break;
108 vma = p->mm->mmap;
109 while (vma) {
110 if (vma->vm_flags & VM_EXECUTABLE) {
111 new_inode = vma->vm_inode;
112 break;
113 }
114 vma = vma->vm_next;
115 }
116 break;
117 }
118 default:
119 switch (ino >> 8) {
120 case PROC_PID_FD_DIR:
121 if (!p->files)
122 break;
123 ino &= 0xff;
124 if (ino < NR_OPEN && p->files->fd[ino]) {
125 new_inode = p->files->fd[ino]->f_inode;
126 }
127 break;
128 }
129 }
130 iput(inode);
131 if (!new_inode)
132 return -ENOENT;
133 *res_inode = new_inode;
134 new_inode->i_count++;
135 return 0;
136 }
137
138 static int proc_readlink(struct inode * inode, char * buffer, int buflen)
139 {
140 int i;
141 unsigned int dev,ino;
142 char buf[64];
143
144 if (!S_ISLNK(inode->i_mode)) {
145 iput(inode);
146 return -EINVAL;
147 }
148 i = proc_follow_link(NULL, inode, 0, 0, &inode);
149 if (i)
150 return i;
151 if (!inode)
152 return -EIO;
153 dev = kdev_t_to_nr(inode->i_dev);
154 ino = inode->i_ino;
155 iput(inode);
156 i = sprintf(buf,"[%04x]:%u", dev, ino);
157 if (buflen > i)
158 buflen = i;
159 i = 0;
160 while (i < buflen)
161 put_user(buf[i++],buffer++);
162 return i;
163 }