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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56#include <linux/types.h>
57#include <linux/errno.h>
58#include <linux/time.h>
59#include <linux/kernel.h>
60#include <linux/kernel_stat.h>
61#include <linux/tty.h>
62#include <linux/string.h>
63#include <linux/mman.h>
64#include <linux/sched/mm.h>
65#include <linux/sched/numa_balancing.h>
66#include <linux/sched/task_stack.h>
67#include <linux/sched/task.h>
68#include <linux/sched/cputime.h>
69#include <linux/proc_fs.h>
70#include <linux/ioport.h>
71#include <linux/uaccess.h>
72#include <linux/io.h>
73#include <linux/mm.h>
74#include <linux/hugetlb.h>
75#include <linux/pagemap.h>
76#include <linux/swap.h>
77#include <linux/smp.h>
78#include <linux/signal.h>
79#include <linux/highmem.h>
80#include <linux/file.h>
81#include <linux/fdtable.h>
82#include <linux/times.h>
83#include <linux/cpuset.h>
84#include <linux/rcupdate.h>
85#include <linux/delayacct.h>
86#include <linux/seq_file.h>
87#include <linux/pid_namespace.h>
88#include <linux/prctl.h>
89#include <linux/ptrace.h>
90#include <linux/tracehook.h>
91#include <linux/string_helpers.h>
92#include <linux/user_namespace.h>
93#include <linux/fs_struct.h>
94
95#include <asm/pgtable.h>
96#include <asm/processor.h>
97#include "internal.h"
98
99void proc_task_name(struct seq_file *m, struct task_struct *p, bool escape)
100{
101 char *buf;
102 size_t size;
103 char tcomm[64];
104 int ret;
105
106 if (p->flags & PF_WQ_WORKER)
107 wq_worker_comm(tcomm, sizeof(tcomm), p);
108 else
109 __get_task_comm(tcomm, sizeof(tcomm), p);
110
111 size = seq_get_buf(m, &buf);
112 if (escape) {
113 ret = string_escape_str(tcomm, buf, size,
114 ESCAPE_SPACE | ESCAPE_SPECIAL, "\n\\");
115 if (ret >= size)
116 ret = -1;
117 } else {
118 ret = strscpy(buf, tcomm, size);
119 }
120
121 seq_commit(m, ret);
122}
123
124
125
126
127
128
129
130static const char * const task_state_array[] = {
131
132
133 "R (running)",
134 "S (sleeping)",
135 "D (disk sleep)",
136 "T (stopped)",
137 "t (tracing stop)",
138 "X (dead)",
139 "Z (zombie)",
140 "P (parked)",
141
142
143 "I (idle)",
144};
145
146static inline const char *get_task_state(struct task_struct *tsk)
147{
148 BUILD_BUG_ON(1 + ilog2(TASK_REPORT_MAX) != ARRAY_SIZE(task_state_array));
149 return task_state_array[task_state_index(tsk)];
150}
151
152static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
153 struct pid *pid, struct task_struct *p)
154{
155 struct user_namespace *user_ns = seq_user_ns(m);
156 struct group_info *group_info;
157 int g, umask = -1;
158 struct task_struct *tracer;
159 const struct cred *cred;
160 pid_t ppid, tpid = 0, tgid, ngid;
161 unsigned int max_fds = 0;
162
163 rcu_read_lock();
164 ppid = pid_alive(p) ?
165 task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0;
166
167 tracer = ptrace_parent(p);
168 if (tracer)
169 tpid = task_pid_nr_ns(tracer, ns);
170
171 tgid = task_tgid_nr_ns(p, ns);
172 ngid = task_numa_group_id(p);
173 cred = get_task_cred(p);
174
175 task_lock(p);
176 if (p->fs)
177 umask = p->fs->umask;
178 if (p->files)
179 max_fds = files_fdtable(p->files)->max_fds;
180 task_unlock(p);
181 rcu_read_unlock();
182
183 if (umask >= 0)
184 seq_printf(m, "Umask:\t%#04o\n", umask);
185 seq_puts(m, "State:\t");
186 seq_puts(m, get_task_state(p));
187
188 seq_put_decimal_ull(m, "\nTgid:\t", tgid);
189 seq_put_decimal_ull(m, "\nNgid:\t", ngid);
190 seq_put_decimal_ull(m, "\nPid:\t", pid_nr_ns(pid, ns));
191 seq_put_decimal_ull(m, "\nPPid:\t", ppid);
192 seq_put_decimal_ull(m, "\nTracerPid:\t", tpid);
193 seq_put_decimal_ull(m, "\nUid:\t", from_kuid_munged(user_ns, cred->uid));
194 seq_put_decimal_ull(m, "\t", from_kuid_munged(user_ns, cred->euid));
195 seq_put_decimal_ull(m, "\t", from_kuid_munged(user_ns, cred->suid));
196 seq_put_decimal_ull(m, "\t", from_kuid_munged(user_ns, cred->fsuid));
197 seq_put_decimal_ull(m, "\nGid:\t", from_kgid_munged(user_ns, cred->gid));
198 seq_put_decimal_ull(m, "\t", from_kgid_munged(user_ns, cred->egid));
199 seq_put_decimal_ull(m, "\t", from_kgid_munged(user_ns, cred->sgid));
200 seq_put_decimal_ull(m, "\t", from_kgid_munged(user_ns, cred->fsgid));
201 seq_put_decimal_ull(m, "\nFDSize:\t", max_fds);
202
203 seq_puts(m, "\nGroups:\t");
204 group_info = cred->group_info;
205 for (g = 0; g < group_info->ngroups; g++)
206 seq_put_decimal_ull(m, g ? " " : "",
207 from_kgid_munged(user_ns, group_info->gid[g]));
208 put_cred(cred);
209
210 seq_putc(m, ' ');
211
212#ifdef CONFIG_PID_NS
213 seq_puts(m, "\nNStgid:");
214 for (g = ns->level; g <= pid->level; g++)
215 seq_put_decimal_ull(m, "\t", task_tgid_nr_ns(p, pid->numbers[g].ns));
216 seq_puts(m, "\nNSpid:");
217 for (g = ns->level; g <= pid->level; g++)
218 seq_put_decimal_ull(m, "\t", task_pid_nr_ns(p, pid->numbers[g].ns));
219 seq_puts(m, "\nNSpgid:");
220 for (g = ns->level; g <= pid->level; g++)
221 seq_put_decimal_ull(m, "\t", task_pgrp_nr_ns(p, pid->numbers[g].ns));
222 seq_puts(m, "\nNSsid:");
223 for (g = ns->level; g <= pid->level; g++)
224 seq_put_decimal_ull(m, "\t", task_session_nr_ns(p, pid->numbers[g].ns));
225#endif
226 seq_putc(m, '\n');
227}
228
229void render_sigset_t(struct seq_file *m, const char *header,
230 sigset_t *set)
231{
232 int i;
233
234 seq_puts(m, header);
235
236 i = _NSIG;
237 do {
238 int x = 0;
239
240 i -= 4;
241 if (sigismember(set, i+1)) x |= 1;
242 if (sigismember(set, i+2)) x |= 2;
243 if (sigismember(set, i+3)) x |= 4;
244 if (sigismember(set, i+4)) x |= 8;
245 seq_putc(m, hex_asc[x]);
246 } while (i >= 4);
247
248 seq_putc(m, '\n');
249}
250
251static void collect_sigign_sigcatch(struct task_struct *p, sigset_t *ign,
252 sigset_t *catch)
253{
254 struct k_sigaction *k;
255 int i;
256
257 k = p->sighand->action;
258 for (i = 1; i <= _NSIG; ++i, ++k) {
259 if (k->sa.sa_handler == SIG_IGN)
260 sigaddset(ign, i);
261 else if (k->sa.sa_handler != SIG_DFL)
262 sigaddset(catch, i);
263 }
264}
265
266static inline void task_sig(struct seq_file *m, struct task_struct *p)
267{
268 unsigned long flags;
269 sigset_t pending, shpending, blocked, ignored, caught;
270 int num_threads = 0;
271 unsigned int qsize = 0;
272 unsigned long qlim = 0;
273
274 sigemptyset(&pending);
275 sigemptyset(&shpending);
276 sigemptyset(&blocked);
277 sigemptyset(&ignored);
278 sigemptyset(&caught);
279
280 if (lock_task_sighand(p, &flags)) {
281 pending = p->pending.signal;
282 shpending = p->signal->shared_pending.signal;
283 blocked = p->blocked;
284 collect_sigign_sigcatch(p, &ignored, &caught);
285 num_threads = get_nr_threads(p);
286 rcu_read_lock();
287 qsize = atomic_read(&__task_cred(p)->user->sigpending);
288 rcu_read_unlock();
289 qlim = task_rlimit(p, RLIMIT_SIGPENDING);
290 unlock_task_sighand(p, &flags);
291 }
292
293 seq_put_decimal_ull(m, "Threads:\t", num_threads);
294 seq_put_decimal_ull(m, "\nSigQ:\t", qsize);
295 seq_put_decimal_ull(m, "/", qlim);
296
297
298 render_sigset_t(m, "\nSigPnd:\t", &pending);
299 render_sigset_t(m, "ShdPnd:\t", &shpending);
300 render_sigset_t(m, "SigBlk:\t", &blocked);
301 render_sigset_t(m, "SigIgn:\t", &ignored);
302 render_sigset_t(m, "SigCgt:\t", &caught);
303}
304
305static void render_cap_t(struct seq_file *m, const char *header,
306 kernel_cap_t *a)
307{
308 unsigned __capi;
309
310 seq_puts(m, header);
311 CAP_FOR_EACH_U32(__capi) {
312 seq_put_hex_ll(m, NULL,
313 a->cap[CAP_LAST_U32 - __capi], 8);
314 }
315 seq_putc(m, '\n');
316}
317
318static inline void task_cap(struct seq_file *m, struct task_struct *p)
319{
320 const struct cred *cred;
321 kernel_cap_t cap_inheritable, cap_permitted, cap_effective,
322 cap_bset, cap_ambient;
323
324 rcu_read_lock();
325 cred = __task_cred(p);
326 cap_inheritable = cred->cap_inheritable;
327 cap_permitted = cred->cap_permitted;
328 cap_effective = cred->cap_effective;
329 cap_bset = cred->cap_bset;
330 cap_ambient = cred->cap_ambient;
331 rcu_read_unlock();
332
333 render_cap_t(m, "CapInh:\t", &cap_inheritable);
334 render_cap_t(m, "CapPrm:\t", &cap_permitted);
335 render_cap_t(m, "CapEff:\t", &cap_effective);
336 render_cap_t(m, "CapBnd:\t", &cap_bset);
337 render_cap_t(m, "CapAmb:\t", &cap_ambient);
338}
339
340static inline void task_seccomp(struct seq_file *m, struct task_struct *p)
341{
342 seq_put_decimal_ull(m, "NoNewPrivs:\t", task_no_new_privs(p));
343#ifdef CONFIG_SECCOMP
344 seq_put_decimal_ull(m, "\nSeccomp:\t", p->seccomp.mode);
345#endif
346 seq_puts(m, "\nSpeculation_Store_Bypass:\t");
347 switch (arch_prctl_spec_ctrl_get(p, PR_SPEC_STORE_BYPASS)) {
348 case -EINVAL:
349 seq_puts(m, "unknown");
350 break;
351 case PR_SPEC_NOT_AFFECTED:
352 seq_puts(m, "not vulnerable");
353 break;
354 case PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE:
355 seq_puts(m, "thread force mitigated");
356 break;
357 case PR_SPEC_PRCTL | PR_SPEC_DISABLE:
358 seq_puts(m, "thread mitigated");
359 break;
360 case PR_SPEC_PRCTL | PR_SPEC_ENABLE:
361 seq_puts(m, "thread vulnerable");
362 break;
363 case PR_SPEC_DISABLE:
364 seq_puts(m, "globally mitigated");
365 break;
366 default:
367 seq_puts(m, "vulnerable");
368 break;
369 }
370 seq_putc(m, '\n');
371}
372
373static inline void task_context_switch_counts(struct seq_file *m,
374 struct task_struct *p)
375{
376 seq_put_decimal_ull(m, "voluntary_ctxt_switches:\t", p->nvcsw);
377 seq_put_decimal_ull(m, "\nnonvoluntary_ctxt_switches:\t", p->nivcsw);
378 seq_putc(m, '\n');
379}
380
381static void task_cpus_allowed(struct seq_file *m, struct task_struct *task)
382{
383 seq_printf(m, "Cpus_allowed:\t%*pb\n",
384 cpumask_pr_args(task->cpus_ptr));
385 seq_printf(m, "Cpus_allowed_list:\t%*pbl\n",
386 cpumask_pr_args(task->cpus_ptr));
387}
388
389static inline void task_core_dumping(struct seq_file *m, struct mm_struct *mm)
390{
391 seq_put_decimal_ull(m, "CoreDumping:\t", !!mm->core_state);
392 seq_putc(m, '\n');
393}
394
395static inline void task_thp_status(struct seq_file *m, struct mm_struct *mm)
396{
397 bool thp_enabled = IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE);
398
399 if (thp_enabled)
400 thp_enabled = !test_bit(MMF_DISABLE_THP, &mm->flags);
401 seq_printf(m, "THP_enabled:\t%d\n", thp_enabled);
402}
403
404int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
405 struct pid *pid, struct task_struct *task)
406{
407 struct mm_struct *mm = get_task_mm(task);
408
409 seq_puts(m, "Name:\t");
410 proc_task_name(m, task, true);
411 seq_putc(m, '\n');
412
413 task_state(m, ns, pid, task);
414
415 if (mm) {
416 task_mem(m, mm);
417 task_core_dumping(m, mm);
418 task_thp_status(m, mm);
419 mmput(mm);
420 }
421 task_sig(m, task);
422 task_cap(m, task);
423 task_seccomp(m, task);
424 task_cpus_allowed(m, task);
425 cpuset_task_status_allowed(m, task);
426 task_context_switch_counts(m, task);
427 return 0;
428}
429
430static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
431 struct pid *pid, struct task_struct *task, int whole)
432{
433 unsigned long vsize, eip, esp, wchan = 0;
434 int priority, nice;
435 int tty_pgrp = -1, tty_nr = 0;
436 sigset_t sigign, sigcatch;
437 char state;
438 pid_t ppid = 0, pgid = -1, sid = -1;
439 int num_threads = 0;
440 int permitted;
441 struct mm_struct *mm;
442 unsigned long long start_time;
443 unsigned long cmin_flt = 0, cmaj_flt = 0;
444 unsigned long min_flt = 0, maj_flt = 0;
445 u64 cutime, cstime, utime, stime;
446 u64 cgtime, gtime;
447 unsigned long rsslim = 0;
448 unsigned long flags;
449
450 state = *get_task_state(task);
451 vsize = eip = esp = 0;
452 permitted = ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS | PTRACE_MODE_NOAUDIT);
453 mm = get_task_mm(task);
454 if (mm) {
455 vsize = task_vsize(mm);
456
457
458
459
460
461
462
463
464
465 if (permitted && (task->flags & (PF_EXITING|PF_DUMPCORE))) {
466 if (try_get_task_stack(task)) {
467 eip = KSTK_EIP(task);
468 esp = KSTK_ESP(task);
469 put_task_stack(task);
470 }
471 }
472 }
473
474 sigemptyset(&sigign);
475 sigemptyset(&sigcatch);
476 cutime = cstime = utime = stime = 0;
477 cgtime = gtime = 0;
478
479 if (lock_task_sighand(task, &flags)) {
480 struct signal_struct *sig = task->signal;
481
482 if (sig->tty) {
483 struct pid *pgrp = tty_get_pgrp(sig->tty);
484 tty_pgrp = pid_nr_ns(pgrp, ns);
485 put_pid(pgrp);
486 tty_nr = new_encode_dev(tty_devnum(sig->tty));
487 }
488
489 num_threads = get_nr_threads(task);
490 collect_sigign_sigcatch(task, &sigign, &sigcatch);
491
492 cmin_flt = sig->cmin_flt;
493 cmaj_flt = sig->cmaj_flt;
494 cutime = sig->cutime;
495 cstime = sig->cstime;
496 cgtime = sig->cgtime;
497 rsslim = READ_ONCE(sig->rlim[RLIMIT_RSS].rlim_cur);
498
499
500 if (whole) {
501 struct task_struct *t = task;
502 do {
503 min_flt += t->min_flt;
504 maj_flt += t->maj_flt;
505 gtime += task_gtime(t);
506 } while_each_thread(task, t);
507
508 min_flt += sig->min_flt;
509 maj_flt += sig->maj_flt;
510 thread_group_cputime_adjusted(task, &utime, &stime);
511 gtime += sig->gtime;
512 }
513
514 sid = task_session_nr_ns(task, ns);
515 ppid = task_tgid_nr_ns(task->real_parent, ns);
516 pgid = task_pgrp_nr_ns(task, ns);
517
518 unlock_task_sighand(task, &flags);
519 }
520
521 if (permitted && (!whole || num_threads < 2))
522 wchan = get_wchan(task);
523 if (!whole) {
524 min_flt = task->min_flt;
525 maj_flt = task->maj_flt;
526 task_cputime_adjusted(task, &utime, &stime);
527 gtime = task_gtime(task);
528 }
529
530
531
532 priority = task_prio(task);
533 nice = task_nice(task);
534
535
536 start_time = nsec_to_clock_t(task->start_boottime);
537
538 seq_put_decimal_ull(m, "", pid_nr_ns(pid, ns));
539 seq_puts(m, " (");
540 proc_task_name(m, task, false);
541 seq_puts(m, ") ");
542 seq_putc(m, state);
543 seq_put_decimal_ll(m, " ", ppid);
544 seq_put_decimal_ll(m, " ", pgid);
545 seq_put_decimal_ll(m, " ", sid);
546 seq_put_decimal_ll(m, " ", tty_nr);
547 seq_put_decimal_ll(m, " ", tty_pgrp);
548 seq_put_decimal_ull(m, " ", task->flags);
549 seq_put_decimal_ull(m, " ", min_flt);
550 seq_put_decimal_ull(m, " ", cmin_flt);
551 seq_put_decimal_ull(m, " ", maj_flt);
552 seq_put_decimal_ull(m, " ", cmaj_flt);
553 seq_put_decimal_ull(m, " ", nsec_to_clock_t(utime));
554 seq_put_decimal_ull(m, " ", nsec_to_clock_t(stime));
555 seq_put_decimal_ll(m, " ", nsec_to_clock_t(cutime));
556 seq_put_decimal_ll(m, " ", nsec_to_clock_t(cstime));
557 seq_put_decimal_ll(m, " ", priority);
558 seq_put_decimal_ll(m, " ", nice);
559 seq_put_decimal_ll(m, " ", num_threads);
560 seq_put_decimal_ull(m, " ", 0);
561 seq_put_decimal_ull(m, " ", start_time);
562 seq_put_decimal_ull(m, " ", vsize);
563 seq_put_decimal_ull(m, " ", mm ? get_mm_rss(mm) : 0);
564 seq_put_decimal_ull(m, " ", rsslim);
565 seq_put_decimal_ull(m, " ", mm ? (permitted ? mm->start_code : 1) : 0);
566 seq_put_decimal_ull(m, " ", mm ? (permitted ? mm->end_code : 1) : 0);
567 seq_put_decimal_ull(m, " ", (permitted && mm) ? mm->start_stack : 0);
568 seq_put_decimal_ull(m, " ", esp);
569 seq_put_decimal_ull(m, " ", eip);
570
571
572
573
574 seq_put_decimal_ull(m, " ", task->pending.signal.sig[0] & 0x7fffffffUL);
575 seq_put_decimal_ull(m, " ", task->blocked.sig[0] & 0x7fffffffUL);
576 seq_put_decimal_ull(m, " ", sigign.sig[0] & 0x7fffffffUL);
577 seq_put_decimal_ull(m, " ", sigcatch.sig[0] & 0x7fffffffUL);
578
579
580
581
582
583
584
585
586 if (wchan)
587 seq_puts(m, " 1");
588 else
589 seq_puts(m, " 0");
590
591 seq_put_decimal_ull(m, " ", 0);
592 seq_put_decimal_ull(m, " ", 0);
593 seq_put_decimal_ll(m, " ", task->exit_signal);
594 seq_put_decimal_ll(m, " ", task_cpu(task));
595 seq_put_decimal_ull(m, " ", task->rt_priority);
596 seq_put_decimal_ull(m, " ", task->policy);
597 seq_put_decimal_ull(m, " ", delayacct_blkio_ticks(task));
598 seq_put_decimal_ull(m, " ", nsec_to_clock_t(gtime));
599 seq_put_decimal_ll(m, " ", nsec_to_clock_t(cgtime));
600
601 if (mm && permitted) {
602 seq_put_decimal_ull(m, " ", mm->start_data);
603 seq_put_decimal_ull(m, " ", mm->end_data);
604 seq_put_decimal_ull(m, " ", mm->start_brk);
605 seq_put_decimal_ull(m, " ", mm->arg_start);
606 seq_put_decimal_ull(m, " ", mm->arg_end);
607 seq_put_decimal_ull(m, " ", mm->env_start);
608 seq_put_decimal_ull(m, " ", mm->env_end);
609 } else
610 seq_puts(m, " 0 0 0 0 0 0 0");
611
612 if (permitted)
613 seq_put_decimal_ll(m, " ", task->exit_code);
614 else
615 seq_puts(m, " 0");
616
617 seq_putc(m, '\n');
618 if (mm)
619 mmput(mm);
620 return 0;
621}
622
623int proc_tid_stat(struct seq_file *m, struct pid_namespace *ns,
624 struct pid *pid, struct task_struct *task)
625{
626 return do_task_stat(m, ns, pid, task, 0);
627}
628
629int proc_tgid_stat(struct seq_file *m, struct pid_namespace *ns,
630 struct pid *pid, struct task_struct *task)
631{
632 return do_task_stat(m, ns, pid, task, 1);
633}
634
635int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns,
636 struct pid *pid, struct task_struct *task)
637{
638 struct mm_struct *mm = get_task_mm(task);
639
640 if (mm) {
641 unsigned long size;
642 unsigned long resident = 0;
643 unsigned long shared = 0;
644 unsigned long text = 0;
645 unsigned long data = 0;
646
647 size = task_statm(mm, &shared, &text, &data, &resident);
648 mmput(mm);
649
650
651
652
653
654
655
656 seq_put_decimal_ull(m, "", size);
657 seq_put_decimal_ull(m, " ", resident);
658 seq_put_decimal_ull(m, " ", shared);
659 seq_put_decimal_ull(m, " ", text);
660 seq_put_decimal_ull(m, " ", 0);
661 seq_put_decimal_ull(m, " ", data);
662 seq_put_decimal_ull(m, " ", 0);
663 seq_putc(m, '\n');
664 } else {
665 seq_write(m, "0 0 0 0 0 0 0\n", 14);
666 }
667 return 0;
668}
669
670#ifdef CONFIG_PROC_CHILDREN
671static struct pid *
672get_children_pid(struct inode *inode, struct pid *pid_prev, loff_t pos)
673{
674 struct task_struct *start, *task;
675 struct pid *pid = NULL;
676
677 read_lock(&tasklist_lock);
678
679 start = pid_task(proc_pid(inode), PIDTYPE_PID);
680 if (!start)
681 goto out;
682
683
684
685
686
687 if (pid_prev) {
688 task = pid_task(pid_prev, PIDTYPE_PID);
689 if (task && task->real_parent == start &&
690 !(list_empty(&task->sibling))) {
691 if (list_is_last(&task->sibling, &start->children))
692 goto out;
693 task = list_first_entry(&task->sibling,
694 struct task_struct, sibling);
695 pid = get_pid(task_pid(task));
696 goto out;
697 }
698 }
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715 list_for_each_entry(task, &start->children, sibling) {
716 if (pos-- == 0) {
717 pid = get_pid(task_pid(task));
718 break;
719 }
720 }
721
722out:
723 read_unlock(&tasklist_lock);
724 return pid;
725}
726
727static int children_seq_show(struct seq_file *seq, void *v)
728{
729 struct inode *inode = file_inode(seq->file);
730
731 seq_printf(seq, "%d ", pid_nr_ns(v, proc_pid_ns(inode)));
732 return 0;
733}
734
735static void *children_seq_start(struct seq_file *seq, loff_t *pos)
736{
737 return get_children_pid(file_inode(seq->file), NULL, *pos);
738}
739
740static void *children_seq_next(struct seq_file *seq, void *v, loff_t *pos)
741{
742 struct pid *pid;
743
744 pid = get_children_pid(file_inode(seq->file), v, *pos + 1);
745 put_pid(v);
746
747 ++*pos;
748 return pid;
749}
750
751static void children_seq_stop(struct seq_file *seq, void *v)
752{
753 put_pid(v);
754}
755
756static const struct seq_operations children_seq_ops = {
757 .start = children_seq_start,
758 .next = children_seq_next,
759 .stop = children_seq_stop,
760 .show = children_seq_show,
761};
762
763static int children_seq_open(struct inode *inode, struct file *file)
764{
765 return seq_open(file, &children_seq_ops);
766}
767
768const struct file_operations proc_tid_children_operations = {
769 .open = children_seq_open,
770 .read = seq_read,
771 .llseek = seq_lseek,
772 .release = seq_release,
773};
774#endif
775