This source file includes following definitions.
- TAILQ_HEAD
- procfs_allocvp
- procfs_freevp
- procfs_rw
- vfs_getuserstr
- vfs_findname
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/time.h>
42 #include <sys/kernel.h>
43 #include <sys/proc.h>
44 #include <sys/vnode.h>
45 #include <sys/malloc.h>
46 #include <sys/stat.h>
47 #include <sys/ptrace.h>
48
49 #include <miscfs/procfs/procfs.h>
50
51 static TAILQ_HEAD(, pfsnode) pfshead;
52 struct lock pfs_vlock;
53
54
55 int
56 procfs_init(struct vfsconf *vfsp)
57 {
58 lockinit(&pfs_vlock, PVFS, "procfsl", 0, 0);
59 TAILQ_INIT(&pfshead);
60 return (0);
61 }
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89 int
90 procfs_allocvp(struct mount *mp, struct vnode **vpp, pid_t pid, pfstype pfs_type)
91 {
92 struct proc *p = curproc;
93 struct pfsnode *pfs;
94 struct vnode *vp;
95 int error;
96
97
98
99
100 error = lockmgr(&pfs_vlock, LK_EXCLUSIVE, NULL);
101 if (error)
102 return (error);
103 loop:
104 TAILQ_FOREACH(pfs, &pfshead, list) {
105 vp = PFSTOV(pfs);
106 if (pfs->pfs_pid == pid &&
107 pfs->pfs_type == pfs_type &&
108 vp->v_mount == mp) {
109 if (vget(vp, 0, p))
110 goto loop;
111 *vpp = vp;
112 goto out;
113 }
114 }
115
116 if ((error = getnewvnode(VT_PROCFS, mp, procfs_vnodeop_p, vpp)) != 0)
117 goto out;
118 vp = *vpp;
119
120 MALLOC(pfs, void *, sizeof(struct pfsnode), M_TEMP, M_WAITOK);
121 vp->v_data = pfs;
122
123 pfs->pfs_pid = pid;
124 pfs->pfs_type = pfs_type;
125 pfs->pfs_vnode = vp;
126 pfs->pfs_flags = 0;
127 pfs->pfs_fileno = PROCFS_FILENO(pid, pfs_type);
128
129 switch (pfs_type) {
130 case Proot:
131 pfs->pfs_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
132 vp->v_type = VDIR;
133 vp->v_flag = VROOT;
134 break;
135
136 case Pcurproc:
137 case Pself:
138 pfs->pfs_mode = S_IRUSR|S_IRGRP|S_IROTH;
139 vp->v_type = VLNK;
140 break;
141
142 case Pproc:
143 pfs->pfs_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
144 vp->v_type = VDIR;
145 break;
146
147 case Pfile:
148 case Pmem:
149 case Pregs:
150 case Pfpregs:
151 pfs->pfs_mode = S_IRUSR|S_IWUSR;
152 vp->v_type = VREG;
153 break;
154
155 case Pctl:
156 case Pnote:
157 case Pnotepg:
158 pfs->pfs_mode = S_IWUSR;
159 vp->v_type = VREG;
160 break;
161
162 case Pstatus:
163 case Pcmdline:
164 case Pmeminfo:
165 case Pcpuinfo:
166 pfs->pfs_mode = S_IRUSR|S_IRGRP|S_IROTH;
167 vp->v_type = VREG;
168 break;
169
170 default:
171 panic("procfs_allocvp");
172 }
173
174
175 TAILQ_INSERT_TAIL(&pfshead, pfs, list);
176 uvm_vnp_setsize(vp, 0);
177 out:
178 lockmgr(&pfs_vlock, LK_RELEASE, NULL);
179
180 return (error);
181 }
182
183 int
184 procfs_freevp(struct vnode *vp)
185 {
186 struct pfsnode *pfs = VTOPFS(vp);
187
188 TAILQ_REMOVE(&pfshead, pfs, list);
189 FREE(vp->v_data, M_TEMP);
190 vp->v_data = 0;
191 return (0);
192 }
193
194 int
195 procfs_rw(void *v)
196 {
197 struct vop_read_args *ap = v;
198 struct vnode *vp = ap->a_vp;
199 struct uio *uio = ap->a_uio;
200 struct proc *curp = uio->uio_procp;
201 struct pfsnode *pfs = VTOPFS(vp);
202 struct proc *p;
203
204 p = pfind(pfs->pfs_pid);
205 if (p == 0)
206 return (EINVAL);
207
208 if (p->p_pid == 1 && securelevel > 0 && uio->uio_rw == UIO_WRITE)
209 return (EPERM);
210 if (uio->uio_offset < 0)
211 return (EINVAL);
212
213 switch (pfs->pfs_type) {
214 case Pnote:
215 case Pnotepg:
216 return (procfs_donote(curp, p, pfs, uio));
217
218 case Pctl:
219 return (procfs_doctl(curp, p, pfs, uio));
220
221 case Pstatus:
222 return (procfs_dostatus(curp, p, pfs, uio));
223
224 case Pmem:
225 return (process_domem(curp, p, uio, PT_WRITE_I));
226
227 case Pcmdline:
228 return (procfs_docmdline(curp, p, pfs, uio));
229
230 case Pmeminfo:
231 return (procfs_domeminfo(curp, p, pfs, uio));
232
233 case Pcpuinfo:
234 return (procfs_docpuinfo(curp, p, pfs, uio));
235
236 default:
237 return (EOPNOTSUPP);
238 }
239 }
240
241
242
243
244
245
246
247
248
249
250
251
252
253 int
254 vfs_getuserstr(struct uio *uio, char *buf, int *buflenp)
255 {
256 int xlen;
257 int error;
258
259 if (uio->uio_offset != 0)
260 return (EINVAL);
261
262 xlen = *buflenp;
263
264
265 if (xlen < uio->uio_resid)
266 return (EMSGSIZE);
267 xlen = uio->uio_resid;
268
269 if ((error = uiomove(buf, xlen, uio)) != 0)
270 return (error);
271
272
273 uio->uio_offset = 0;
274
275
276 buf[xlen] = '\0';
277 xlen = strlen(buf);
278 if (xlen > 0 && buf[xlen-1] == '\n')
279 buf[--xlen] = '\0';
280 *buflenp = xlen;
281
282 return (0);
283 }
284
285 const vfs_namemap_t *
286 vfs_findname(const vfs_namemap_t *nm, char *buf, int buflen)
287 {
288 for (; nm->nm_name; nm++)
289 if (bcmp(buf, nm->nm_name, buflen + 1) == 0)
290 return (nm);
291
292 return (0);
293 }