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/%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