4 #include <sys/ptrace.h>
8 #include "BidirectionalPipe.h"
9 #include "misc/Exception.h"
14 BidirectionalPipeException::BidirectionalPipeException(std::string message
,
15 bool strerr
) : Misc::Exception(Misc::StreamAsString() << message
<< (strerr
?strerror(errno
):"")) {
18 BidirectionalPipe::BidirectionalPipe(Misc::ArgumentList argument_list
, bool block
) : block(block
) {
25 if(pid
== -1) throw BidirectionalPipeException("Could not fork to execute child process: ", true);
27 close(pc_pipe_fd
[1]); /* Close the write end of the pc pipe */
28 close(cp_pipe_fd
[0]); /* Close the read end of the cp pipe */
30 fcntl(pc_pipe_fd
[0], F_SETFL
, fcntl(pc_pipe_fd
[0], F_GETFL
) & ~O_NONBLOCK
);
31 fcntl(cp_pipe_fd
[1], F_SETFL
, fcntl(cp_pipe_fd
[1], F_GETFL
) & ~O_NONBLOCK
);
33 dup2(pc_pipe_fd
[0], STDIN_FILENO
);
34 dup2(cp_pipe_fd
[1], STDOUT_FILENO
);
36 execv(argument_list
.get_argument(0).c_str(), argument_list
.get_as_argv());
38 throw BidirectionalPipeException("Failed to execute file: ", true);
40 close(pc_pipe_fd
[0]); /* Close the read end of the pc pipe */
41 close(cp_pipe_fd
[1]); /* Close the write end of the cp pipe */
43 fcntl(pc_pipe_fd
[1], F_SETFL
, fcntl(cp_pipe_fd
[1], F_GETFL
) & ~O_NONBLOCK
);
46 /* Pipe opened and ready to go. */
50 BidirectionalPipe::~BidirectionalPipe() {
51 if(is_connected
) close(pc_pipe_fd
[1]), close(cp_pipe_fd
[0]);
55 std::string
BidirectionalPipe::get_string() {
60 if(!is_open()) return "";
62 while((ret_value
= read(cp_pipe_fd
[0], &recv
, sizeof(recv
))) > 0) {
68 /* EAGAIN on a pipe read with O_NONBLOCK set means no data waiting. */
69 if(!block
&& ret_value
== -1 && errno
== EAGAIN
) {
76 void BidirectionalPipe::send_string(std::string data
) {
77 if(is_open()) write(pc_pipe_fd
[1], data
.c_str(), data
.length());
80 void BidirectionalPipe::set_blocking(bool new_blocking
) {
82 if(!block
) fcntl(cp_pipe_fd
[0], F_SETFL
, fcntl(cp_pipe_fd
[0], F_GETFL
) | O_NONBLOCK
);
83 else fcntl(cp_pipe_fd
[0], F_SETFL
, fcntl(cp_pipe_fd
[0], F_GETFL
) & ~O_NONBLOCK
);
86 } // namespace Platform
87 } // namespace Aesalon