Files
clang-p2996/lldb/test/functionalities/process_attach/attach_denied/main.cpp
Siva Chandra ff2b29d0ea [TestAttachDenied] Use a file instead of a pipe for synchronization.
Summary:
One cannot use mknod or mkfifo on user Android devices. This commit
changes the use of pipe to a file to synchronize between the inferior
and the test.

Test Plan: dotest.py -P TestAttachDenied

Reviewers: ovyalov, chaoren

Reviewed By: chaoren

Subscribers: tberghammer, lldb-commits

Differential Revision: http://reviews.llvm.org/D9768

llvm-svn: 237328
2015-05-14 01:36:47 +00:00

106 lines
2.5 KiB
C++

#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <linux/limits.h>
#include <sys/types.h>
#include <sys/ptrace.h>
#include <sys/stat.h>
#include <sys/wait.h>
#if defined(PTRACE_ATTACH)
#define ATTACH_REQUEST PTRACE_ATTACH
#define DETACH_REQUEST PTRACE_DETACH
#elif defined(PT_ATTACH)
#define ATTACH_REQUEST PT_ATTACH
#define DETACH_REQUEST PT_DETACH
#else
#error "Unsupported platform"
#endif
bool writePid (const char* file_name, const pid_t pid)
{
char tmp_file_name[PATH_MAX];
strcpy(tmp_file_name, file_name);
strcat(tmp_file_name, "_tmp");
int fd = open (tmp_file_name, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR);
if (fd == -1)
{
fprintf (stderr, "open(%s) failed: %s\n", tmp_file_name, strerror (errno));
return false;
}
char buffer[64];
snprintf (buffer, sizeof(buffer), "%ld", (long)pid);
bool res = true;
if (write (fd, buffer, strlen (buffer)) == -1)
{
fprintf (stderr, "write(%s) failed: %s\n", buffer, strerror (errno));
res = false;
}
close (fd);
if (rename (tmp_file_name, file_name) == -1)
{
fprintf (stderr, "rename(%s, %s) failed: %s\n", tmp_file_name, file_name, strerror (errno));
res = false;
}
return res;
}
void sigterm_handler (int)
{
}
int main (int argc, char const *argv[])
{
if (argc < 2)
{
fprintf (stderr, "invalid number of command line arguments\n");
return 1;
}
const pid_t pid = fork ();
if (pid == -1)
{
fprintf (stderr, "fork failed: %s\n", strerror (errno));
return 1;
}
if (pid > 0)
{
// Make pause call to return when SIGTERM is received.
signal (SIGTERM, sigterm_handler);
if (ptrace (ATTACH_REQUEST, pid, NULL, 0) == -1)
{
fprintf (stderr, "ptrace(ATTACH) failed: %s\n", strerror (errno));
}
else
{
if (writePid (argv[1], pid))
pause (); // Waiting for the debugger trying attach to the child.
if (ptrace (DETACH_REQUEST, pid, NULL, 0) != 0)
fprintf (stderr, "ptrace(DETACH) failed: %s\n", strerror (errno));
}
kill (pid, SIGTERM);
int status = 0;
if (waitpid (pid, &status, 0) == -1)
fprintf (stderr, "waitpid failed: %s\n", strerror (errno));
}
else
{
// child inferior.
pause ();
}
printf ("Exiting now\n");
return 0;
}