Home | History | Annotate | Download | only in tests
      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 
     20 static 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 
     48 static 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 
     67 static 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 
     91 int 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/%ld/cmdline", (long) 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/%ld/exe", (long) 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