From 3ca6e5ea6e5b9fa0226012d8851794c31070400d Mon Sep 17 00:00:00 2001 From: Vadim Lopatin Date: Tue, 31 May 2016 16:21:39 +0300 Subject: [PATCH] terminal pipe --- src/dlangide/ui/outputpanel.d | 8 +-- src/dlangide/ui/terminal.d | 127 ++++++++++++++++++++++++++-------- 2 files changed, 101 insertions(+), 34 deletions(-) diff --git a/src/dlangide/ui/outputpanel.d b/src/dlangide/ui/outputpanel.d index 30ddcba..1c04557 100644 --- a/src/dlangide/ui/outputpanel.d +++ b/src/dlangide/ui/outputpanel.d @@ -181,10 +181,10 @@ class OutputPanel : DockWindow { _terminalWidget.write("\x1b[34;45m blue on magenta "d); _terminalWidget.write("\x1b[31;46m red on cyan "d); //_terminalWidget.write("\x1b[2Jerased screen"d); - TerminalDevice term = new TerminalDevice(); - if (!term.create()) { - Log.e("Cannot create terminal device"); - } + //TerminalDevice term = new TerminalDevice(); + //if (!term.create()) { + // Log.e("Cannot create terminal device"); + //} return _tabs; } diff --git a/src/dlangide/ui/terminal.d b/src/dlangide/ui/terminal.d index 988062c..2aa59b0 100644 --- a/src/dlangide/ui/terminal.d +++ b/src/dlangide/ui/terminal.d @@ -655,46 +655,113 @@ class TerminalWidget : WidgetGroup, OnScrollHandler { } -class TerminalDevice { - int masterfd; - int slavefd; +import core.thread; + +class TerminalDevice : Thread { + version (Windows) { + import win32.windows; + HANDLE hpipe; + } else { + int masterfd; + } string name; - void close() { - if (masterfd && masterfd != -1) { - import core.sys.posix.unistd; - close(masterfd); - masterfd = 0; + bool closed; + bool connected; + + this() { + super(&threadProc); + } + ~this() { + close(); + } + + void threadProc() { + } + + bool write(string msg) { + if (!msg.length) + return true; + if (!closed) + return false; + version (Windows) { + for (;;) { + DWORD bytesWritten = 0; + if (WriteFile(hpipe, cast(char*)msg.ptr, msg.length, &bytesWritten, null) != TRUE) { + return false; + } + if (bytesWritten < msg.length) + msg = msg[bytesWritten .. $]; + else + break; + } + } else { + // linux/posix } + return true; + } + void close() { + version (Windows) { + if (hpipe && hpipe != INVALID_HANDLE_VALUE) { + CloseHandle(hpipe); + hpipe = null; + } + } else { + if (masterfd && masterfd != -1) { + import core.sys.posix.unistd; + close(masterfd); + masterfd = 0; + } + } + name = null; + closed = true; } bool create() { import std.string; - const(char) * s = null; - { - import core.sys.posix.fcntl; - import core.sys.posix.stdio; - import core.sys.posix.stdlib; - import core.sys.posix.unistd; - masterfd = posix_openpt(O_RDWR | O_NOCTTY); - if (masterfd == -1) { - Log.e("posix_openpt failed - cannot open terminal"); + version (Windows) { + import std.uuid; + name = "\\\\.\\pipe\\dlangide-terminal-" ~ randomUUID().toString; + hpipe = CreateNamedPipeA(cast(const(char)*)name.toStringz, + PIPE_ACCESS_DUPLEX, + cast(uint)PIPE_TYPE_BYTE, + 1, + 16384, + 16384, + 50, + null); + if (hpipe == INVALID_HANDLE_VALUE) { + Log.e("Failed to create named pipe for terminal, error=", GetLastError()); + close(); return false; } - if (grantpt(masterfd) == -1 || unlockpt(masterfd) == -1) { - Log.e("grantpt / unlockpt failed - cannot open terminal"); - close(masterfd); - masterfd = 0; - return false; - } - s = ptsname(masterfd); - if (!s) { - Log.e("ptsname failed - cannot open terminal"); - close(masterfd); - masterfd = 0; - return false; + } else { + const(char) * s = null; + { + import core.sys.posix.fcntl; + import core.sys.posix.stdio; + import core.sys.posix.stdlib; + import core.sys.posix.unistd; + masterfd = posix_openpt(O_RDWR | O_NOCTTY); + if (masterfd == -1) { + Log.e("posix_openpt failed - cannot open terminal"); + close(); + return false; + } + if (grantpt(masterfd) == -1 || unlockpt(masterfd) == -1) { + Log.e("grantpt / unlockpt failed - cannot open terminal"); + close(); + return false; + } + s = ptsname(masterfd); + if (!s) { + Log.e("ptsname failed - cannot open terminal"); + close(); + return false; + } } + name = fromStringz(s).dup; } - name = fromStringz(s).dup; Log.i("ptty device created: ", name); + start(); return true; } }