| /* |
| * Read /proc/self/cmdline and /proc/self/exe such that it can be tested |
| * whether Valgrind intercepts the system calls that access these pseudo-files |
| * properly on Linux and whether Valgrind does not modify the behavior of |
| * accessing these files on other operating systems. |
| */ |
| |
| #define _ATFILE_SOURCE |
| |
| #include <ctype.h> |
| #include <errno.h> |
| #include <fcntl.h> |
| #include <stdio.h> |
| #include <sys/types.h> |
| #include <sys/stat.h> |
| #include <string.h> |
| #include <unistd.h> |
| #include "../../config.h" |
| |
| static void test_cmdline(const char* const cwd, const char* const label, |
| const char* const path) |
| { |
| int fd, n; |
| char ch; |
| |
| fprintf(stderr, "%s:\n", label); |
| fd = open(path, 0); |
| if (fd >= 0) |
| { |
| while ((n = read(fd, &ch, 1)) > 0) |
| { |
| if (ch == '\\') |
| fprintf(stderr, "\\\\"); |
| else if (ch == 0) |
| fprintf(stderr, "\\0"); |
| else if (isprint((unsigned)ch)) |
| fprintf(stderr, "%c", ch); |
| else |
| fprintf(stderr, "\\0%o", ch); |
| } |
| fprintf(stderr, "\n"); |
| close(fd); |
| } |
| else |
| perror("open()"); |
| } |
| |
| static void test_readlink(const char* const cwd, const char* const label, |
| const char* const path) |
| { |
| char buf[512]; |
| const char* p; |
| int n; |
| |
| if ((n = readlink(path, buf, sizeof(buf) - 1)) >= 0) |
| { |
| buf[n] = 0; |
| p = buf; |
| if (strncmp(buf, cwd, strlen(cwd)) == 0) |
| p += strlen(cwd); |
| fprintf(stderr, "Result of readlink(\"%s\"): %s\n", label, p); |
| } |
| else |
| perror("readlink"); |
| } |
| |
| static void test_readlinkat(const char* const cwd, const char* const label, |
| const char* const path) |
| { |
| #if HAVE_READLINKAT |
| char buf[512]; |
| const char* p; |
| int n; |
| |
| if ((n = readlinkat(AT_FDCWD, path, buf, sizeof(buf) - 1)) >= 0) |
| { |
| buf[n] = 0; |
| p = buf; |
| if (strncmp(buf, cwd, strlen(cwd)) == 0) |
| p += strlen(cwd); |
| fprintf(stderr, "Result of readlinkat(\"%s\"): %s\n", label, p); |
| } |
| else |
| perror("readlinkat"); |
| #else |
| errno = ENOSYS; |
| perror("readlinkat"); |
| #endif |
| } |
| |
| int main(int argc, char** argv) |
| { |
| char cwd[512]; |
| char path[512]; |
| |
| cwd[0] = 0; |
| if (! getcwd(cwd, sizeof(cwd))) |
| perror("getcwd"); |
| strcat(cwd, "/"); |
| |
| snprintf(path, sizeof(path), "/proc/%d/cmdline", getpid()); |
| |
| test_cmdline(cwd, "/proc/self/cmdline", "/proc/self/cmdline"); |
| test_cmdline(cwd, "/proc/<pid>/cmdline", path); |
| |
| snprintf(path, sizeof(path), "/proc/%d/exe", getpid()); |
| |
| test_readlink(cwd, "/proc/self/exe", "/proc/self/exe"); |
| test_readlink(cwd, "/proc/<pid>/exe", path); |
| |
| test_readlinkat(cwd, "/proc/self/exe", "/proc/self/exe"); |
| test_readlinkat(cwd, "/proc/<pid>/exe", path); |
| |
| return 0; |
| } |