File: tracer_ppid_pgid_sid.c

package info (click to toggle)
strace 6.1-0.1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 64,424 kB
  • sloc: ansic: 160,349; sh: 9,223; makefile: 3,817; cpp: 944; awk: 353; perl: 267; exp: 62; sed: 9
file content (90 lines) | stat: -rw-r--r-- 1,829 bytes parent folder | download | duplicates (9)
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
57
58
59
60
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
90
/*
 * Helper program for strace-DDD.test
 *
 * Copyright (c) 2019-2021 Dmitry V. Levin <ldv@strace.io>
 * All rights reserved.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

#include "tests.h"
#include "xmalloc.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

static int
fetch_tracer_pid(const char *str)
{
	for (; isspace(*str); ++str)
		;
	return atoi(str);
}

static int
get_tracer_pid(void)
{
	static const char status[] = "/proc/self/status";
	FILE *fp = fopen(status, "r");
	if (!fp)
		perror_msg_and_fail("fopen: %s", status);

	static const char prefix[] = "TracerPid:";
	const size_t prefix_len = sizeof(prefix) - 1;
	const char *str = NULL;
	char *line = NULL;
	size_t n = 0;

	while (getline(&line, &n, fp) > 0) {
		if (strncmp(line, prefix, prefix_len) == 0) {
			str = line + prefix_len;
			break;
		}
	}
	if (!str && !line)
		perror_msg_and_fail("getline");

	int pid = str ? fetch_tracer_pid(str) : 0;
	free(line);
	fclose(fp);

	return pid;
}

static void
get_ppid_pgid_sid(int pid, int *ppid, int *pgid, int *sid)
{
	char *stat = xasprintf("/proc/%d/stat", pid);
	FILE *fp = fopen(stat, "r");
	if (!fp)
		perror_msg_and_fail("fopen: %s", stat);
	char buf[4096];
	if (!fgets(buf, sizeof(buf), fp))
		perror_msg_and_fail("fgets: %s", stat);

	fclose(fp);

	const char *p = strrchr(buf, ')');
	if (!p)
		error_msg_and_fail("%s: parenthesis not found", stat);
	++p;

	if (sscanf(p, " %*c %d %d %d", ppid, pgid, sid) != 3)
		error_msg_and_fail("%s: sscanf failed", stat);
}

int
main(void)
{
	int tracer_pid = get_tracer_pid();
	if (tracer_pid < 0)
		error_msg_and_fail("tracer_pid = %d", tracer_pid);

	int ppid = 0, pgid = 0, sid = 0;
	get_ppid_pgid_sid(tracer_pid, &ppid, &pgid, &sid);
	printf("%d %d %d %d\n", tracer_pid, ppid, pgid, sid);

	return 0;
}