1 /*
2 * Helper program for strace-DDD.test
3 *
4 * Copyright (c) 2019-2021 Dmitry V. Levin <ldv@strace.io>
5 * All rights reserved.
6 *
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 */
9
10 #include "tests.h"
11 #include "xmalloc.h"
12 #include <ctype.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <unistd.h>
17
18 static int
19 fetch_tracer_pid(const char *str)
20 {
21 for (; isspace(*str); ++str)
22 ;
23 return atoi(str);
24 }
25
26 static int
27 get_tracer_pid(void)
28 {
29 static const char status[] = "/proc/self/status";
30 FILE *fp = fopen(status, "r");
31 if (!fp)
32 perror_msg_and_fail("fopen: %s", status);
33
34 static const char prefix[] = "TracerPid:";
35 const size_t prefix_len = sizeof(prefix) - 1;
36 const char *str = NULL;
37 char *line = NULL;
38 size_t n = 0;
39
40 while (getline(&line, &n, fp) > 0) {
41 if (strncmp(line, prefix, prefix_len) == 0) {
42 str = line + prefix_len;
43 break;
44 }
45 }
46 if (!str && !line)
47 perror_msg_and_fail("getline");
48
49 int pid = str ? fetch_tracer_pid(str) : 0;
50 free(line);
51 fclose(fp);
52
53 return pid;
54 }
55
56 static void
57 get_ppid_pgid_sid(int pid, int *ppid, int *pgid, int *sid)
58 {
59 char *stat = xasprintf("/proc/%d/stat", pid);
60 FILE *fp = fopen(stat, "r");
61 if (!fp)
62 perror_msg_and_fail("fopen: %s", stat);
63 char buf[4096];
64 if (!fgets(buf, sizeof(buf), fp))
65 perror_msg_and_fail("fgets: %s", stat);
66
67 fclose(fp);
68
69 const char *p = strrchr(buf, ')');
70 if (!p)
71 error_msg_and_fail("%s: parenthesis not found", stat);
72 ++p;
73
74 if (sscanf(p, " %*c %d %d %d", ppid, pgid, sid) != 3)
75 error_msg_and_fail("%s: sscanf failed", stat);
76 }
77
78 int
79 main(void)
80 {
81 int tracer_pid = get_tracer_pid();
82 if (tracer_pid < 0)
83 error_msg_and_fail("tracer_pid = %d", tracer_pid);
84
85 int ppid = 0, pgid = 0, sid = 0;
86 get_ppid_pgid_sid(tracer_pid, &ppid, &pgid, &sid);
87 printf("%d %d %d %d\n", tracer_pid, ppid, pgid, sid);
88
89 return 0;
90 }