(root)/
strace-6.5/
tests-m32/
tracer_ppid_pgid_sid.c
       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  }