procfs-cmdline-exe.c revision e739ac0589b4fb43561f801c4faba8c1b89f8680
1/*
2 * Read /proc/self/cmdline and /proc/self/exe such that it can be tested
3 * whether Valgrind intercepts the system calls that access these pseudo-files
4 * properly on Linux and whether Valgrind does not modify the behavior of
5 * accessing these files on other operating systems.
6 */
7
8#define _ATFILE_SOURCE
9
10#include <ctype.h>
11#include <errno.h>
12#include <fcntl.h>
13#include <stdio.h>
14#include <sys/types.h>
15#include <sys/stat.h>
16#include <string.h>
17#include <unistd.h>
18#include "../../config.h"
19
20static void test_cmdline(const char* const cwd, const char* const label,
21                         const char* const path)
22{
23  int fd, n;
24  char ch;
25
26  fprintf(stderr, "%s:\n", label);
27  fd = open(path, 0);
28  if (fd >= 0)
29  {
30    while ((n = read(fd, &ch, 1)) > 0)
31    {
32      if (ch == '\\')
33        fprintf(stderr, "\\\\");
34      else if (ch == 0)
35        fprintf(stderr, "\\0");
36      else if (isprint((unsigned)ch))
37        fprintf(stderr, "%c", ch);
38      else
39        fprintf(stderr, "\\0%o", ch);
40    }
41    fprintf(stderr, "\n");
42    close(fd);
43  }
44  else
45    perror("open()");
46}
47
48static void test_readlink(const char* const cwd, const char* const label,
49                          const char* const path)
50{
51  char buf[512];
52  const char* p;
53  int n;
54
55  if ((n = readlink(path, buf, sizeof(buf) - 1)) >= 0)
56  {
57    buf[n] = 0;
58    p = buf;
59    if (strncmp(buf, cwd, strlen(cwd)) == 0)
60      p += strlen(cwd);
61    fprintf(stderr, "Result of readlink(\"%s\"): %s\n", label, p);
62  }
63  else
64    perror("readlink");
65}
66
67static void test_readlinkat(const char* const cwd, const char* const label,
68                            const char* const path)
69{
70#if HAVE_READLINKAT
71  char buf[512];
72  const char* p;
73  int n;
74
75  if ((n = readlinkat(AT_FDCWD, path, buf, sizeof(buf) - 1)) >= 0)
76  {
77    buf[n] = 0;
78    p = buf;
79    if (strncmp(buf, cwd, strlen(cwd)) == 0)
80      p += strlen(cwd);
81    fprintf(stderr, "Result of readlinkat(\"%s\"): %s\n", label, p);
82  }
83  else
84    perror("readlinkat");
85#else
86  errno = ENOSYS;
87  perror("readlinkat");
88#endif
89}
90
91int main(int argc, char** argv)
92{
93  char cwd[512];
94  char path[512];
95
96  cwd[0] = 0;
97  if (! getcwd(cwd, sizeof(cwd)))
98    perror("getcwd");
99  strcat(cwd, "/");
100
101  snprintf(path, sizeof(path), "/proc/%d/cmdline", getpid());
102
103  test_cmdline(cwd, "/proc/self/cmdline", "/proc/self/cmdline");
104  test_cmdline(cwd, "/proc/<pid>/cmdline", path);
105
106  snprintf(path, sizeof(path), "/proc/%d/exe", getpid());
107
108  test_readlink(cwd, "/proc/self/exe", "/proc/self/exe");
109  test_readlink(cwd, "/proc/<pid>/exe", path);
110
111  test_readlinkat(cwd, "/proc/self/exe", "/proc/self/exe");
112  test_readlinkat(cwd, "/proc/<pid>/exe", path);
113
114  return 0;
115}
116