@@ -24,26 +24,53 @@ using namespace llvm;
2424
2525namespace lldb_dap {
2626
27- FifoFile::FifoFile (StringRef path) : m_path(path) {}
27+ #if defined(_WIN32)
28+ FifoFile::FifoFile (StringRef path, HANDLE handle, bool is_server)
29+ : m_path(path), m_is_server(is_server), m_pipe_fd(handle) {}
30+ #else
31+ FifoFile::FifoFile (StringRef path, bool is_server)
32+ : m_path(path), m_is_server(is_server) {}
33+ #endif
2834
2935FifoFile::~FifoFile () {
30- #if !defined(_WIN32)
31- unlink (m_path.c_str ());
36+ #if defined(_WIN32)
37+ if (m_pipe_fd == INVALID_HANDLE_VALUE)
38+ return ;
39+ if (m_is_server)
40+ DisconnectNamedPipe (m_pipe_fd);
41+ CloseHandle (m_pipe_fd);
42+ #else
43+ if (m_is_server)
44+ unlink (m_path.c_str ());
3245#endif
3346}
3447
35- Expected<std::shared_ptr<FifoFile>> CreateFifoFile (StringRef path) {
48+ Expected<std::shared_ptr<FifoFile>> CreateFifoFile (StringRef path,
49+ bool is_server) {
3650#if defined(_WIN32)
37- return createStringError (inconvertibleErrorCode (), " Unimplemented" );
51+ if (!is_server)
52+ return std::make_shared<FifoFile>(path, INVALID_HANDLE_VALUE, is_server);
53+ HANDLE handle =
54+ CreateNamedPipeA (path.data (), PIPE_ACCESS_DUPLEX,
55+ PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1 ,
56+ 1024 * 16 , 1024 * 16 , 0 , NULL );
57+ if (handle == INVALID_HANDLE_VALUE)
58+ return createStringError (
59+ std::error_code (GetLastError (), std::generic_category ()),
60+ " Couldn't create fifo file: %s" , path.data ());
61+ return std::make_shared<FifoFile>(path, handle, is_server);
3862#else
63+ if (!is_server)
64+ return std::make_shared<FifoFile>(path, is_server);
3965 if (int err = mkfifo (path.data (), 0600 ))
4066 return createStringError (std::error_code (err, std::generic_category ()),
4167 " Couldn't create fifo file: %s" , path.data ());
42- return std::make_shared<FifoFile>(path);
68+ return std::make_shared<FifoFile>(path, is_server );
4369#endif
4470}
4571
46- FifoFileIO::FifoFileIO (StringRef fifo_file, StringRef other_endpoint_name)
72+ FifoFileIO::FifoFileIO (std::shared_ptr<FifoFile> fifo_file,
73+ StringRef other_endpoint_name)
4774 : m_fifo_file(fifo_file), m_other_endpoint_name(other_endpoint_name) {}
4875
4976Expected<json::Value> FifoFileIO::ReadJSON (std::chrono::milliseconds timeout) {
@@ -52,11 +79,27 @@ Expected<json::Value> FifoFileIO::ReadJSON(std::chrono::milliseconds timeout) {
5279 std::optional<std::string> line;
5380 std::future<void > *future =
5481 new std::future<void >(std::async (std::launch::async, [&]() {
55- std::ifstream reader (m_fifo_file, std::ifstream::in);
82+ #if defined(_WIN32)
83+ std::string buffer;
84+ buffer.reserve (4096 );
85+ char ch;
86+ DWORD bytes_read = 0 ;
87+ while (ReadFile (m_fifo_file->m_pipe_fd , &ch, 1 , &bytes_read, NULL ) &&
88+ (bytes_read == 1 )) {
89+ buffer.push_back (ch);
90+ if (ch == ' \n ' ) {
91+ break ;
92+ }
93+ }
94+ if (!buffer.empty ())
95+ line = std::move (buffer);
96+ #else
97+ std::ifstream reader (m_fifo_file->m_path , std::ifstream::in);
5698 std::string buffer;
5799 std::getline (reader, buffer);
58100 if (!buffer.empty ())
59101 line = buffer;
102+ #endif
60103 }));
61104 if (future->wait_for (timeout) == std::future_status::timeout || !line)
62105 // Indeed this is a leak, but it's intentional. "future" obj destructor
@@ -78,9 +121,18 @@ Error FifoFileIO::SendJSON(const json::Value &json,
78121 bool done = false ;
79122 std::future<void > *future =
80123 new std::future<void >(std::async (std::launch::async, [&]() {
81- std::ofstream writer (m_fifo_file, std::ofstream::out);
124+ #if defined(_WIN32)
125+ std::string buffer = JSONToString (json);
126+ buffer.append (" \n " );
127+ DWORD bytes_write = 0 ;
128+ WriteFile (m_fifo_file->m_pipe_fd , buffer.c_str (), buffer.size (),
129+ &bytes_write, NULL );
130+ done = bytes_write == buffer.size ();
131+ #else
132+ std::ofstream writer (m_fifo_file->m_path , std::ofstream::out);
82133 writer << JSONToString (json) << std::endl;
83134 done = true ;
135+ #endif
84136 }));
85137 if (future->wait_for (timeout) == std::future_status::timeout || !done) {
86138 // Indeed this is a leak, but it's intentional. "future" obj destructor will
@@ -98,4 +150,20 @@ Error FifoFileIO::SendJSON(const json::Value &json,
98150 return Error::success ();
99151}
100152
153+ #if defined(_WIN32)
154+ bool FifoFileIO::Connect () {
155+ if (m_fifo_file->m_is_server ) {
156+ return ConnectNamedPipe (m_fifo_file->m_pipe_fd , NULL );
157+ }
158+ if (!WaitNamedPipeA (m_fifo_file->m_path .c_str (), NMPWAIT_WAIT_FOREVER))
159+ return false ;
160+ m_fifo_file->m_pipe_fd =
161+ CreateFileA (m_fifo_file->m_path .c_str (), GENERIC_READ | GENERIC_WRITE, 0 ,
162+ NULL , OPEN_EXISTING, 0 , NULL );
163+ if (m_fifo_file->m_pipe_fd == INVALID_HANDLE_VALUE)
164+ return false ;
165+ return true ;
166+ }
167+ #endif
168+
101169} // namespace lldb_dap
0 commit comments