root/tools/testing/selftests/pidfd/pidfd_open_test.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. safe_int
  2. char_left_gc
  3. char_right_gc
  4. trim_whitespace_in_place
  5. get_pid_from_fdinfo_file
  6. main

   1 // SPDX-License-Identifier: GPL-2.0
   2 
   3 #define _GNU_SOURCE
   4 #include <errno.h>
   5 #include <fcntl.h>
   6 #include <inttypes.h>
   7 #include <limits.h>
   8 #include <linux/types.h>
   9 #include <linux/wait.h>
  10 #include <sched.h>
  11 #include <signal.h>
  12 #include <stdbool.h>
  13 #include <stdio.h>
  14 #include <stdlib.h>
  15 #include <string.h>
  16 #include <syscall.h>
  17 #include <sys/mount.h>
  18 #include <sys/prctl.h>
  19 #include <sys/wait.h>
  20 #include <unistd.h>
  21 
  22 #include "pidfd.h"
  23 #include "../kselftest.h"
  24 
  25 static int safe_int(const char *numstr, int *converted)
  26 {
  27         char *err = NULL;
  28         long sli;
  29 
  30         errno = 0;
  31         sli = strtol(numstr, &err, 0);
  32         if (errno == ERANGE && (sli == LONG_MAX || sli == LONG_MIN))
  33                 return -ERANGE;
  34 
  35         if (errno != 0 && sli == 0)
  36                 return -EINVAL;
  37 
  38         if (err == numstr || *err != '\0')
  39                 return -EINVAL;
  40 
  41         if (sli > INT_MAX || sli < INT_MIN)
  42                 return -ERANGE;
  43 
  44         *converted = (int)sli;
  45         return 0;
  46 }
  47 
  48 static int char_left_gc(const char *buffer, size_t len)
  49 {
  50         size_t i;
  51 
  52         for (i = 0; i < len; i++) {
  53                 if (buffer[i] == ' ' ||
  54                     buffer[i] == '\t')
  55                         continue;
  56 
  57                 return i;
  58         }
  59 
  60         return 0;
  61 }
  62 
  63 static int char_right_gc(const char *buffer, size_t len)
  64 {
  65         int i;
  66 
  67         for (i = len - 1; i >= 0; i--) {
  68                 if (buffer[i] == ' '  ||
  69                     buffer[i] == '\t' ||
  70                     buffer[i] == '\n' ||
  71                     buffer[i] == '\0')
  72                         continue;
  73 
  74                 return i + 1;
  75         }
  76 
  77         return 0;
  78 }
  79 
  80 static char *trim_whitespace_in_place(char *buffer)
  81 {
  82         buffer += char_left_gc(buffer, strlen(buffer));
  83         buffer[char_right_gc(buffer, strlen(buffer))] = '\0';
  84         return buffer;
  85 }
  86 
  87 static pid_t get_pid_from_fdinfo_file(int pidfd, const char *key, size_t keylen)
  88 {
  89         int ret;
  90         char path[512];
  91         FILE *f;
  92         size_t n = 0;
  93         pid_t result = -1;
  94         char *line = NULL;
  95 
  96         snprintf(path, sizeof(path), "/proc/self/fdinfo/%d", pidfd);
  97 
  98         f = fopen(path, "re");
  99         if (!f)
 100                 return -1;
 101 
 102         while (getline(&line, &n, f) != -1) {
 103                 char *numstr;
 104 
 105                 if (strncmp(line, key, keylen))
 106                         continue;
 107 
 108                 numstr = trim_whitespace_in_place(line + 4);
 109                 ret = safe_int(numstr, &result);
 110                 if (ret < 0)
 111                         goto out;
 112 
 113                 break;
 114         }
 115 
 116 out:
 117         free(line);
 118         fclose(f);
 119         return result;
 120 }
 121 
 122 int main(int argc, char **argv)
 123 {
 124         int pidfd = -1, ret = 1;
 125         pid_t pid;
 126 
 127         ksft_set_plan(3);
 128 
 129         pidfd = sys_pidfd_open(-1, 0);
 130         if (pidfd >= 0) {
 131                 ksft_print_msg(
 132                         "%s - succeeded to open pidfd for invalid pid -1\n",
 133                         strerror(errno));
 134                 goto on_error;
 135         }
 136         ksft_test_result_pass("do not allow invalid pid test: passed\n");
 137 
 138         pidfd = sys_pidfd_open(getpid(), 1);
 139         if (pidfd >= 0) {
 140                 ksft_print_msg(
 141                         "%s - succeeded to open pidfd with invalid flag value specified\n",
 142                         strerror(errno));
 143                 goto on_error;
 144         }
 145         ksft_test_result_pass("do not allow invalid flag test: passed\n");
 146 
 147         pidfd = sys_pidfd_open(getpid(), 0);
 148         if (pidfd < 0) {
 149                 ksft_print_msg("%s - failed to open pidfd\n", strerror(errno));
 150                 goto on_error;
 151         }
 152         ksft_test_result_pass("open a new pidfd test: passed\n");
 153 
 154         pid = get_pid_from_fdinfo_file(pidfd, "Pid:", sizeof("Pid:") - 1);
 155         ksft_print_msg("pidfd %d refers to process with pid %d\n", pidfd, pid);
 156 
 157         ret = 0;
 158 
 159 on_error:
 160         if (pidfd >= 0)
 161                 close(pidfd);
 162 
 163         return !ret ? ksft_exit_pass() : ksft_exit_fail();
 164 }

/* [<][>][^][v][top][bottom][index][help] */