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