├── .config └── tsaoptions.json ├── .editorconfig ├── .eslintrc.js ├── .gitattributes ├── .github └── ISSUE_TEMPLATE.md ├── .gitignore ├── .npmignore ├── .npmrc ├── .vscode └── launch.json ├── LICENSE ├── README.md ├── SECURITY.md ├── azure-pipelines.yml ├── binding.gyp ├── deps ├── .editorconfig └── winpty │ ├── .drone.yml │ ├── .gitattributes │ ├── .gitignore │ ├── LICENSE │ ├── Makefile │ ├── README.md │ ├── RELEASES.md │ ├── VERSION.txt │ ├── configure │ ├── misc │ ├── .gitignore │ ├── BufferResizeTests.cc │ ├── ChangeScreenBuffer.cc │ ├── ClearConsole.cc │ ├── ConinMode.cc │ ├── ConinMode.ps1 │ ├── ConoutMode.cc │ ├── DebugClient.py │ ├── DebugServer.py │ ├── DumpLines.py │ ├── EnableExtendedFlags.txt │ ├── Font-Report-June2016 │ │ ├── CP437-Consolas.txt │ │ ├── CP437-Lucida.txt │ │ ├── CP932.txt │ │ ├── CP936.txt │ │ ├── CP949.txt │ │ ├── CP950.txt │ │ ├── MinimumWindowWidths.txt │ │ ├── Results.txt │ │ └── Windows10SetFontBugginess.txt │ ├── FontSurvey.cc │ ├── FormatChar.h │ ├── FreezePerfTest.cc │ ├── GetCh.cc │ ├── GetConsolePos.cc │ ├── GetFont.cc │ ├── IdentifyConsoleWindow.ps1 │ ├── IsNewConsole.cc │ ├── MouseInputNotes.txt │ ├── MoveConsoleWindow.cc │ ├── Notes.txt │ ├── OSVersion.cc │ ├── ScreenBufferFreezeInactive.cc │ ├── ScreenBufferTest.cc │ ├── ScreenBufferTest2.cc │ ├── SelectAllTest.cc │ ├── SetBufferSize.cc │ ├── SetCursorPos.cc │ ├── SetFont.cc │ ├── SetWindowRect.cc │ ├── ShowArgv.cc │ ├── ShowConsoleInput.cc │ ├── Spew.py │ ├── TestUtil.cc │ ├── UnicodeDoubleWidthTest.cc │ ├── UnicodeWideTest1.cc │ ├── UnicodeWideTest2.cc │ ├── UnixEcho.cc │ ├── Utf16Echo.cc │ ├── VeryLargeRead.cc │ ├── VkEscapeTest.cc │ ├── Win10ResizeWhileFrozen.cc │ ├── Win10WrapTest1.cc │ ├── Win10WrapTest2.cc │ ├── Win32Echo1.cc │ ├── Win32Echo2.cc │ ├── Win32Test1.cc │ ├── Win32Test2.cc │ ├── Win32Test3.cc │ ├── Win32Write1.cc │ ├── WindowsBugCrashReader.cc │ ├── WriteConsole.cc │ ├── build32.sh │ ├── build64.sh │ ├── color-test.sh │ ├── font-notes.txt │ └── winbug-15048.cc │ ├── ship │ ├── build-pty4j-libpty.bat │ ├── common_ship.py │ ├── make_msvc_package.py │ └── ship.py │ ├── src │ ├── agent │ │ ├── Agent.cc │ │ ├── Agent.h │ │ ├── AgentCreateDesktop.cc │ │ ├── AgentCreateDesktop.h │ │ ├── ConsoleFont.cc │ │ ├── ConsoleFont.h │ │ ├── ConsoleInput.cc │ │ ├── ConsoleInput.h │ │ ├── ConsoleInputReencoding.cc │ │ ├── ConsoleInputReencoding.h │ │ ├── ConsoleLine.cc │ │ ├── ConsoleLine.h │ │ ├── Coord.h │ │ ├── DebugShowInput.cc │ │ ├── DebugShowInput.h │ │ ├── DefaultInputMap.cc │ │ ├── DefaultInputMap.h │ │ ├── DsrSender.h │ │ ├── EventLoop.cc │ │ ├── EventLoop.h │ │ ├── InputMap.cc │ │ ├── InputMap.h │ │ ├── LargeConsoleRead.cc │ │ ├── LargeConsoleRead.h │ │ ├── NamedPipe.cc │ │ ├── NamedPipe.h │ │ ├── Scraper.cc │ │ ├── Scraper.h │ │ ├── SimplePool.h │ │ ├── SmallRect.h │ │ ├── Terminal.cc │ │ ├── Terminal.h │ │ ├── UnicodeEncoding.h │ │ ├── UnicodeEncodingTest.cc │ │ ├── Win32Console.cc │ │ ├── Win32Console.h │ │ ├── Win32ConsoleBuffer.cc │ │ ├── Win32ConsoleBuffer.h │ │ ├── main.cc │ │ └── subdir.mk │ ├── configurations.gypi │ ├── debugserver │ │ ├── DebugServer.cc │ │ └── subdir.mk │ ├── include │ │ ├── winpty.h │ │ └── winpty_constants.h │ ├── libwinpty │ │ ├── AgentLocation.cc │ │ ├── AgentLocation.h │ │ ├── LibWinptyException.h │ │ ├── WinptyInternal.h │ │ ├── subdir.mk │ │ └── winpty.cc │ ├── shared │ │ ├── AgentMsg.h │ │ ├── BackgroundDesktop.cc │ │ ├── BackgroundDesktop.h │ │ ├── Buffer.cc │ │ ├── Buffer.h │ │ ├── DebugClient.cc │ │ ├── DebugClient.h │ │ ├── GenRandom.cc │ │ ├── GenRandom.h │ │ ├── GetCommitHash.bat │ │ ├── Mutex.h │ │ ├── OsModule.h │ │ ├── OwnedHandle.cc │ │ ├── OwnedHandle.h │ │ ├── PrecompiledHeader.h │ │ ├── StringBuilder.h │ │ ├── StringBuilderTest.cc │ │ ├── StringUtil.cc │ │ ├── StringUtil.h │ │ ├── TimeMeasurement.h │ │ ├── UnixCtrlChars.h │ │ ├── UpdateGenVersion.bat │ │ ├── WindowsSecurity.cc │ │ ├── WindowsSecurity.h │ │ ├── WindowsVersion.cc │ │ ├── WindowsVersion.h │ │ ├── WinptyAssert.cc │ │ ├── WinptyAssert.h │ │ ├── WinptyException.cc │ │ ├── WinptyException.h │ │ ├── WinptyVersion.cc │ │ ├── WinptyVersion.h │ │ └── winpty_snprintf.h │ ├── subdir.mk │ ├── tests │ │ ├── subdir.mk │ │ └── trivial_test.cc │ ├── unix-adapter │ │ ├── InputHandler.cc │ │ ├── InputHandler.h │ │ ├── OutputHandler.cc │ │ ├── OutputHandler.h │ │ ├── Util.cc │ │ ├── Util.h │ │ ├── WakeupFd.cc │ │ ├── WakeupFd.h │ │ ├── main.cc │ │ └── subdir.mk │ └── winpty.gyp │ └── vcbuild.bat ├── examples ├── electron │ ├── README.md │ ├── images │ │ └── preview.png │ ├── index.html │ ├── main.js │ ├── npm_install.bat │ ├── npm_install.sh │ ├── package.json │ └── renderer.js ├── fork │ ├── index.js │ └── package.json └── killDeepTree │ ├── README.md │ ├── entry.js │ ├── index.js │ ├── package.json │ └── webpack.config.js ├── fixtures └── utf8-character.txt ├── package-lock.json ├── package.json ├── publish.yml ├── scripts ├── increment-version.js └── post-install.js ├── src ├── conpty_console_list_agent.ts ├── eventEmitter2.test.ts ├── eventEmitter2.ts ├── index.ts ├── interfaces.ts ├── native.d.ts ├── shared │ └── conout.ts ├── terminal.test.ts ├── terminal.ts ├── testUtils.test.ts ├── tsconfig.json ├── types.ts ├── unix │ ├── pty.cc │ └── spawn-helper.cc ├── unixTerminal.test.ts ├── unixTerminal.ts ├── utils.ts ├── win │ ├── conpty.cc │ ├── conpty.h │ ├── conpty_console_list.cc │ ├── path_util.cc │ ├── path_util.h │ └── winpty.cc ├── windowsConoutConnection.ts ├── windowsPtyAgent.test.ts ├── windowsPtyAgent.ts ├── windowsTerminal.test.ts ├── windowsTerminal.ts └── worker │ └── conoutSocketWorker.ts ├── test └── spam-close.js ├── third_party └── conpty │ └── 1.22.250204002 │ ├── win10-arm64 │ ├── OpenConsole.exe │ └── conpty.dll │ └── win10-x64 │ ├── OpenConsole.exe │ └── conpty.dll └── typings └── node-pty.d.ts /.config/tsaoptions.json: -------------------------------------------------------------------------------- 1 | { 2 | "codebaseName": "devdiv_microsoft_vscode_node_pty", 3 | "instanceUrl": "https://devdiv.visualstudio.com/defaultcollection", 4 | "projectName": "DevDiv", 5 | "areaPath": "DevDiv\\VS Code (compliance tracking only)\\Visual Studio Code NPM Packages", 6 | "notificationAliases": [ 7 | "stbatt@microsoft.com", 8 | "lszomoru@microsoft.com" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | insert_final_newline = true 7 | trim_trailing_whitespace = true 8 | end_of_line = lf 9 | 10 | [*.ts] 11 | max_line_length = 100 12 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Environment details 2 | 3 | - OS: 4 | - OS version: 5 | - node-pty version: 6 | 7 | ## Issue description 8 | 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | .lock-wscript 3 | out/ 4 | Makefile.gyp 5 | *.Makefile 6 | *.target.gyp.mk 7 | node_modules/ 8 | builderror.log 9 | lib/ 10 | npm-debug.log 11 | fixtures/space folder/ 12 | .vscode/settings.json 13 | .vscode/ipch/ 14 | yarn.lock 15 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | *.test.js 2 | *.test.ts 3 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | unsafe-perm=true 2 | package-lock=false 3 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "node", 9 | "request": "launch", 10 | "name": "Unit Tests", 11 | "cwd": "${workspaceRoot}", 12 | "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/mocha", 13 | "windows": { 14 | "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/mocha.cmd" 15 | }, 16 | "runtimeArgs": [ 17 | "--colors", 18 | "--recursive", 19 | "${workspaceRoot}/lib/**/*.test.js" 20 | ], 21 | "env": { 22 | "NODE_PATH": "${workspaceRoot}/lib" 23 | }, 24 | "sourceMaps": true, 25 | "outFiles": [ 26 | "${workspaceRoot}/lib/**/*.js" 27 | ], 28 | "internalConsoleOptions": "openOnSessionStart" 29 | }, 30 | { 31 | "type": "node", 32 | "request": "attach", 33 | "name": "Attach to process ID", 34 | "processId": "${command:PickProcess}" 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). 40 | 41 | 42 | -------------------------------------------------------------------------------- /azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | # Node.js 2 | # Build a general Node.js project with npm. 3 | # Add steps that analyze code, save build artifacts, deploy, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/languages/javascript 5 | 6 | resources: 7 | repositories: 8 | - repository: 1esPipelines 9 | type: git 10 | name: 1ESPipelineTemplates/1ESPipelineTemplates 11 | ref: refs/tags/release 12 | 13 | extends: 14 | template: v1/1ES.Official.PipelineTemplate.yml@1esPipelines 15 | parameters: 16 | sdl: 17 | sourceAnalysisPool: 1es-oss-windows-2022-x64 18 | tsa: 19 | enabled: true 20 | stages: 21 | - stage: Build 22 | jobs: 23 | - job: Linux 24 | pool: 25 | name: 1es-oss-ubuntu-22.04-x64 26 | os: Linux 27 | steps: 28 | - task: NodeTool@0 29 | inputs: 30 | versionSpec: 20.x 31 | displayName: 'Install Node.js' 32 | - script: npm ci 33 | displayName: 'Install dependencies and build' 34 | - script: npm test 35 | displayName: 'Test' 36 | - script: npm run lint 37 | displayName: 'Lint' 38 | 39 | - job: macOS 40 | pool: 41 | name: Azure Pipelines 42 | vmImage: 'macOS-14' 43 | os: macOS 44 | steps: 45 | - task: NodeTool@0 46 | inputs: 47 | versionSpec: 20.x 48 | displayName: 'Install Node.js' 49 | - script: python3 -m pip install setuptools 50 | displayName: Install setuptools (macOS) 51 | - script: npm ci 52 | displayName: 'Install dependencies and build' 53 | - script: npm test 54 | displayName: 'Test' 55 | - script: npm run lint 56 | displayName: 'Lint' 57 | 58 | - job: Windows 59 | pool: 60 | name: 1es-oss-windows-2022-x64 61 | os: Windows 62 | steps: 63 | - task: NodeTool@0 64 | inputs: 65 | versionSpec: 20.x 66 | displayName: 'Install Node.js' 67 | - script: npm ci 68 | displayName: 'Install dependencies and build' 69 | - script: npm test 70 | displayName: 'Test' 71 | - script: npm run lint 72 | displayName: 'Lint' 73 | -------------------------------------------------------------------------------- /deps/.editorconfig: -------------------------------------------------------------------------------- 1 | # Have editor config ignore this directory 2 | root = true 3 | -------------------------------------------------------------------------------- /deps/winpty/.drone.yml: -------------------------------------------------------------------------------- 1 | # Build configure for https://www.tea-ci.org (fork of Drone CI with Msys2 support) 2 | build: 3 | image: teaci/msys$$arch 4 | pull: true 5 | shell: msys$$arch 6 | commands: 7 | - pacman -S --needed --noconfirm --noprogressbar mingw-w64-cross-gcc mingw-w64-cross-crt-git 8 | - ./configure 9 | - make 10 | - make tests 11 | - build/trivial_test.exe 12 | - mintty --log - --exec build/winpty.exe cmd /c ver | grep Windows 13 | 14 | matrix: 15 | arch: 16 | - 64 17 | - 32 18 | -------------------------------------------------------------------------------- /deps/winpty/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.bat text eol=crlf 3 | *.c text 4 | *.cc text 5 | *.gyp text 6 | *.gypi text 7 | *.h text 8 | *.ps1 text eol=crlf 9 | *.rst text 10 | *.sh text 11 | *.txt text 12 | .gitignore text 13 | .gitattributes text 14 | Makefile text 15 | configure text 16 | 17 | *.sh eol=lf 18 | configure eol=lf 19 | VERSION.txt eol=lf 20 | -------------------------------------------------------------------------------- /deps/winpty/.gitignore: -------------------------------------------------------------------------------- 1 | *.sln 2 | *.suo 3 | *.vcxproj 4 | *.vcxproj.filters 5 | *.pyc 6 | winpty.sdf 7 | winpty.opensdf 8 | /config.mk 9 | /build 10 | /build-gyp 11 | /build-libpty 12 | /ship/packages 13 | /src/Default 14 | /src/Release 15 | /src/gen 16 | -------------------------------------------------------------------------------- /deps/winpty/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2011-2016 Ryan Prichard 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to 7 | deal in the Software without restriction, including without limitation the 8 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9 | sell copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /deps/winpty/VERSION.txt: -------------------------------------------------------------------------------- 1 | 0.4.4-dev 2 | -------------------------------------------------------------------------------- /deps/winpty/misc/.gitignore: -------------------------------------------------------------------------------- 1 | *.exe 2 | UnixEcho -------------------------------------------------------------------------------- /deps/winpty/misc/BufferResizeTests.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "TestUtil.cc" 5 | 6 | void dumpInfoToTrace() { 7 | CONSOLE_SCREEN_BUFFER_INFO info; 8 | assert(GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info)); 9 | trace("win=(%d,%d,%d,%d)", 10 | (int)info.srWindow.Left, 11 | (int)info.srWindow.Top, 12 | (int)info.srWindow.Right, 13 | (int)info.srWindow.Bottom); 14 | trace("buf=(%d,%d)", 15 | (int)info.dwSize.X, 16 | (int)info.dwSize.Y); 17 | trace("cur=(%d,%d)", 18 | (int)info.dwCursorPosition.X, 19 | (int)info.dwCursorPosition.Y); 20 | } 21 | 22 | int main(int argc, char *argv[]) { 23 | if (argc == 1) { 24 | startChildProcess(L"CHILD"); 25 | return 0; 26 | } 27 | 28 | setWindowPos(0, 0, 1, 1); 29 | 30 | if (false) { 31 | // Reducing the buffer height can move the window up. 32 | setBufferSize(80, 25); 33 | setWindowPos(0, 20, 80, 5); 34 | Sleep(2000); 35 | setBufferSize(80, 10); 36 | } 37 | 38 | if (false) { 39 | // Reducing the buffer height moves the window up and the buffer 40 | // contents up too. 41 | setBufferSize(80, 25); 42 | setWindowPos(0, 20, 80, 5); 43 | setCursorPos(0, 20); 44 | printf("TEST1\nTEST2\nTEST3\nTEST4\n"); 45 | fflush(stdout); 46 | Sleep(2000); 47 | setBufferSize(80, 10); 48 | } 49 | 50 | if (false) { 51 | // Reducing the buffer width can move the window left. 52 | setBufferSize(80, 25); 53 | setWindowPos(40, 0, 40, 25); 54 | Sleep(2000); 55 | setBufferSize(60, 25); 56 | } 57 | 58 | if (false) { 59 | // Sometimes the buffer contents are shifted up; sometimes they're 60 | // shifted down. It seems to depend on the cursor position? 61 | 62 | // setBufferSize(80, 25); 63 | // setWindowPos(0, 20, 80, 5); 64 | // setCursorPos(0, 20); 65 | // printf("TESTa\nTESTb\nTESTc\nTESTd\nTESTe"); 66 | // fflush(stdout); 67 | // setCursorPos(0, 0); 68 | // printf("TEST1\nTEST2\nTEST3\nTEST4\nTEST5"); 69 | // fflush(stdout); 70 | // setCursorPos(0, 24); 71 | // Sleep(5000); 72 | // setBufferSize(80, 24); 73 | 74 | setBufferSize(80, 20); 75 | setWindowPos(0, 10, 80, 10); 76 | setCursorPos(0, 18); 77 | 78 | printf("TEST1\nTEST2"); 79 | fflush(stdout); 80 | setCursorPos(0, 18); 81 | 82 | Sleep(2000); 83 | setBufferSize(80, 18); 84 | } 85 | 86 | dumpInfoToTrace(); 87 | Sleep(30000); 88 | 89 | return 0; 90 | } 91 | -------------------------------------------------------------------------------- /deps/winpty/misc/ChangeScreenBuffer.cc: -------------------------------------------------------------------------------- 1 | // A test program for CreateConsoleScreenBuffer / SetConsoleActiveScreenBuffer 2 | // 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "TestUtil.cc" 11 | 12 | int main() 13 | { 14 | HANDLE origBuffer = GetStdHandle(STD_OUTPUT_HANDLE); 15 | HANDLE childBuffer = CreateConsoleScreenBuffer( 16 | GENERIC_READ | GENERIC_WRITE, 17 | FILE_SHARE_READ | FILE_SHARE_WRITE, 18 | NULL, CONSOLE_TEXTMODE_BUFFER, NULL); 19 | 20 | SetConsoleActiveScreenBuffer(childBuffer); 21 | 22 | while (true) { 23 | char buf[1024]; 24 | CONSOLE_SCREEN_BUFFER_INFO info; 25 | 26 | assert(GetConsoleScreenBufferInfo(origBuffer, &info)); 27 | trace("child.size=(%d,%d)", (int)info.dwSize.X, (int)info.dwSize.Y); 28 | trace("child.cursor=(%d,%d)", (int)info.dwCursorPosition.X, (int)info.dwCursorPosition.Y); 29 | trace("child.window=(%d,%d,%d,%d)", 30 | (int)info.srWindow.Left, (int)info.srWindow.Top, 31 | (int)info.srWindow.Right, (int)info.srWindow.Bottom); 32 | trace("child.maxSize=(%d,%d)", (int)info.dwMaximumWindowSize.X, (int)info.dwMaximumWindowSize.Y); 33 | 34 | int ch = getch(); 35 | sprintf(buf, "%02x\n", ch); 36 | DWORD actual = 0; 37 | WriteFile(childBuffer, buf, strlen(buf), &actual, NULL); 38 | if (ch == 0x1b/*ESC*/ || ch == 0x03/*CTRL-C*/) 39 | break; 40 | 41 | if (ch == 'b') { 42 | setBufferSize(origBuffer, 40, 25); 43 | } else if (ch == 'w') { 44 | setWindowPos(origBuffer, 1, 1, 38, 23); 45 | } else if (ch == 'c') { 46 | setCursorPos(origBuffer, 10, 10); 47 | } 48 | } 49 | 50 | SetConsoleActiveScreenBuffer(origBuffer); 51 | 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /deps/winpty/misc/ClearConsole.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Demonstrates that console clearing sets each cell's character to SP, not 3 | * NUL, and it sets the attribute of each cell to the current text attribute. 4 | * 5 | * This confirms the MSDN instruction in the "Clearing the Screen" article. 6 | * https://msdn.microsoft.com/en-us/library/windows/desktop/ms682022(v=vs.85).aspx 7 | * It advises using GetConsoleScreenBufferInfo to get the current text 8 | * attribute, then FillConsoleOutputCharacter and FillConsoleOutputAttribute to 9 | * write to the console buffer. 10 | */ 11 | 12 | #include 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #include "TestUtil.cc" 19 | 20 | int main(int argc, char *argv[]) { 21 | if (argc == 1) { 22 | startChildProcess(L"CHILD"); 23 | return 0; 24 | } 25 | 26 | const HANDLE conout = GetStdHandle(STD_OUTPUT_HANDLE); 27 | 28 | SetConsoleTextAttribute(conout, 0x24); 29 | system("cls"); 30 | 31 | setWindowPos(0, 0, 1, 1); 32 | setBufferSize(80, 25); 33 | setWindowPos(0, 0, 80, 25); 34 | 35 | CHAR_INFO buf; 36 | COORD bufSize = { 1, 1 }; 37 | COORD bufCoord = { 0, 0 }; 38 | SMALL_RECT rect = { 5, 5, 5, 5 }; 39 | BOOL ret; 40 | DWORD actual; 41 | COORD writeCoord = { 5, 5 }; 42 | 43 | // After cls, each cell's character is a space, and its attributes are the 44 | // default text attributes. 45 | ret = ReadConsoleOutputW(conout, &buf, bufSize, bufCoord, &rect); 46 | assert(ret && buf.Char.UnicodeChar == L' ' && buf.Attributes == 0x24); 47 | 48 | // Nevertheless, it is possible to change a cell to NUL. 49 | ret = FillConsoleOutputCharacterW(conout, L'\0', 1, writeCoord, &actual); 50 | assert(ret && actual == 1); 51 | ret = ReadConsoleOutputW(conout, &buf, bufSize, bufCoord, &rect); 52 | assert(ret && buf.Char.UnicodeChar == L'\0' && buf.Attributes == 0x24); 53 | 54 | // As well as a 0 attribute. (As one would expect, the cell is 55 | // black-on-black.) 56 | ret = FillConsoleOutputAttribute(conout, 0, 1, writeCoord, &actual); 57 | assert(ret && actual == 1); 58 | ret = ReadConsoleOutputW(conout, &buf, bufSize, bufCoord, &rect); 59 | assert(ret && buf.Char.UnicodeChar == L'\0' && buf.Attributes == 0); 60 | ret = FillConsoleOutputCharacterW(conout, L'X', 1, writeCoord, &actual); 61 | assert(ret && actual == 1); 62 | ret = ReadConsoleOutputW(conout, &buf, bufSize, bufCoord, &rect); 63 | assert(ret && buf.Char.UnicodeChar == L'X' && buf.Attributes == 0); 64 | 65 | // The 'X' is invisible. 66 | countDown(3); 67 | 68 | ret = FillConsoleOutputAttribute(conout, 0x42, 1, writeCoord, &actual); 69 | assert(ret && actual == 1); 70 | 71 | countDown(5); 72 | } 73 | -------------------------------------------------------------------------------- /deps/winpty/misc/DebugClient.py: -------------------------------------------------------------------------------- 1 | #!python 2 | # Run with native CPython. Needs pywin32 extensions. 3 | 4 | # Copyright (c) 2011-2012 Ryan Prichard 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a copy 7 | # of this software and associated documentation files (the "Software"), to 8 | # deal in the Software without restriction, including without limitation the 9 | # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | # sell copies of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in 14 | # all copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 | # IN THE SOFTWARE. 23 | 24 | import winerror 25 | import win32pipe 26 | import win32file 27 | import win32api 28 | import sys 29 | import pywintypes 30 | import time 31 | 32 | if len(sys.argv) != 2: 33 | print("Usage: %s message" % sys.argv[0]) 34 | sys.exit(1) 35 | 36 | message = "[%05.3f %s]: %s" % (time.time() % 100000, sys.argv[0], sys.argv[1]) 37 | 38 | win32pipe.CallNamedPipe( 39 | "\\\\.\\pipe\\DebugServer", 40 | message.encode(), 41 | 16, 42 | win32pipe.NMPWAIT_WAIT_FOREVER) 43 | -------------------------------------------------------------------------------- /deps/winpty/misc/DebugServer.py: -------------------------------------------------------------------------------- 1 | #!python 2 | # 3 | # Run with native CPython. Needs pywin32 extensions. 4 | 5 | # Copyright (c) 2011-2012 Ryan Prichard 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to 9 | # deal in the Software without restriction, including without limitation the 10 | # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 11 | # sell copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | # 14 | # The above copyright notice and this permission notice shall be included in 15 | # all copies or substantial portions of the Software. 16 | # 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 23 | # IN THE SOFTWARE. 24 | 25 | import win32pipe 26 | import win32api 27 | import win32file 28 | import time 29 | import threading 30 | import sys 31 | 32 | # A message may not be larger than this size. 33 | MSG_SIZE=4096 34 | 35 | serverPipe = win32pipe.CreateNamedPipe( 36 | "\\\\.\\pipe\\DebugServer", 37 | win32pipe.PIPE_ACCESS_DUPLEX, 38 | win32pipe.PIPE_TYPE_MESSAGE | win32pipe.PIPE_READMODE_MESSAGE, 39 | win32pipe.PIPE_UNLIMITED_INSTANCES, 40 | MSG_SIZE, 41 | MSG_SIZE, 42 | 10 * 1000, 43 | None) 44 | while True: 45 | win32pipe.ConnectNamedPipe(serverPipe, None) 46 | (ret, data) = win32file.ReadFile(serverPipe, MSG_SIZE) 47 | print(data.decode()) 48 | sys.stdout.flush() 49 | 50 | # The client uses CallNamedPipe to send its message. CallNamedPipe waits 51 | # for a reply message. If I send a reply, however, using WriteFile, then 52 | # sometimes WriteFile fails with: 53 | # pywintypes.error: (232, 'WriteFile', 'The pipe is being closed.') 54 | # I can't figure out how to write a strictly correct pipe server, but if 55 | # I comment out the WriteFile line, then everything seems to work. I 56 | # think the DisconnectNamedPipe call aborts the client's CallNamedPipe 57 | # call normally. 58 | 59 | try: 60 | win32file.WriteFile(serverPipe, b'OK') 61 | except: 62 | pass 63 | win32pipe.DisconnectNamedPipe(serverPipe) 64 | -------------------------------------------------------------------------------- /deps/winpty/misc/DumpLines.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import sys 3 | 4 | for i in range(1, int(sys.argv[1]) + 1): 5 | print i, "X" * 78 6 | -------------------------------------------------------------------------------- /deps/winpty/misc/EnableExtendedFlags.txt: -------------------------------------------------------------------------------- 1 | Note regarding ENABLE_EXTENDED_FLAGS (2016-05-30) 2 | 3 | There is a complicated interaction between the ENABLE_EXTENDED_FLAGS flag 4 | and the ENABLE_QUICK_EDIT_MODE and ENABLE_INSERT_MODE flags (presumably for 5 | backwards compatibility?). I studied the behavior on Windows 7 and Windows 6 | 10, with both the old and new consoles, and I didn't see any differences 7 | between versions. Here's what I seemed to observe: 8 | 9 | - The console has three flags internally: 10 | - QuickEdit 11 | - InsertMode 12 | - ExtendedFlags 13 | 14 | - SetConsoleMode psuedocode: 15 | void SetConsoleMode(..., DWORD mode) { 16 | ExtendedFlags = (mode & (ENABLE_EXTENDED_FLAGS 17 | | ENABLE_QUICK_EDIT_MODE 18 | | ENABLE_INSERT_MODE )) != 0; 19 | if (ExtendedFlags) { 20 | QuickEdit = (mode & ENABLE_QUICK_EDIT_MODE) != 0; 21 | InsertMode = (mode & ENABLE_INSERT_MODE) != 0; 22 | } 23 | } 24 | 25 | - Setting QuickEdit or InsertMode from the properties dialog GUI does not 26 | affect the ExtendedFlags setting -- it simply toggles the one flag. 27 | 28 | - GetConsoleMode psuedocode: 29 | GetConsoleMode(..., DWORD *result) { 30 | if (ExtendedFlags) { 31 | *result |= ENABLE_EXTENDED_FLAGS; 32 | if (QuickEdit) { *result |= ENABLE_QUICK_EDIT_MODE; } 33 | if (InsertMode) { *result |= ENABLE_INSERT_MODE; } 34 | } 35 | } 36 | 37 | Effectively, the ExtendedFlags flags controls whether the other two flags 38 | are visible/controlled by the user application. If they aren't visible, 39 | though, there is no way for the user application to make them visible, 40 | except by overwriting their values! Calling SetConsoleMode with just 41 | ENABLE_EXTENDED_FLAGS would clear the extended flags we want to read. 42 | 43 | Consequently, if a program temporarily alters the QuickEdit flag (e.g. to 44 | enable mouse input), it cannot restore the original values of the QuickEdit 45 | and InsertMode flags, UNLESS every other console program cooperates by 46 | keeping the ExtendedFlags flag set. 47 | -------------------------------------------------------------------------------- /deps/winpty/misc/Font-Report-June2016/MinimumWindowWidths.txt: -------------------------------------------------------------------------------- 1 | The narrowest allowed console window, in pixels, on a conventional (~96dpi) 2 | monitor: 3 | 4 | (mode con: cols=40 lines=40) && SetFont.exe -face "Lucida Console" -h 1 && (ping -n 4 127.0.0.1 > NUL) && cls && GetConsolePos.exe && SetFont.exe -face "Lucida Console" -h 12 5 | 6 | (mode con: cols=40 lines=40) && SetFont.exe -face "Lucida Console" -h 16 && (ping -n 4 127.0.0.1 > NUL) && cls && GetConsolePos.exe && SetFont.exe -face "Lucida Console" -h 12 7 | 8 | sz1:px sz1:col sz16:px sz16:col 9 | Vista: 124 104 137 10 10 | Windows 7: 132 112 147 11 11 | Windows 8: 140 120 147 11 12 | Windows 8.1: 140 120 147 11 13 | Windows 10 OLD: 136 116 147 11 14 | Windows 10 NEW: 136 103 136 10 15 | 16 | I used build 14342 to test Windows 10. 17 | -------------------------------------------------------------------------------- /deps/winpty/misc/Font-Report-June2016/Results.txt: -------------------------------------------------------------------------------- 1 | As before, avoid odd sizes in favor of even sizes. 2 | 3 | It's curious that the Japanese font is handled so poorly, especially with 4 | Windows 8 and later. 5 | -------------------------------------------------------------------------------- /deps/winpty/misc/FormatChar.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | static inline void formatChar(char *str, char ch) 6 | { 7 | // Print some common control codes. 8 | switch (ch) { 9 | case '\r': strcpy(str, "CR "); break; 10 | case '\n': strcpy(str, "LF "); break; 11 | case ' ': strcpy(str, "SP "); break; 12 | case 27: strcpy(str, "^[ "); break; 13 | case 3: strcpy(str, "^C "); break; 14 | default: 15 | if (isgraph(ch)) 16 | sprintf(str, "%c ", ch); 17 | else 18 | sprintf(str, "%02x ", ch); 19 | break; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /deps/winpty/misc/FreezePerfTest.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "TestUtil.cc" 4 | 5 | const int SC_CONSOLE_MARK = 0xFFF2; 6 | const int SC_CONSOLE_SELECT_ALL = 0xFFF5; 7 | 8 | int main(int argc, char *argv[0]) { 9 | 10 | if (argc != 2) { 11 | printf("Usage: %s (mark|selectall|read)\n", argv[0]); 12 | return 1; 13 | } 14 | 15 | enum class Test { Mark, SelectAll, Read } test; 16 | if (!strcmp(argv[1], "mark")) { 17 | test = Test::Mark; 18 | } else if (!strcmp(argv[1], "selectall")) { 19 | test = Test::SelectAll; 20 | } else if (!strcmp(argv[1], "read")) { 21 | test = Test::Read; 22 | } else { 23 | printf("Invalid test: %s\n", argv[1]); 24 | return 1; 25 | } 26 | 27 | HANDLE conout = GetStdHandle(STD_OUTPUT_HANDLE); 28 | TimeMeasurement tm; 29 | HWND hwnd = GetConsoleWindow(); 30 | 31 | setWindowPos(0, 0, 1, 1); 32 | setBufferSize(100, 3000); 33 | system("cls"); 34 | setWindowPos(0, 2975, 100, 25); 35 | setCursorPos(0, 2999); 36 | 37 | ShowWindow(hwnd, SW_HIDE); 38 | 39 | for (int i = 0; i < 1000; ++i) { 40 | // CONSOLE_SCREEN_BUFFER_INFO info = {}; 41 | // GetConsoleScreenBufferInfo(conout, &info); 42 | 43 | if (test == Test::Mark) { 44 | SendMessage(hwnd, WM_SYSCOMMAND, SC_CONSOLE_MARK, 0); 45 | SendMessage(hwnd, WM_CHAR, 27, 0x00010001); 46 | } else if (test == Test::SelectAll) { 47 | SendMessage(hwnd, WM_SYSCOMMAND, SC_CONSOLE_SELECT_ALL, 0); 48 | SendMessage(hwnd, WM_CHAR, 27, 0x00010001); 49 | } else if (test == Test::Read) { 50 | static CHAR_INFO buffer[100 * 3000]; 51 | const SMALL_RECT readRegion = {0, 0, 99, 2999}; 52 | SMALL_RECT tmp = readRegion; 53 | BOOL ret = ReadConsoleOutput(conout, buffer, {100, 3000}, {0, 0}, &tmp); 54 | ASSERT(ret && !memcmp(&tmp, &readRegion, sizeof(tmp))); 55 | } 56 | } 57 | 58 | ShowWindow(hwnd, SW_SHOW); 59 | 60 | printf("elapsed: %f\n", tm.elapsed()); 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /deps/winpty/misc/GetCh.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() { 6 | printf("\nPress any keys -- Ctrl-D exits\n\n"); 7 | 8 | while (true) { 9 | const int ch = getch(); 10 | printf("0x%x", ch); 11 | if (isgraph(ch)) { 12 | printf(" '%c'", ch); 13 | } 14 | printf("\n"); 15 | if (ch == 0x4) { // Ctrl-D 16 | break; 17 | } 18 | } 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /deps/winpty/misc/GetConsolePos.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include "TestUtil.cc" 6 | 7 | int main() { 8 | const HANDLE conout = openConout(); 9 | 10 | CONSOLE_SCREEN_BUFFER_INFO info = {}; 11 | BOOL ret = GetConsoleScreenBufferInfo(conout, &info); 12 | ASSERT(ret && "GetConsoleScreenBufferInfo failed"); 13 | 14 | trace("cursor=%d,%d", info.dwCursorPosition.X, info.dwCursorPosition.Y); 15 | printf("cursor=%d,%d\n", info.dwCursorPosition.X, info.dwCursorPosition.Y); 16 | 17 | trace("srWindow={L=%d,T=%d,R=%d,B=%d}", info.srWindow.Left, info.srWindow.Top, info.srWindow.Right, info.srWindow.Bottom); 18 | printf("srWindow={L=%d,T=%d,R=%d,B=%d}\n", info.srWindow.Left, info.srWindow.Top, info.srWindow.Right, info.srWindow.Bottom); 19 | 20 | trace("dwSize=%d,%d", info.dwSize.X, info.dwSize.Y); 21 | printf("dwSize=%d,%d\n", info.dwSize.X, info.dwSize.Y); 22 | 23 | const HWND hwnd = GetConsoleWindow(); 24 | if (hwnd != NULL) { 25 | RECT r = {}; 26 | if (GetWindowRect(hwnd, &r)) { 27 | const int w = r.right - r.left; 28 | const int h = r.bottom - r.top; 29 | trace("hwnd: pos=(%d,%d) size=(%d,%d)", r.left, r.top, w, h); 30 | printf("hwnd: pos=(%d,%d) size=(%d,%d)\n", r.left, r.top, w, h); 31 | } else { 32 | trace("GetWindowRect failed"); 33 | printf("GetWindowRect failed\n"); 34 | } 35 | } else { 36 | trace("GetConsoleWindow returned NULL"); 37 | printf("GetConsoleWindow returned NULL\n"); 38 | } 39 | 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /deps/winpty/misc/IdentifyConsoleWindow.ps1: -------------------------------------------------------------------------------- 1 | # 2 | # Usage: powershell \IdentifyConsoleWindow.ps1 3 | # 4 | # This script determines whether the process has a console attached, whether 5 | # that console has a non-NULL window (e.g. HWND), and whether the window is on 6 | # the current window station. 7 | # 8 | 9 | $signature = @' 10 | [DllImport("kernel32.dll", SetLastError=true)] 11 | public static extern IntPtr GetConsoleWindow(); 12 | 13 | [DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)] 14 | public static extern bool SetConsoleTitle(String title); 15 | 16 | [DllImport("user32.dll", CharSet=CharSet.Auto, SetLastError=true)] 17 | public static extern int GetWindowText(IntPtr hWnd, 18 | System.Text.StringBuilder lpString, 19 | int nMaxCount); 20 | '@ 21 | 22 | $WinAPI = Add-Type -MemberDefinition $signature ` 23 | -Name WinAPI -Namespace IdentifyConsoleWindow -PassThru 24 | 25 | if (!$WinAPI::SetConsoleTitle("ConsoleWindowScript")) { 26 | echo "error: could not change console title -- is a console attached?" 27 | exit 1 28 | } else { 29 | echo "note: successfully set console title to ""ConsoleWindowScript""." 30 | } 31 | 32 | $hwnd = $WinAPI::GetConsoleWindow() 33 | if ($hwnd -eq 0) { 34 | echo "note: GetConsoleWindow returned NULL." 35 | } else { 36 | echo "note: GetConsoleWindow returned 0x$($hwnd.ToString("X"))." 37 | $sb = New-Object System.Text.StringBuilder -ArgumentList 4096 38 | if ($WinAPI::GetWindowText($hwnd, $sb, $sb.Capacity)) { 39 | $title = $sb.ToString() 40 | echo "note: GetWindowText returned ""${title}""." 41 | if ($title -eq "ConsoleWindowScript") { 42 | echo "success!" 43 | } else { 44 | echo "error: expected to see ""ConsoleWindowScript""." 45 | echo " (Perhaps the console window is on a different window station?)" 46 | } 47 | } else { 48 | echo "error: GetWindowText could not read the window title." 49 | echo " (Perhaps the console window is on a different window station?)" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /deps/winpty/misc/MoveConsoleWindow.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "TestUtil.cc" 4 | 5 | int main(int argc, char *argv[]) { 6 | if (argc != 3 && argc != 5) { 7 | printf("Usage: %s x y\n", argv[0]); 8 | printf("Usage: %s x y width height\n", argv[0]); 9 | return 1; 10 | } 11 | 12 | HWND hwnd = GetConsoleWindow(); 13 | 14 | const int x = atoi(argv[1]); 15 | const int y = atoi(argv[2]); 16 | 17 | int w = 0, h = 0; 18 | if (argc == 3) { 19 | RECT r = {}; 20 | BOOL ret = GetWindowRect(hwnd, &r); 21 | ASSERT(ret && "GetWindowRect failed on console window"); 22 | w = r.right - r.left; 23 | h = r.bottom - r.top; 24 | } else { 25 | w = atoi(argv[3]); 26 | h = atoi(argv[4]); 27 | } 28 | 29 | BOOL ret = MoveWindow(hwnd, x, y, w, h, TRUE); 30 | trace("MoveWindow: ret=%d", ret); 31 | printf("MoveWindow: ret=%d\n", ret); 32 | 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /deps/winpty/misc/OSVersion.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | int main() { 10 | setlocale(LC_ALL, ""); 11 | 12 | OSVERSIONINFOEXW info = {0}; 13 | info.dwOSVersionInfoSize = sizeof(info); 14 | assert(GetVersionExW((OSVERSIONINFOW*)&info)); 15 | 16 | printf("dwMajorVersion = %d\n", (int)info.dwMajorVersion); 17 | printf("dwMinorVersion = %d\n", (int)info.dwMinorVersion); 18 | printf("dwBuildNumber = %d\n", (int)info.dwBuildNumber); 19 | printf("dwPlatformId = %d\n", (int)info.dwPlatformId); 20 | printf("szCSDVersion = %ls\n", info.szCSDVersion); 21 | printf("wServicePackMajor = %d\n", info.wServicePackMajor); 22 | printf("wServicePackMinor = %d\n", info.wServicePackMinor); 23 | printf("wSuiteMask = 0x%x\n", (unsigned int)info.wSuiteMask); 24 | printf("wProductType = 0x%x\n", (unsigned int)info.wProductType); 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /deps/winpty/misc/ScreenBufferFreezeInactive.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Verify that console selection blocks writes to an inactive console screen 3 | // buffer. Writes TEST PASSED or TEST FAILED to the popup console window. 4 | // 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | #include "TestUtil.cc" 12 | 13 | const int SC_CONSOLE_MARK = 0xFFF2; 14 | const int SC_CONSOLE_SELECT_ALL = 0xFFF5; 15 | 16 | bool g_useMark = false; 17 | 18 | CALLBACK DWORD pausingThread(LPVOID dummy) 19 | { 20 | HWND hwnd = GetConsoleWindow(); 21 | trace("Sending selection to freeze"); 22 | SendMessage(hwnd, WM_SYSCOMMAND, 23 | g_useMark ? SC_CONSOLE_MARK : 24 | SC_CONSOLE_SELECT_ALL, 25 | 0); 26 | Sleep(1000); 27 | trace("Sending escape WM_CHAR to unfreeze"); 28 | SendMessage(hwnd, WM_CHAR, 27, 0x00010001); 29 | Sleep(1000); 30 | } 31 | 32 | static HANDLE createBuffer() { 33 | HANDLE buf = CreateConsoleScreenBuffer( 34 | GENERIC_READ | GENERIC_WRITE, 35 | FILE_SHARE_READ | FILE_SHARE_WRITE, 36 | NULL, 37 | CONSOLE_TEXTMODE_BUFFER, 38 | NULL); 39 | ASSERT(buf != INVALID_HANDLE_VALUE); 40 | return buf; 41 | } 42 | 43 | static void runTest(bool useMark, bool createEarly) { 44 | trace("======================================="); 45 | trace("useMark=%d createEarly=%d", useMark, createEarly); 46 | g_useMark = useMark; 47 | HANDLE buf = INVALID_HANDLE_VALUE; 48 | 49 | if (createEarly) { 50 | buf = createBuffer(); 51 | } 52 | 53 | CreateThread(NULL, 0, 54 | pausingThread, NULL, 55 | 0, NULL); 56 | Sleep(500); 57 | 58 | if (!createEarly) { 59 | trace("Creating buffer"); 60 | TimeMeasurement tm1; 61 | buf = createBuffer(); 62 | const double elapsed1 = tm1.elapsed(); 63 | if (elapsed1 >= 0.250) { 64 | printf("!!! TEST FAILED !!!\n"); 65 | Sleep(2000); 66 | return; 67 | } 68 | } 69 | 70 | trace("Writing to aux buffer"); 71 | TimeMeasurement tm2; 72 | DWORD actual = 0; 73 | BOOL ret = WriteConsoleW(buf, L"HI", 2, &actual, NULL); 74 | const double elapsed2 = tm2.elapsed(); 75 | trace("Writing to aux buffer: finished: ret=%d actual=%d (elapsed=%1.3f)", ret, actual, elapsed2); 76 | if (elapsed2 < 0.250) { 77 | printf("!!! TEST FAILED !!!\n"); 78 | } else { 79 | printf("TEST PASSED\n"); 80 | } 81 | Sleep(2000); 82 | } 83 | 84 | int main(int argc, char **argv) { 85 | if (argc == 1) { 86 | startChildProcess(L"child"); 87 | return 0; 88 | } 89 | 90 | std::string arg = argv[1]; 91 | if (arg == "child") { 92 | for (int useMark = 0; useMark <= 1; useMark++) { 93 | for (int createEarly = 0; createEarly <= 1; createEarly++) { 94 | runTest(useMark, createEarly); 95 | } 96 | } 97 | printf("done...\n"); 98 | Sleep(1000); 99 | } 100 | return 0; 101 | } 102 | -------------------------------------------------------------------------------- /deps/winpty/misc/SelectAllTest.cc: -------------------------------------------------------------------------------- 1 | #define _WIN32_WINNT 0x0501 2 | #include 3 | #include 4 | 5 | #include "../src/shared/DebugClient.cc" 6 | 7 | const int SC_CONSOLE_MARK = 0xFFF2; 8 | const int SC_CONSOLE_SELECT_ALL = 0xFFF5; 9 | 10 | CALLBACK DWORD pausingThread(LPVOID dummy) 11 | { 12 | HWND hwnd = GetConsoleWindow(); 13 | while (true) { 14 | SendMessage(hwnd, WM_SYSCOMMAND, SC_CONSOLE_SELECT_ALL, 0); 15 | Sleep(1000); 16 | SendMessage(hwnd, WM_CHAR, 27, 0x00010001); 17 | Sleep(1000); 18 | } 19 | } 20 | 21 | int main() 22 | { 23 | HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE); 24 | CONSOLE_SCREEN_BUFFER_INFO info; 25 | 26 | GetConsoleScreenBufferInfo(out, &info); 27 | COORD initial = info.dwCursorPosition; 28 | 29 | CreateThread(NULL, 0, 30 | pausingThread, NULL, 31 | 0, NULL); 32 | 33 | for (int i = 0; i < 30; ++i) { 34 | Sleep(100); 35 | GetConsoleScreenBufferInfo(out, &info); 36 | if (memcmp(&info.dwCursorPosition, &initial, sizeof(COORD)) != 0) { 37 | trace("cursor moved to [%d,%d]", 38 | info.dwCursorPosition.X, 39 | info.dwCursorPosition.Y); 40 | } else { 41 | trace("cursor in expected position"); 42 | } 43 | } 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /deps/winpty/misc/SetBufferSize.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | #include "TestUtil.cc" 7 | 8 | int main(int argc, char *argv[]) { 9 | if (argc != 3) { 10 | printf("Usage: %s x y width height\n", argv[0]); 11 | return 1; 12 | } 13 | 14 | const HANDLE conout = CreateFileW(L"CONOUT$", 15 | GENERIC_READ | GENERIC_WRITE, 16 | FILE_SHARE_READ | FILE_SHARE_WRITE, 17 | NULL, OPEN_EXISTING, 0, NULL); 18 | ASSERT(conout != INVALID_HANDLE_VALUE); 19 | 20 | COORD size = { 21 | (short)atoi(argv[1]), 22 | (short)atoi(argv[2]), 23 | }; 24 | 25 | BOOL ret = SetConsoleScreenBufferSize(conout, size); 26 | const unsigned lastError = GetLastError(); 27 | const char *const retStr = ret ? "OK" : "failed"; 28 | trace("SetConsoleScreenBufferSize ret: %s (LastError=0x%x)", retStr, lastError); 29 | printf("SetConsoleScreenBufferSize ret: %s (LastError=0x%x)\n", retStr, lastError); 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /deps/winpty/misc/SetCursorPos.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "TestUtil.cc" 4 | 5 | int main(int argc, char *argv[]) { 6 | int col = atoi(argv[1]); 7 | int row = atoi(argv[2]); 8 | setCursorPos(col, row); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /deps/winpty/misc/SetWindowRect.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | #include "TestUtil.cc" 7 | 8 | int main(int argc, char *argv[]) { 9 | if (argc != 5) { 10 | printf("Usage: %s x y width height\n", argv[0]); 11 | return 1; 12 | } 13 | 14 | const HANDLE conout = CreateFileW(L"CONOUT$", 15 | GENERIC_READ | GENERIC_WRITE, 16 | FILE_SHARE_READ | FILE_SHARE_WRITE, 17 | NULL, OPEN_EXISTING, 0, NULL); 18 | ASSERT(conout != INVALID_HANDLE_VALUE); 19 | 20 | SMALL_RECT sr = { 21 | (short)atoi(argv[1]), 22 | (short)atoi(argv[2]), 23 | (short)(atoi(argv[1]) + atoi(argv[3]) - 1), 24 | (short)(atoi(argv[2]) + atoi(argv[4]) - 1), 25 | }; 26 | 27 | trace("Calling SetConsoleWindowInfo with {L=%d,T=%d,R=%d,B=%d}", 28 | sr.Left, sr.Top, sr.Right, sr.Bottom); 29 | BOOL ret = SetConsoleWindowInfo(conout, TRUE, &sr); 30 | const unsigned lastError = GetLastError(); 31 | const char *const retStr = ret ? "OK" : "failed"; 32 | trace("SetConsoleWindowInfo ret: %s (LastError=0x%x)", retStr, lastError); 33 | printf("SetConsoleWindowInfo ret: %s (LastError=0x%x)\n", retStr, lastError); 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /deps/winpty/misc/ShowArgv.cc: -------------------------------------------------------------------------------- 1 | // This test program is useful for studying commandline<->argv conversion. 2 | 3 | #include 4 | #include 5 | 6 | int main(int argc, char **argv) 7 | { 8 | printf("cmdline = [%s]\n", GetCommandLine()); 9 | for (int i = 0; i < argc; ++i) 10 | printf("[%s]\n", argv[i]); 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /deps/winpty/misc/ShowConsoleInput.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | static int escCount = 0; 8 | 9 | HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); 10 | while (true) { 11 | DWORD count; 12 | INPUT_RECORD ir; 13 | if (!ReadConsoleInput(hStdin, &ir, 1, &count)) { 14 | printf("ReadConsoleInput failed\n"); 15 | return 1; 16 | } 17 | 18 | if (true) { 19 | DWORD mode; 20 | GetConsoleMode(hStdin, &mode); 21 | SetConsoleMode(hStdin, mode & ~ENABLE_PROCESSED_INPUT); 22 | } 23 | 24 | if (ir.EventType == KEY_EVENT) { 25 | const KEY_EVENT_RECORD &ker = ir.Event.KeyEvent; 26 | printf("%s", ker.bKeyDown ? "dn" : "up"); 27 | printf(" ch="); 28 | if (isprint(ker.uChar.AsciiChar)) 29 | printf("'%c'", ker.uChar.AsciiChar); 30 | printf("%d", ker.uChar.AsciiChar); 31 | printf(" vk=%#x", ker.wVirtualKeyCode); 32 | printf(" scan=%#x", ker.wVirtualScanCode); 33 | printf(" state=%#x", (int)ker.dwControlKeyState); 34 | printf(" repeat=%d", ker.wRepeatCount); 35 | printf("\n"); 36 | if (ker.uChar.AsciiChar == 27 && ++escCount == 6) 37 | break; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /deps/winpty/misc/Spew.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | i = 0; 3 | while True: 4 | i += 1 5 | print(i) 6 | -------------------------------------------------------------------------------- /deps/winpty/misc/UnixEcho.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Unix test code that puts the terminal into raw mode, then echos typed 3 | * characters to stdout. Derived from sample code in the Stevens book, posted 4 | * online at http://www.lafn.org/~dave/linux/terminalIO.html. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "FormatChar.h" 12 | 13 | static struct termios save_termios; 14 | static int term_saved; 15 | 16 | /* RAW! mode */ 17 | int tty_raw(int fd) 18 | { 19 | struct termios buf; 20 | 21 | if (tcgetattr(fd, &save_termios) < 0) /* get the original state */ 22 | return -1; 23 | 24 | buf = save_termios; 25 | 26 | /* echo off, canonical mode off, extended input 27 | processing off, signal chars off */ 28 | buf.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG); 29 | 30 | /* no SIGINT on BREAK, CR-to-NL off, input parity 31 | check off, don't strip the 8th bit on input, 32 | ouput flow control off */ 33 | buf.c_iflag &= ~(BRKINT | ICRNL | ISTRIP | IXON); 34 | 35 | /* clear size bits, parity checking off */ 36 | buf.c_cflag &= ~(CSIZE | PARENB); 37 | 38 | /* set 8 bits/char */ 39 | buf.c_cflag |= CS8; 40 | 41 | /* output processing off */ 42 | buf.c_oflag &= ~(OPOST); 43 | 44 | buf.c_cc[VMIN] = 1; /* 1 byte at a time */ 45 | buf.c_cc[VTIME] = 0; /* no timer on input */ 46 | 47 | if (tcsetattr(fd, TCSAFLUSH, &buf) < 0) 48 | return -1; 49 | 50 | term_saved = 1; 51 | 52 | return 0; 53 | } 54 | 55 | 56 | /* set it to normal! */ 57 | int tty_reset(int fd) 58 | { 59 | if (term_saved) 60 | if (tcsetattr(fd, TCSAFLUSH, &save_termios) < 0) 61 | return -1; 62 | 63 | return 0; 64 | } 65 | 66 | 67 | int main() 68 | { 69 | tty_raw(0); 70 | 71 | int count = 0; 72 | while (true) { 73 | char ch; 74 | char buf[16]; 75 | int actual = read(0, &ch, 1); 76 | if (actual != 1) { 77 | perror("read error"); 78 | break; 79 | } 80 | formatChar(buf, ch); 81 | fputs(buf, stdout); 82 | fflush(stdout); 83 | if (ch == 3) // Ctrl-C 84 | break; 85 | } 86 | 87 | tty_reset(0); 88 | return 0; 89 | } 90 | -------------------------------------------------------------------------------- /deps/winpty/misc/Utf16Echo.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | int main(int argc, char *argv[]) { 10 | system("cls"); 11 | 12 | if (argc == 1) { 13 | printf("Usage: %s hhhh\n", argv[0]); 14 | return 0; 15 | } 16 | 17 | std::wstring dataToWrite; 18 | for (int i = 1; i < argc; ++i) { 19 | wchar_t ch = strtol(argv[i], NULL, 16); 20 | dataToWrite.push_back(ch); 21 | } 22 | 23 | DWORD actual = 0; 24 | BOOL ret = WriteConsoleW( 25 | GetStdHandle(STD_OUTPUT_HANDLE), 26 | dataToWrite.data(), dataToWrite.size(), &actual, NULL); 27 | assert(ret && actual == dataToWrite.size()); 28 | 29 | // Read it back. 30 | std::vector readBuffer(dataToWrite.size() * 2); 31 | COORD bufSize = {static_cast(readBuffer.size()), 1}; 32 | COORD bufCoord = {0, 0}; 33 | SMALL_RECT topLeft = {0, 0, static_cast(readBuffer.size() - 1), 0}; 34 | ret = ReadConsoleOutputW( 35 | GetStdHandle(STD_OUTPUT_HANDLE), readBuffer.data(), 36 | bufSize, bufCoord, &topLeft); 37 | assert(ret); 38 | 39 | printf("\n"); 40 | for (int i = 0; i < readBuffer.size(); ++i) { 41 | printf("CHAR: %04x %04x\n", 42 | readBuffer[i].Char.UnicodeChar, 43 | readBuffer[i].Attributes); 44 | } 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /deps/winpty/misc/VkEscapeTest.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Sending VK_PAUSE to the console window almost works as a mechanism for 3 | * pausing it, but it doesn't because the console could turn off the 4 | * ENABLE_LINE_INPUT console mode flag. 5 | */ 6 | 7 | #define _WIN32_WINNT 0x0501 8 | #include 9 | #include 10 | #include 11 | 12 | CALLBACK DWORD pausingThread(LPVOID dummy) 13 | { 14 | if (1) { 15 | Sleep(1000); 16 | HWND hwnd = GetConsoleWindow(); 17 | SendMessage(hwnd, WM_KEYDOWN, VK_PAUSE, 1); 18 | Sleep(1000); 19 | SendMessage(hwnd, WM_KEYDOWN, VK_ESCAPE, 1); 20 | } 21 | 22 | if (0) { 23 | INPUT_RECORD ir; 24 | memset(&ir, 0, sizeof(ir)); 25 | ir.EventType = KEY_EVENT; 26 | ir.Event.KeyEvent.bKeyDown = TRUE; 27 | ir.Event.KeyEvent.wVirtualKeyCode = VK_PAUSE; 28 | ir.Event.KeyEvent.wRepeatCount = 1; 29 | } 30 | 31 | return 0; 32 | } 33 | 34 | int main() 35 | { 36 | HANDLE hin = GetStdHandle(STD_INPUT_HANDLE); 37 | HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); 38 | COORD c = { 0, 0 }; 39 | 40 | DWORD mode; 41 | GetConsoleMode(hin, &mode); 42 | SetConsoleMode(hin, mode & 43 | ~(ENABLE_LINE_INPUT)); 44 | 45 | CreateThread(NULL, 0, 46 | pausingThread, NULL, 47 | 0, NULL); 48 | 49 | int i = 0; 50 | while (true) { 51 | Sleep(100); 52 | printf("%d\n", ++i); 53 | } 54 | 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /deps/winpty/misc/Win10ResizeWhileFrozen.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Demonstrates a conhost hang that occurs when widening the console buffer 3 | * while selection is in progress. The problem affects the new Windows 10 4 | * console, not the "legacy" console mode that Windows 10 also includes. 5 | * 6 | * First tested with: 7 | * - Windows 10.0.10240 8 | * - conhost.exe version 10.0.10240.16384 9 | * - ConhostV1.dll version 10.0.10240.16384 10 | * - ConhostV2.dll version 10.0.10240.16391 11 | */ 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include "TestUtil.cc" 19 | 20 | const int SC_CONSOLE_MARK = 0xFFF2; 21 | const int SC_CONSOLE_SELECT_ALL = 0xFFF5; 22 | 23 | int main(int argc, char *argv[]) { 24 | if (argc == 1) { 25 | startChildProcess(L"CHILD"); 26 | return 0; 27 | } 28 | 29 | setWindowPos(0, 0, 1, 1); 30 | setBufferSize(80, 25); 31 | setWindowPos(0, 0, 80, 25); 32 | 33 | countDown(5); 34 | 35 | SendMessage(GetConsoleWindow(), WM_SYSCOMMAND, SC_CONSOLE_SELECT_ALL, 0); 36 | Sleep(2000); 37 | 38 | // This API call does not return. In the console window, the "Select All" 39 | // operation appears to end. The console window becomes non-responsive, 40 | // and the conhost.exe process must be killed from the Task Manager. 41 | // (Killing this test program or closing the console window is not 42 | // sufficient.) 43 | // 44 | // The same hang occurs whether line resizing is off or on. It happens 45 | // with both "Mark" and "Select All". Calling setBufferSize with the 46 | // existing buffer size does not hang, but calling it with only a changed 47 | // buffer height *does* hang. Calling setWindowPos does not hang. 48 | setBufferSize(120, 25); 49 | 50 | printf("Done...\n"); 51 | Sleep(2000); 52 | } 53 | -------------------------------------------------------------------------------- /deps/winpty/misc/Win10WrapTest1.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Demonstrates some wrapping behaviors of the new Windows 10 console. 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include "TestUtil.cc" 10 | 11 | int main(int argc, char *argv[]) { 12 | if (argc == 1) { 13 | startChildProcess(L"CHILD"); 14 | return 0; 15 | } 16 | 17 | setWindowPos(0, 0, 1, 1); 18 | setBufferSize(40, 20); 19 | setWindowPos(0, 0, 40, 20); 20 | 21 | system("cls"); 22 | 23 | repeatChar(39, 'A'); repeatChar(1, ' '); 24 | repeatChar(39, 'B'); repeatChar(1, ' '); 25 | printf("\n"); 26 | 27 | repeatChar(39, 'C'); repeatChar(1, ' '); 28 | repeatChar(39, 'D'); repeatChar(1, ' '); 29 | printf("\n"); 30 | 31 | repeatChar(40, 'E'); 32 | repeatChar(40, 'F'); 33 | printf("\n"); 34 | 35 | repeatChar(39, 'G'); repeatChar(1, ' '); 36 | repeatChar(39, 'H'); repeatChar(1, ' '); 37 | printf("\n"); 38 | 39 | Sleep(2000); 40 | 41 | setChar(39, 0, '*', 0x24); 42 | setChar(39, 1, '*', 0x24); 43 | 44 | setChar(39, 3, ' ', 0x24); 45 | setChar(39, 4, ' ', 0x24); 46 | 47 | setChar(38, 6, ' ', 0x24); 48 | setChar(38, 7, ' ', 0x24); 49 | 50 | Sleep(2000); 51 | setWindowPos(0, 0, 35, 20); 52 | setBufferSize(35, 20); 53 | trace("DONE"); 54 | 55 | printf("Sleeping forever...\n"); 56 | while(true) { Sleep(1000); } 57 | } 58 | -------------------------------------------------------------------------------- /deps/winpty/misc/Win10WrapTest2.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "TestUtil.cc" 4 | 5 | int main(int argc, char *argv[]) { 6 | if (argc == 1) { 7 | startChildProcess(L"CHILD"); 8 | return 0; 9 | } 10 | 11 | const int WIDTH = 25; 12 | 13 | setWindowPos(0, 0, 1, 1); 14 | setBufferSize(WIDTH, 40); 15 | setWindowPos(0, 0, WIDTH, 20); 16 | 17 | system("cls"); 18 | 19 | for (int i = 0; i < 100; ++i) { 20 | printf("FOO(%d)\n", i); 21 | } 22 | 23 | repeatChar(5, '\n'); 24 | repeatChar(WIDTH * 5, '.'); 25 | repeatChar(10, '\n'); 26 | setWindowPos(0, 20, WIDTH, 20); 27 | writeBox(0, 5, 1, 10, '|'); 28 | 29 | Sleep(120000); 30 | } 31 | -------------------------------------------------------------------------------- /deps/winpty/misc/Win32Echo1.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * A Win32 program that reads raw console input with ReadFile and echos 3 | * it to stdout. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | int main() 11 | { 12 | int count = 0; 13 | HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE); 14 | HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); 15 | SetConsoleMode(hStdIn, 0); 16 | 17 | while (true) { 18 | DWORD actual; 19 | char ch; 20 | ReadFile(hStdIn, &ch, 1, &actual, NULL); 21 | printf("%02x ", ch); 22 | if (++count == 50) 23 | break; 24 | } 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /deps/winpty/misc/Win32Echo2.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * A Win32 program that reads raw console input with getch and echos 3 | * it to stdout. 4 | */ 5 | 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | int count = 0; 12 | while (true) { 13 | int ch = getch(); 14 | printf("%02x ", ch); 15 | if (++count == 50) 16 | break; 17 | } 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /deps/winpty/misc/Win32Test1.cc: -------------------------------------------------------------------------------- 1 | #define _WIN32_WINNT 0x0501 2 | #include "../src/shared/DebugClient.cc" 3 | #include 4 | #include 5 | 6 | const int SC_CONSOLE_MARK = 0xFFF2; 7 | 8 | CALLBACK DWORD writerThread(void*) 9 | { 10 | while (true) { 11 | Sleep(1000); 12 | trace("writing"); 13 | printf("X\n"); 14 | trace("written"); 15 | } 16 | } 17 | 18 | int main() 19 | { 20 | CreateThread(NULL, 0, writerThread, NULL, 0, NULL); 21 | trace("marking console"); 22 | HWND hwnd = GetConsoleWindow(); 23 | PostMessage(hwnd, WM_SYSCOMMAND, SC_CONSOLE_MARK, 0); 24 | 25 | Sleep(2000); 26 | 27 | trace("reading output"); 28 | CHAR_INFO buf[1]; 29 | COORD bufSize = { 1, 1 }; 30 | COORD zeroCoord = { 0, 0 }; 31 | SMALL_RECT readRect = { 0, 0, 0, 0 }; 32 | ReadConsoleOutput(GetStdHandle(STD_OUTPUT_HANDLE), 33 | buf, 34 | bufSize, 35 | zeroCoord, 36 | &readRect); 37 | trace("done reading output"); 38 | 39 | Sleep(2000); 40 | 41 | PostMessage(hwnd, WM_CHAR, 27, 0x00010001); 42 | 43 | Sleep(1100); 44 | 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /deps/winpty/misc/Win32Test2.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * This test demonstrates that putting a console into selection mode does not 3 | * block the low-level console APIs, even though it blocks WriteFile. 4 | */ 5 | 6 | #define _WIN32_WINNT 0x0501 7 | #include "../src/shared/DebugClient.cc" 8 | #include 9 | #include 10 | 11 | const int SC_CONSOLE_MARK = 0xFFF2; 12 | 13 | CALLBACK DWORD writerThread(void*) 14 | { 15 | CHAR_INFO xChar, fillChar; 16 | memset(&xChar, 0, sizeof(xChar)); 17 | xChar.Char.AsciiChar = 'X'; 18 | xChar.Attributes = 7; 19 | memset(&fillChar, 0, sizeof(fillChar)); 20 | fillChar.Char.AsciiChar = ' '; 21 | fillChar.Attributes = 7; 22 | COORD oneCoord = { 1, 1 }; 23 | COORD zeroCoord = { 0, 0 }; 24 | 25 | while (true) { 26 | SMALL_RECT writeRegion = { 5, 5, 5, 5 }; 27 | WriteConsoleOutput(GetStdHandle(STD_OUTPUT_HANDLE), 28 | &xChar, oneCoord, 29 | zeroCoord, 30 | &writeRegion); 31 | Sleep(500); 32 | SMALL_RECT scrollRect = { 1, 1, 20, 20 }; 33 | COORD destCoord = { 0, 0 }; 34 | ScrollConsoleScreenBuffer(GetStdHandle(STD_OUTPUT_HANDLE), 35 | &scrollRect, 36 | NULL, 37 | destCoord, 38 | &fillChar); 39 | } 40 | } 41 | 42 | int main() 43 | { 44 | CreateThread(NULL, 0, writerThread, NULL, 0, NULL); 45 | trace("marking console"); 46 | HWND hwnd = GetConsoleWindow(); 47 | PostMessage(hwnd, WM_SYSCOMMAND, SC_CONSOLE_MARK, 0); 48 | 49 | Sleep(2000); 50 | 51 | trace("reading output"); 52 | CHAR_INFO buf[1]; 53 | COORD bufSize = { 1, 1 }; 54 | COORD zeroCoord = { 0, 0 }; 55 | SMALL_RECT readRect = { 0, 0, 0, 0 }; 56 | ReadConsoleOutput(GetStdHandle(STD_OUTPUT_HANDLE), 57 | buf, 58 | bufSize, 59 | zeroCoord, 60 | &readRect); 61 | trace("done reading output"); 62 | 63 | Sleep(2000); 64 | 65 | PostMessage(hwnd, WM_CHAR, 27, 0x00010001); 66 | 67 | Sleep(1100); 68 | 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /deps/winpty/misc/Win32Test3.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Creates a window station and starts a process under it. The new process 3 | * also gets a new console. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | int main() 11 | { 12 | BOOL success; 13 | 14 | SECURITY_ATTRIBUTES sa; 15 | memset(&sa, 0, sizeof(sa)); 16 | sa.bInheritHandle = TRUE; 17 | 18 | HWINSTA originalStation = GetProcessWindowStation(); 19 | printf("originalStation == 0x%x\n", originalStation); 20 | HWINSTA station = CreateWindowStation(NULL, 21 | 0, 22 | WINSTA_ALL_ACCESS, 23 | &sa); 24 | printf("station == 0x%x\n", station); 25 | if (!SetProcessWindowStation(station)) 26 | printf("SetWindowStation failed!\n"); 27 | HDESK desktop = CreateDesktop("Default", NULL, NULL, 28 | /*dwFlags=*/0, GENERIC_ALL, 29 | &sa); 30 | printf("desktop = 0x%x\n", desktop); 31 | 32 | char stationName[256]; 33 | stationName[0] = '\0'; 34 | success = GetUserObjectInformation(station, UOI_NAME, 35 | stationName, sizeof(stationName), 36 | NULL); 37 | printf("stationName = [%s]\n", stationName); 38 | 39 | char startupDesktop[256]; 40 | sprintf(startupDesktop, "%s\\Default", stationName); 41 | 42 | STARTUPINFO sui; 43 | PROCESS_INFORMATION pi; 44 | memset(&sui, 0, sizeof(sui)); 45 | memset(&pi, 0, sizeof(pi)); 46 | sui.cb = sizeof(STARTUPINFO); 47 | sui.lpDesktop = startupDesktop; 48 | 49 | // Start a cmd subprocess, and have it start its own cmd subprocess. 50 | // Both subprocesses will connect to the same non-interactive window 51 | // station. 52 | 53 | const char program[] = "c:\\windows\\system32\\cmd.exe"; 54 | char cmdline[256]; 55 | sprintf(cmdline, "%s /c cmd", program); 56 | success = CreateProcess(program, 57 | cmdline, 58 | NULL, 59 | NULL, 60 | /*bInheritHandles=*/FALSE, 61 | /*dwCreationFlags=*/CREATE_NEW_CONSOLE, 62 | NULL, NULL, 63 | &sui, 64 | &pi); 65 | 66 | printf("pid == %d\n", pi.dwProcessId); 67 | 68 | // This sleep is necessary. We must give the child enough time to 69 | // connect to the specified window station. 70 | Sleep(5000); 71 | 72 | SetProcessWindowStation(originalStation); 73 | CloseWindowStation(station); 74 | CloseDesktop(desktop); 75 | Sleep(5000); 76 | 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /deps/winpty/misc/Win32Write1.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * A Win32 program that scrolls and writes to the console using the ioctl-like 3 | * interface. 4 | */ 5 | 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | HANDLE conout = GetStdHandle(STD_OUTPUT_HANDLE); 12 | 13 | for (int i = 0; i < 80; ++i) { 14 | 15 | CONSOLE_SCREEN_BUFFER_INFO info; 16 | GetConsoleScreenBufferInfo(conout, &info); 17 | 18 | SMALL_RECT src = { 0, 1, info.dwSize.X - 1, info.dwSize.Y - 1 }; 19 | COORD destOrigin = { 0, 0 }; 20 | CHAR_INFO fillCharInfo = { 0 }; 21 | fillCharInfo.Char.AsciiChar = ' '; 22 | fillCharInfo.Attributes = 7; 23 | ScrollConsoleScreenBuffer(conout, 24 | &src, 25 | NULL, 26 | destOrigin, 27 | &fillCharInfo); 28 | 29 | CHAR_INFO buffer = { 0 }; 30 | buffer.Char.AsciiChar = 'X'; 31 | buffer.Attributes = 7; 32 | COORD bufferSize = { 1, 1 }; 33 | COORD bufferCoord = { 0, 0 }; 34 | SMALL_RECT writeRegion = { 0, 0, 0, 0 }; 35 | writeRegion.Left = writeRegion.Right = i; 36 | writeRegion.Top = writeRegion.Bottom = 5; 37 | WriteConsoleOutput(conout, 38 | &buffer, bufferSize, bufferCoord, 39 | &writeRegion); 40 | 41 | Sleep(250); 42 | } 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /deps/winpty/misc/WindowsBugCrashReader.cc: -------------------------------------------------------------------------------- 1 | // I noticed this on the ConEmu web site: 2 | // 3 | // https://social.msdn.microsoft.com/Forums/en-US/40c8e395-cca9-45c8-b9b8-2fbe6782ac2b/readconsoleoutput-cause-access-violation-writing-location-exception 4 | // https://conemu.github.io/en/MicrosoftBugs.html 5 | // 6 | // In Windows 7, 8, and 8.1, a ReadConsoleOutputW with an out-of-bounds read 7 | // region crashes the application. I have reproduced the problem on Windows 8 8 | // and 8.1, but not on Windows 7. 9 | // 10 | 11 | #include 12 | 13 | #include "TestUtil.cc" 14 | 15 | int main() { 16 | setWindowPos(0, 0, 1, 1); 17 | setBufferSize(80, 25); 18 | setWindowPos(0, 0, 80, 25); 19 | 20 | const HANDLE conout = openConout(); 21 | static CHAR_INFO lineBuf[80]; 22 | SMALL_RECT readRegion = { 0, 999, 79, 999 }; 23 | const BOOL ret = ReadConsoleOutputW(conout, lineBuf, {80, 1}, {0, 0}, &readRegion); 24 | ASSERT(!ret && "ReadConsoleOutputW should have failed"); 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /deps/winpty/misc/build32.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | name=$1 4 | name=${name%.} 5 | name=${name%.cc} 6 | name=${name%.exe} 7 | echo Compiling $name.cc to $name.exe 8 | i686-w64-mingw32-g++.exe -static -std=c++11 $name.cc -o $name.exe 9 | i686-w64-mingw32-strip $name.exe 10 | -------------------------------------------------------------------------------- /deps/winpty/misc/build64.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | name=$1 4 | name=${name%.} 5 | name=${name%.cc} 6 | name=${name%.exe} 7 | echo Compiling $name.cc to $name.exe 8 | x86_64-w64-mingw32-g++.exe -static -std=c++11 $name.cc -o $name.exe 9 | x86_64-w64-mingw32-strip $name.exe 10 | -------------------------------------------------------------------------------- /deps/winpty/ship/build-pty4j-libpty.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | setlocal 4 | cd %~dp0.. 5 | set Path=C:\Python27;C:\Program Files\Git\cmd;%Path% 6 | 7 | call "%VS140COMNTOOLS%\VsDevCmd.bat" || goto :fail 8 | 9 | rmdir /s/q build-libpty 2>NUL 10 | mkdir build-libpty\win 11 | mkdir build-libpty\win\x86 12 | mkdir build-libpty\win\x86_64 13 | mkdir build-libpty\win\xp 14 | 15 | rmdir /s/q src\Release 2>NUL 16 | rmdir /s/q src\.vs 2>NUL 17 | del src\*.vcxproj src\*.vcxproj.filters src\*.sln src\*.sdf 2>NUL 18 | 19 | call vcbuild.bat --msvc-platform Win32 --gyp-msvs-version 2015 --toolset v140_xp || goto :fail 20 | copy src\Release\Win32\winpty.dll build-libpty\win\xp || goto :fail 21 | copy src\Release\Win32\winpty-agent.exe build-libpty\win\xp || goto :fail 22 | 23 | call vcbuild.bat --msvc-platform Win32 --gyp-msvs-version 2015 || goto :fail 24 | copy src\Release\Win32\winpty.dll build-libpty\win\x86 || goto :fail 25 | copy src\Release\Win32\winpty-agent.exe build-libpty\win\x86 || goto :fail 26 | 27 | call vcbuild.bat --msvc-platform x64 --gyp-msvs-version 2015 || goto :fail 28 | copy src\Release\x64\winpty.dll build-libpty\win\x86_64 || goto :fail 29 | copy src\Release\x64\winpty-agent.exe build-libpty\win\x86_64 || goto :fail 30 | 31 | echo success 32 | goto :EOF 33 | 34 | :fail 35 | echo error: build failed 36 | exit /b 1 37 | -------------------------------------------------------------------------------- /deps/winpty/ship/common_ship.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | 4 | if os.name != "nt": 5 | sys.exit("Error: ship scripts require native Python 2.7. (wrong os.name)") 6 | if sys.version_info[0:2] != (2,7): 7 | sys.exit("Error: ship scripts require native Python 2.7. (wrong version)") 8 | 9 | import glob 10 | import shutil 11 | import subprocess 12 | from distutils.spawn import find_executable 13 | 14 | topDir = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) 15 | 16 | with open(topDir + "/VERSION.txt", "rt") as f: 17 | winptyVersion = f.read().strip() 18 | 19 | def rmrf(patterns): 20 | for pattern in patterns: 21 | for path in glob.glob(pattern): 22 | if os.path.isdir(path) and not os.path.islink(path): 23 | print "+ rm -r " + path 24 | sys.stdout.flush() 25 | shutil.rmtree(path) 26 | elif os.path.isfile(path): 27 | print "+ rm " + path 28 | sys.stdout.flush() 29 | os.remove(path) 30 | 31 | def mkdir(path): 32 | if not os.path.isdir(path): 33 | os.makedirs(path) 34 | 35 | def requireExe(name, guesses): 36 | if find_executable(name) is None: 37 | for guess in guesses: 38 | if os.path.exists(guess): 39 | newDir = os.path.dirname(guess) 40 | print "Adding " + newDir + " to Path to provide " + name 41 | os.environ["Path"] = newDir + ";" + os.environ["Path"] 42 | ret = find_executable(name) 43 | if ret is None: 44 | sys.exit("Error: required EXE is missing from Path: " + name) 45 | return ret 46 | 47 | requireExe("git.exe", [ 48 | "C:\\Program Files\\Git\\cmd\\git.exe", 49 | "C:\\Program Files (x86)\\Git\\cmd\\git.exe" 50 | ]) 51 | 52 | commitHash = subprocess.check_output(["git.exe", "rev-parse", "HEAD"]).decode().strip() 53 | defaultPathEnviron = "C:\\Windows\\System32;C:\\Windows" 54 | -------------------------------------------------------------------------------- /deps/winpty/src/agent/AgentCreateDesktop.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #include "AgentCreateDesktop.h" 22 | 23 | #include "../shared/BackgroundDesktop.h" 24 | #include "../shared/Buffer.h" 25 | #include "../shared/DebugClient.h" 26 | #include "../shared/StringUtil.h" 27 | 28 | #include "EventLoop.h" 29 | #include "NamedPipe.h" 30 | 31 | namespace { 32 | 33 | static inline WriteBuffer newPacket() { 34 | WriteBuffer packet; 35 | packet.putRawValue(0); // Reserve space for size. 36 | return packet; 37 | } 38 | 39 | class CreateDesktopLoop : public EventLoop { 40 | public: 41 | CreateDesktopLoop(LPCWSTR controlPipeName); 42 | 43 | protected: 44 | virtual void onPipeIo(NamedPipe &namedPipe) override; 45 | 46 | private: 47 | void writePacket(WriteBuffer &packet); 48 | 49 | BackgroundDesktop m_desktop; 50 | NamedPipe &m_pipe; 51 | }; 52 | 53 | CreateDesktopLoop::CreateDesktopLoop(LPCWSTR controlPipeName) : 54 | m_pipe(createNamedPipe()) { 55 | m_pipe.connectToServer(controlPipeName, NamedPipe::OpenMode::Duplex); 56 | auto packet = newPacket(); 57 | packet.putWString(m_desktop.desktopName()); 58 | writePacket(packet); 59 | } 60 | 61 | void CreateDesktopLoop::writePacket(WriteBuffer &packet) { 62 | const auto &bytes = packet.buf(); 63 | packet.replaceRawValue(0, bytes.size()); 64 | m_pipe.write(bytes.data(), bytes.size()); 65 | } 66 | 67 | void CreateDesktopLoop::onPipeIo(NamedPipe &namedPipe) { 68 | if (m_pipe.isClosed()) { 69 | shutdown(); 70 | } 71 | } 72 | 73 | } // anonymous namespace 74 | 75 | void handleCreateDesktop(LPCWSTR controlPipeName) { 76 | try { 77 | CreateDesktopLoop loop(controlPipeName); 78 | loop.run(); 79 | trace("Agent exiting..."); 80 | } catch (const WinptyException &e) { 81 | trace("handleCreateDesktop: internal error: %s", 82 | utf8FromWide(e.what()).c_str()); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /deps/winpty/src/agent/AgentCreateDesktop.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef AGENT_CREATE_DESKTOP_H 22 | #define AGENT_CREATE_DESKTOP_H 23 | 24 | #include 25 | 26 | void handleCreateDesktop(LPCWSTR controlPipeName); 27 | 28 | #endif // AGENT_CREATE_DESKTOP_H 29 | -------------------------------------------------------------------------------- /deps/winpty/src/agent/ConsoleFont.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef CONSOLEFONT_H 22 | #define CONSOLEFONT_H 23 | 24 | #include 25 | 26 | void setSmallFont(HANDLE conout, int columns, bool isNewW10); 27 | 28 | #endif // CONSOLEFONT_H 29 | -------------------------------------------------------------------------------- /deps/winpty/src/agent/ConsoleInputReencoding.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef AGENT_CONSOLE_INPUT_REENCODING_H 22 | #define AGENT_CONSOLE_INPUT_REENCODING_H 23 | 24 | #include 25 | 26 | #include 27 | 28 | #include 29 | 30 | void reencodeEscapedKeyPress( 31 | std::vector &records, 32 | uint16_t virtualKey, 33 | uint32_t codePoint, 34 | uint16_t keyState); 35 | 36 | #endif // AGENT_CONSOLE_INPUT_REENCODING_H 37 | -------------------------------------------------------------------------------- /deps/winpty/src/agent/ConsoleLine.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef CONSOLE_LINE_H 22 | #define CONSOLE_LINE_H 23 | 24 | #include 25 | 26 | #include 27 | 28 | class ConsoleLine 29 | { 30 | public: 31 | ConsoleLine(); 32 | void reset(); 33 | bool detectChangeAndSetLine(const CHAR_INFO *line, int newLength); 34 | void setLine(const CHAR_INFO *line, int newLength); 35 | void blank(WORD attributes); 36 | private: 37 | int m_prevLength; 38 | std::vector m_prevData; 39 | }; 40 | 41 | #endif // CONSOLE_LINE_H 42 | -------------------------------------------------------------------------------- /deps/winpty/src/agent/Coord.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2012 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef COORD_H 22 | #define COORD_H 23 | 24 | #include 25 | 26 | #include 27 | 28 | #include "../shared/winpty_snprintf.h" 29 | 30 | struct Coord : COORD { 31 | Coord() 32 | { 33 | X = 0; 34 | Y = 0; 35 | } 36 | 37 | Coord(SHORT x, SHORT y) 38 | { 39 | X = x; 40 | Y = y; 41 | } 42 | 43 | Coord(COORD other) 44 | { 45 | *(COORD*)this = other; 46 | } 47 | 48 | Coord(const Coord &other) 49 | { 50 | *(COORD*)this = *(const COORD*)&other; 51 | } 52 | 53 | Coord &operator=(const Coord &other) 54 | { 55 | *(COORD*)this = *(const COORD*)&other; 56 | return *this; 57 | } 58 | 59 | bool operator==(const Coord &other) const 60 | { 61 | return X == other.X && Y == other.Y; 62 | } 63 | 64 | bool operator!=(const Coord &other) const 65 | { 66 | return !(*this == other); 67 | } 68 | 69 | Coord operator+(const Coord &other) const 70 | { 71 | return Coord(X + other.X, Y + other.Y); 72 | } 73 | 74 | bool isEmpty() const 75 | { 76 | return X <= 0 || Y <= 0; 77 | } 78 | 79 | std::string toString() const 80 | { 81 | char ret[32]; 82 | winpty_snprintf(ret, "(%d,%d)", X, Y); 83 | return std::string(ret); 84 | } 85 | }; 86 | 87 | #endif // COORD_H 88 | -------------------------------------------------------------------------------- /deps/winpty/src/agent/DebugShowInput.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef AGENT_DEBUG_SHOW_INPUT_H 22 | #define AGENT_DEBUG_SHOW_INPUT_H 23 | 24 | #include 25 | 26 | #include 27 | 28 | std::string controlKeyStatePrefix(DWORD controlKeyState); 29 | std::string mouseEventToString(const MOUSE_EVENT_RECORD &mer); 30 | void debugShowInput(bool enableMouse, bool escapeInput); 31 | 32 | #endif // AGENT_DEBUG_SHOW_INPUT_H 33 | -------------------------------------------------------------------------------- /deps/winpty/src/agent/DefaultInputMap.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef DEFAULT_INPUT_MAP_H 22 | #define DEFAULT_INPUT_MAP_H 23 | 24 | class InputMap; 25 | 26 | void addDefaultEntriesToInputMap(InputMap &inputMap); 27 | 28 | #endif // DEFAULT_INPUT_MAP_H 29 | -------------------------------------------------------------------------------- /deps/winpty/src/agent/DsrSender.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2012 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef DSRSENDER_H 22 | #define DSRSENDER_H 23 | 24 | class DsrSender 25 | { 26 | public: 27 | virtual void sendDsr() = 0; 28 | }; 29 | 30 | #endif // DSRSENDER_H 31 | -------------------------------------------------------------------------------- /deps/winpty/src/agent/EventLoop.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2012 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef EVENTLOOP_H 22 | #define EVENTLOOP_H 23 | 24 | #include 25 | 26 | class NamedPipe; 27 | 28 | class EventLoop 29 | { 30 | public: 31 | virtual ~EventLoop(); 32 | void run(); 33 | 34 | protected: 35 | NamedPipe &createNamedPipe(); 36 | void setPollInterval(int ms); 37 | void shutdown(); 38 | virtual void onPollTimeout() {} 39 | virtual void onPipeIo(NamedPipe &namedPipe) {} 40 | 41 | private: 42 | bool m_exiting = false; 43 | std::vector m_pipes; 44 | int m_pollInterval = 0; 45 | }; 46 | 47 | #endif // EVENTLOOP_H 48 | -------------------------------------------------------------------------------- /deps/winpty/src/agent/LargeConsoleRead.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #include "LargeConsoleRead.h" 22 | 23 | #include 24 | 25 | #include "../shared/WindowsVersion.h" 26 | #include "Scraper.h" 27 | #include "Win32ConsoleBuffer.h" 28 | 29 | LargeConsoleReadBuffer::LargeConsoleReadBuffer() : 30 | m_rect(0, 0, 0, 0), m_rectWidth(0) 31 | { 32 | } 33 | 34 | void largeConsoleRead(LargeConsoleReadBuffer &out, 35 | Win32ConsoleBuffer &buffer, 36 | const SmallRect &readArea, 37 | WORD attributesMask) { 38 | ASSERT(readArea.Left >= 0 && 39 | readArea.Top >= 0 && 40 | readArea.Right >= readArea.Left && 41 | readArea.Bottom >= readArea.Top && 42 | readArea.width() <= MAX_CONSOLE_WIDTH); 43 | const size_t count = readArea.width() * readArea.height(); 44 | if (out.m_data.size() < count) { 45 | out.m_data.resize(count); 46 | } 47 | out.m_rect = readArea; 48 | out.m_rectWidth = readArea.width(); 49 | 50 | static const bool useLargeReads = isAtLeastWindows8(); 51 | if (useLargeReads) { 52 | buffer.read(readArea, out.m_data.data()); 53 | } else { 54 | const int maxReadLines = std::max(1, MAX_CONSOLE_WIDTH / readArea.width()); 55 | int curLine = readArea.Top; 56 | while (curLine <= readArea.Bottom) { 57 | const SmallRect subReadArea( 58 | readArea.Left, 59 | curLine, 60 | readArea.width(), 61 | std::min(maxReadLines, readArea.Bottom + 1 - curLine)); 62 | buffer.read(subReadArea, out.lineDataMut(curLine)); 63 | curLine = subReadArea.Bottom + 1; 64 | } 65 | } 66 | if (attributesMask != static_cast(~0)) { 67 | for (size_t i = 0; i < count; ++i) { 68 | out.m_data[i].Attributes &= attributesMask; 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /deps/winpty/src/agent/LargeConsoleRead.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef LARGE_CONSOLE_READ_H 22 | #define LARGE_CONSOLE_READ_H 23 | 24 | #include 25 | #include 26 | 27 | #include 28 | 29 | #include "SmallRect.h" 30 | #include "../shared/DebugClient.h" 31 | #include "../shared/WinptyAssert.h" 32 | 33 | class Win32ConsoleBuffer; 34 | 35 | class LargeConsoleReadBuffer { 36 | public: 37 | LargeConsoleReadBuffer(); 38 | const SmallRect &rect() const { return m_rect; } 39 | const CHAR_INFO *lineData(int line) const { 40 | validateLineNumber(line); 41 | return &m_data[(line - m_rect.Top) * m_rectWidth]; 42 | } 43 | 44 | private: 45 | CHAR_INFO *lineDataMut(int line) { 46 | validateLineNumber(line); 47 | return &m_data[(line - m_rect.Top) * m_rectWidth]; 48 | } 49 | 50 | void validateLineNumber(int line) const { 51 | if (line < m_rect.Top || line > m_rect.Bottom) { 52 | trace("Fatal error: LargeConsoleReadBuffer: invalid line %d for " 53 | "read rect %s", line, m_rect.toString().c_str()); 54 | abort(); 55 | } 56 | } 57 | 58 | SmallRect m_rect; 59 | int m_rectWidth; 60 | std::vector m_data; 61 | 62 | friend void largeConsoleRead(LargeConsoleReadBuffer &out, 63 | Win32ConsoleBuffer &buffer, 64 | const SmallRect &readArea, 65 | WORD attributesMask); 66 | }; 67 | 68 | #endif // LARGE_CONSOLE_READ_H 69 | -------------------------------------------------------------------------------- /deps/winpty/src/agent/SimplePool.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef SIMPLE_POOL_H 22 | #define SIMPLE_POOL_H 23 | 24 | #include 25 | 26 | #include 27 | 28 | #include "../shared/WinptyAssert.h" 29 | 30 | template 31 | class SimplePool { 32 | public: 33 | ~SimplePool(); 34 | T *alloc(); 35 | void clear(); 36 | private: 37 | struct Chunk { 38 | size_t count; 39 | T *data; 40 | }; 41 | std::vector m_chunks; 42 | }; 43 | 44 | template 45 | SimplePool::~SimplePool() { 46 | clear(); 47 | } 48 | 49 | template 50 | void SimplePool::clear() { 51 | for (size_t ci = 0; ci < m_chunks.size(); ++ci) { 52 | Chunk &chunk = m_chunks[ci]; 53 | for (size_t ti = 0; ti < chunk.count; ++ti) { 54 | chunk.data[ti].~T(); 55 | } 56 | free(chunk.data); 57 | } 58 | m_chunks.clear(); 59 | } 60 | 61 | template 62 | T *SimplePool::alloc() { 63 | if (m_chunks.empty() || m_chunks.back().count == chunkSize) { 64 | T *newData = reinterpret_cast(malloc(sizeof(T) * chunkSize)); 65 | ASSERT(newData != NULL); 66 | Chunk newChunk = { 0, newData }; 67 | m_chunks.push_back(newChunk); 68 | } 69 | Chunk &chunk = m_chunks.back(); 70 | T *ret = &chunk.data[chunk.count++]; 71 | new (ret) T(); 72 | return ret; 73 | } 74 | 75 | #endif // SIMPLE_POOL_H 76 | -------------------------------------------------------------------------------- /deps/winpty/src/agent/Terminal.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef TERMINAL_H 22 | #define TERMINAL_H 23 | 24 | #include 25 | #include 26 | 27 | #include 28 | #include 29 | 30 | #include "Coord.h" 31 | 32 | class NamedPipe; 33 | 34 | class Terminal 35 | { 36 | public: 37 | explicit Terminal(NamedPipe &output, bool plainMode, bool outputColor) 38 | : m_output(output), m_plainMode(plainMode), m_outputColor(outputColor) 39 | { 40 | } 41 | 42 | enum SendClearFlag { OmitClear, SendClear }; 43 | void reset(SendClearFlag sendClearFirst, int64_t newLine); 44 | void sendLine(int64_t line, const CHAR_INFO *lineData, int width, 45 | int cursorColumn); 46 | void showTerminalCursor(int column, int64_t line); 47 | void hideTerminalCursor(); 48 | 49 | private: 50 | void moveTerminalToLine(int64_t line); 51 | 52 | public: 53 | void enableMouseMode(bool enabled); 54 | 55 | private: 56 | NamedPipe &m_output; 57 | int64_t m_remoteLine = 0; 58 | int m_remoteColumn = 0; 59 | bool m_lineDataValid = true; 60 | std::vector m_lineData; 61 | bool m_cursorHidden = false; 62 | int m_remoteColor = -1; 63 | std::string m_termLineWorkingBuffer; 64 | bool m_plainMode = false; 65 | bool m_outputColor = true; 66 | bool m_mouseModeEnabled = false; 67 | }; 68 | 69 | #endif // TERMINAL_H 70 | -------------------------------------------------------------------------------- /deps/winpty/src/agent/Win32Console.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef AGENT_WIN32_CONSOLE_H 22 | #define AGENT_WIN32_CONSOLE_H 23 | 24 | #include 25 | 26 | #include 27 | #include 28 | 29 | class Win32Console 30 | { 31 | public: 32 | class FreezeGuard { 33 | public: 34 | FreezeGuard(Win32Console &console, bool frozen) : 35 | m_console(console), m_previous(console.frozen()) { 36 | m_console.setFrozen(frozen); 37 | } 38 | ~FreezeGuard() { 39 | m_console.setFrozen(m_previous); 40 | } 41 | FreezeGuard(const FreezeGuard &other) = delete; 42 | FreezeGuard &operator=(const FreezeGuard &other) = delete; 43 | private: 44 | Win32Console &m_console; 45 | bool m_previous; 46 | }; 47 | 48 | Win32Console(); 49 | 50 | HWND hwnd() { return m_hwnd; } 51 | std::wstring title(); 52 | void setTitle(const std::wstring &title); 53 | void setFreezeUsesMark(bool useMark) { m_freezeUsesMark = useMark; } 54 | void setNewW10(bool isNewW10) { m_isNewW10 = isNewW10; } 55 | bool isNewW10() { return m_isNewW10; } 56 | void setFrozen(bool frozen=true); 57 | bool frozen() { return m_frozen; } 58 | 59 | private: 60 | HWND m_hwnd = nullptr; 61 | bool m_frozen = false; 62 | bool m_freezeUsesMark = false; 63 | bool m_isNewW10 = false; 64 | std::vector m_titleWorkBuf; 65 | }; 66 | 67 | #endif // AGENT_WIN32_CONSOLE_H 68 | -------------------------------------------------------------------------------- /deps/winpty/src/agent/subdir.mk: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2011-2015 Ryan Prichard 2 | # 3 | # Permission is hereby granted, free of charge, to any person obtaining a copy 4 | # of this software and associated documentation files (the "Software"), to 5 | # deal in the Software without restriction, including without limitation the 6 | # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | # sell copies of the Software, and to permit persons to whom the Software is 8 | # furnished to do so, subject to the following conditions: 9 | # 10 | # The above copyright notice and this permission notice shall be included in 11 | # all copies or substantial portions of the Software. 12 | # 13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | # IN THE SOFTWARE. 20 | 21 | ALL_TARGETS += build/winpty-agent.exe 22 | 23 | $(eval $(call def_mingw_target,agent,-DWINPTY_AGENT_ASSERT)) 24 | 25 | AGENT_OBJECTS = \ 26 | build/agent/agent/Agent.o \ 27 | build/agent/agent/AgentCreateDesktop.o \ 28 | build/agent/agent/ConsoleFont.o \ 29 | build/agent/agent/ConsoleInput.o \ 30 | build/agent/agent/ConsoleInputReencoding.o \ 31 | build/agent/agent/ConsoleLine.o \ 32 | build/agent/agent/DebugShowInput.o \ 33 | build/agent/agent/DefaultInputMap.o \ 34 | build/agent/agent/EventLoop.o \ 35 | build/agent/agent/InputMap.o \ 36 | build/agent/agent/LargeConsoleRead.o \ 37 | build/agent/agent/NamedPipe.o \ 38 | build/agent/agent/Scraper.o \ 39 | build/agent/agent/Terminal.o \ 40 | build/agent/agent/Win32Console.o \ 41 | build/agent/agent/Win32ConsoleBuffer.o \ 42 | build/agent/agent/main.o \ 43 | build/agent/shared/BackgroundDesktop.o \ 44 | build/agent/shared/Buffer.o \ 45 | build/agent/shared/DebugClient.o \ 46 | build/agent/shared/GenRandom.o \ 47 | build/agent/shared/OwnedHandle.o \ 48 | build/agent/shared/StringUtil.o \ 49 | build/agent/shared/WindowsSecurity.o \ 50 | build/agent/shared/WindowsVersion.o \ 51 | build/agent/shared/WinptyAssert.o \ 52 | build/agent/shared/WinptyException.o \ 53 | build/agent/shared/WinptyVersion.o 54 | 55 | build/agent/shared/WinptyVersion.o : build/gen/GenVersion.h 56 | 57 | build/winpty-agent.exe : $(AGENT_OBJECTS) 58 | $(info Linking $@) 59 | @$(MINGW_CXX) $(MINGW_LDFLAGS) -o $@ $^ 60 | 61 | -include $(AGENT_OBJECTS:.o=.d) 62 | -------------------------------------------------------------------------------- /deps/winpty/src/configurations.gypi: -------------------------------------------------------------------------------- 1 | # By default gyp/msbuild build for 32-bit Windows. This gyp include file 2 | # defines configurations for both 32-bit and 64-bit Windows. To use it, run: 3 | # 4 | # C:\...\winpty\src>gyp -I configurations.gypi 5 | # 6 | # This command generates Visual Studio project files with a Release 7 | # configuration and two Platforms--Win32 and x64. Both can be built: 8 | # 9 | # C:\...\winpty\src>msbuild winpty.sln /p:Platform=Win32 10 | # C:\...\winpty\src>msbuild winpty.sln /p:Platform=x64 11 | # 12 | # The output is placed in: 13 | # 14 | # C:\...\winpty\src\Release\Win32 15 | # C:\...\winpty\src\Release\x64 16 | # 17 | # Windows XP note: By default, the project files will use the default "toolset" 18 | # for the given MSVC version. For MSVC 2013 and MSVC 2015, the default toolset 19 | # generates binaries that do not run on Windows XP. To target Windows XP, 20 | # select the XP-specific toolset by passing 21 | # -D WINPTY_MSBUILD_TOOLSET={v120_xp,v140_xp} to gyp (v120_xp == MSVC 2013, 22 | # v140_xp == MSVC 2015). Unfortunately, it isn't possible to have a single 23 | # project file with configurations for both XP and post-XP. This seems to be a 24 | # limitation of the MSVC project file format. 25 | # 26 | # This file is not included by default, because I suspect it would interfere 27 | # with node-gyp, which has a different system for building 32-vs-64-bit 28 | # binaries. It uses a common.gypi, and the project files it generates can only 29 | # build a single architecture, the output paths are not differentiated by 30 | # architecture. 31 | 32 | { 33 | 'variables': { 34 | 'WINPTY_MSBUILD_TOOLSET%': '', 35 | }, 36 | 'target_defaults': { 37 | 'default_configuration': 'Release_Win32', 38 | 'configurations': { 39 | 'Release_Win32': { 40 | 'msvs_configuration_platform': 'Win32', 41 | }, 42 | 'Release_x64': { 43 | 'msvs_configuration_platform': 'x64', 44 | }, 45 | }, 46 | 'msvs_configuration_attributes': { 47 | 'OutputDirectory': '$(SolutionDir)$(ConfigurationName)\\$(Platform)', 48 | 'IntermediateDirectory': '$(ConfigurationName)\\$(Platform)\\obj\\$(ProjectName)', 49 | }, 50 | 'msvs_settings': { 51 | 'VCLinkerTool': { 52 | 'SubSystem': '1', # /SUBSYSTEM:CONSOLE 53 | }, 54 | 'VCCLCompilerTool': { 55 | 'RuntimeLibrary': '0', # MultiThreaded (/MT) 56 | }, 57 | }, 58 | 'msbuild_toolset' : '<(WINPTY_MSBUILD_TOOLSET)', 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /deps/winpty/src/debugserver/subdir.mk: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 Ryan Prichard 2 | # 3 | # Permission is hereby granted, free of charge, to any person obtaining a copy 4 | # of this software and associated documentation files (the "Software"), to 5 | # deal in the Software without restriction, including without limitation the 6 | # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | # sell copies of the Software, and to permit persons to whom the Software is 8 | # furnished to do so, subject to the following conditions: 9 | # 10 | # The above copyright notice and this permission notice shall be included in 11 | # all copies or substantial portions of the Software. 12 | # 13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | # IN THE SOFTWARE. 20 | 21 | ALL_TARGETS += build/winpty-debugserver.exe 22 | 23 | $(eval $(call def_mingw_target,debugserver,)) 24 | 25 | DEBUGSERVER_OBJECTS = \ 26 | build/debugserver/debugserver/DebugServer.o \ 27 | build/debugserver/shared/DebugClient.o \ 28 | build/debugserver/shared/OwnedHandle.o \ 29 | build/debugserver/shared/StringUtil.o \ 30 | build/debugserver/shared/WindowsSecurity.o \ 31 | build/debugserver/shared/WindowsVersion.o \ 32 | build/debugserver/shared/WinptyAssert.o \ 33 | build/debugserver/shared/WinptyException.o 34 | 35 | build/debugserver/shared/WindowsVersion.o : build/gen/GenVersion.h 36 | 37 | build/winpty-debugserver.exe : $(DEBUGSERVER_OBJECTS) 38 | $(info Linking $@) 39 | @$(MINGW_CXX) $(MINGW_LDFLAGS) -o $@ $^ 40 | 41 | -include $(DEBUGSERVER_OBJECTS:.o=.d) 42 | -------------------------------------------------------------------------------- /deps/winpty/src/libwinpty/AgentLocation.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #include "AgentLocation.h" 22 | 23 | #include 24 | 25 | #include 26 | 27 | #include "../shared/WinptyAssert.h" 28 | 29 | #include "LibWinptyException.h" 30 | 31 | #define AGENT_EXE L"winpty-agent.exe" 32 | 33 | static HMODULE getCurrentModule() { 34 | HMODULE module; 35 | if (!GetModuleHandleExW( 36 | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | 37 | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, 38 | reinterpret_cast(getCurrentModule), 39 | &module)) { 40 | ASSERT(false && "GetModuleHandleEx failed"); 41 | } 42 | return module; 43 | } 44 | 45 | static std::wstring getModuleFileName(HMODULE module) { 46 | const int bufsize = 4096; 47 | wchar_t path[bufsize]; 48 | int size = GetModuleFileNameW(module, path, bufsize); 49 | ASSERT(size != 0 && size != bufsize); 50 | return std::wstring(path); 51 | } 52 | 53 | static std::wstring dirname(const std::wstring &path) { 54 | std::wstring::size_type pos = path.find_last_of(L"\\/"); 55 | if (pos == std::wstring::npos) { 56 | return L""; 57 | } else { 58 | return path.substr(0, pos); 59 | } 60 | } 61 | 62 | static bool pathExists(const std::wstring &path) { 63 | return GetFileAttributesW(path.c_str()) != 0xFFFFFFFF; 64 | } 65 | 66 | std::wstring findAgentProgram() { 67 | std::wstring progDir = dirname(getModuleFileName(getCurrentModule())); 68 | std::wstring ret = progDir + (L"\\" AGENT_EXE); 69 | if (!pathExists(ret)) { 70 | throw LibWinptyException( 71 | WINPTY_ERROR_AGENT_EXE_MISSING, 72 | (L"agent executable does not exist: '" + ret + L"'").c_str()); 73 | } 74 | return ret; 75 | } 76 | -------------------------------------------------------------------------------- /deps/winpty/src/libwinpty/AgentLocation.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef LIBWINPTY_AGENT_LOCATION_H 22 | #define LIBWINPTY_AGENT_LOCATION_H 23 | 24 | #include 25 | 26 | std::wstring findAgentProgram(); 27 | 28 | #endif // LIBWINPTY_AGENT_LOCATION_H 29 | -------------------------------------------------------------------------------- /deps/winpty/src/libwinpty/LibWinptyException.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef LIB_WINPTY_EXCEPTION_H 22 | #define LIB_WINPTY_EXCEPTION_H 23 | 24 | #include "../include/winpty.h" 25 | 26 | #include "../shared/WinptyException.h" 27 | 28 | #include 29 | #include 30 | 31 | class LibWinptyException : public WinptyException { 32 | public: 33 | LibWinptyException(winpty_result_t code, const wchar_t *what) : 34 | m_code(code), m_what(std::make_shared(what)) {} 35 | 36 | winpty_result_t code() const WINPTY_NOEXCEPT { 37 | return m_code; 38 | } 39 | 40 | const wchar_t *what() const WINPTY_NOEXCEPT override { 41 | return m_what->c_str(); 42 | } 43 | 44 | std::shared_ptr whatSharedStr() const WINPTY_NOEXCEPT { 45 | return m_what; 46 | } 47 | 48 | private: 49 | winpty_result_t m_code; 50 | // Using a shared_ptr ensures that copying the object raises no exception. 51 | std::shared_ptr m_what; 52 | }; 53 | 54 | #endif // LIB_WINPTY_EXCEPTION_H 55 | -------------------------------------------------------------------------------- /deps/winpty/src/libwinpty/WinptyInternal.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef LIBWINPTY_WINPTY_INTERNAL_H 22 | #define LIBWINPTY_WINPTY_INTERNAL_H 23 | 24 | #include 25 | #include 26 | 27 | #include "../include/winpty.h" 28 | 29 | #include "../shared/Mutex.h" 30 | #include "../shared/OwnedHandle.h" 31 | 32 | // The structures in this header are not intended to be accessed directly by 33 | // client programs. 34 | 35 | struct winpty_error_s { 36 | winpty_result_t code; 37 | const wchar_t *msgStatic; 38 | // Use a pointer to a std::shared_ptr so that the struct remains simple 39 | // enough to statically initialize, for the benefit of static error 40 | // objects like kOutOfMemory. 41 | std::shared_ptr *msgDynamic; 42 | }; 43 | 44 | struct winpty_config_s { 45 | uint64_t flags = 0; 46 | int cols = 80; 47 | int rows = 25; 48 | int mouseMode = WINPTY_MOUSE_MODE_AUTO; 49 | DWORD timeoutMs = 30000; 50 | }; 51 | 52 | struct winpty_s { 53 | Mutex mutex; 54 | OwnedHandle agentProcess; 55 | OwnedHandle controlPipe; 56 | DWORD agentTimeoutMs = 0; 57 | OwnedHandle ioEvent; 58 | std::wstring spawnDesktopName; 59 | std::wstring coninPipeName; 60 | std::wstring conoutPipeName; 61 | std::wstring conerrPipeName; 62 | }; 63 | 64 | struct winpty_spawn_config_s { 65 | uint64_t winptyFlags = 0; 66 | std::wstring appname; 67 | std::wstring cmdline; 68 | std::wstring cwd; 69 | std::wstring env; 70 | }; 71 | 72 | #endif // LIBWINPTY_WINPTY_INTERNAL_H 73 | -------------------------------------------------------------------------------- /deps/winpty/src/libwinpty/subdir.mk: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2011-2015 Ryan Prichard 2 | # 3 | # Permission is hereby granted, free of charge, to any person obtaining a copy 4 | # of this software and associated documentation files (the "Software"), to 5 | # deal in the Software without restriction, including without limitation the 6 | # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | # sell copies of the Software, and to permit persons to whom the Software is 8 | # furnished to do so, subject to the following conditions: 9 | # 10 | # The above copyright notice and this permission notice shall be included in 11 | # all copies or substantial portions of the Software. 12 | # 13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | # IN THE SOFTWARE. 20 | 21 | ALL_TARGETS += build/winpty.dll 22 | 23 | $(eval $(call def_mingw_target,libwinpty,-DCOMPILING_WINPTY_DLL)) 24 | 25 | LIBWINPTY_OBJECTS = \ 26 | build/libwinpty/libwinpty/AgentLocation.o \ 27 | build/libwinpty/libwinpty/winpty.o \ 28 | build/libwinpty/shared/BackgroundDesktop.o \ 29 | build/libwinpty/shared/Buffer.o \ 30 | build/libwinpty/shared/DebugClient.o \ 31 | build/libwinpty/shared/GenRandom.o \ 32 | build/libwinpty/shared/OwnedHandle.o \ 33 | build/libwinpty/shared/StringUtil.o \ 34 | build/libwinpty/shared/WindowsSecurity.o \ 35 | build/libwinpty/shared/WindowsVersion.o \ 36 | build/libwinpty/shared/WinptyAssert.o \ 37 | build/libwinpty/shared/WinptyException.o \ 38 | build/libwinpty/shared/WinptyVersion.o 39 | 40 | build/libwinpty/shared/WinptyVersion.o : build/gen/GenVersion.h 41 | 42 | build/winpty.dll : $(LIBWINPTY_OBJECTS) 43 | $(info Linking $@) 44 | @$(MINGW_CXX) $(MINGW_LDFLAGS) -shared -o $@ $^ -Wl,--out-implib,build/winpty.lib 45 | 46 | -include $(LIBWINPTY_OBJECTS:.o=.d) 47 | -------------------------------------------------------------------------------- /deps/winpty/src/shared/AgentMsg.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2012 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef WINPTY_SHARED_AGENT_MSG_H 22 | #define WINPTY_SHARED_AGENT_MSG_H 23 | 24 | struct AgentMsg 25 | { 26 | enum Type { 27 | StartProcess, 28 | SetSize, 29 | GetConsoleProcessList, 30 | }; 31 | }; 32 | 33 | enum class StartProcessResult { 34 | CreateProcessFailed, 35 | ProcessCreated, 36 | }; 37 | 38 | #endif // WINPTY_SHARED_AGENT_MSG_H 39 | -------------------------------------------------------------------------------- /deps/winpty/src/shared/DebugClient.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2012 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef DEBUGCLIENT_H 22 | #define DEBUGCLIENT_H 23 | 24 | #include "winpty_snprintf.h" 25 | 26 | bool isTracingEnabled(); 27 | bool hasDebugFlag(const char *flag); 28 | void trace(const char *format, ...) WINPTY_SNPRINTF_FORMAT(1, 2); 29 | 30 | // This macro calls trace without evaluating the arguments. 31 | #define TRACE(format, ...) \ 32 | do { \ 33 | if (isTracingEnabled()) { \ 34 | trace((format), ## __VA_ARGS__); \ 35 | } \ 36 | } while (false) 37 | 38 | #endif // DEBUGCLIENT_H 39 | -------------------------------------------------------------------------------- /deps/winpty/src/shared/GenRandom.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef WINPTY_GEN_RANDOM_H 22 | #define WINPTY_GEN_RANDOM_H 23 | 24 | // The original MinGW requires that we include wincrypt.h. With MinGW-w64 and 25 | // MSVC, including windows.h is sufficient. 26 | #include 27 | #include 28 | 29 | #include 30 | 31 | #include "OsModule.h" 32 | 33 | class GenRandom { 34 | typedef BOOLEAN WINAPI RtlGenRandom_t(PVOID, ULONG); 35 | 36 | OsModule m_advapi32; 37 | RtlGenRandom_t *m_rtlGenRandom = nullptr; 38 | bool m_cryptProvIsValid = false; 39 | HCRYPTPROV m_cryptProv = 0; 40 | 41 | public: 42 | GenRandom(); 43 | ~GenRandom(); 44 | bool fillBuffer(void *buffer, size_t size); 45 | std::string randomBytes(size_t numBytes); 46 | std::wstring randomHexString(size_t numBytes); 47 | std::wstring uniqueName(); 48 | 49 | // Return true if the crypto context was successfully initialized. 50 | bool valid() const { 51 | return m_rtlGenRandom != nullptr || m_cryptProvIsValid; 52 | } 53 | }; 54 | 55 | #endif // WINPTY_GEN_RANDOM_H 56 | -------------------------------------------------------------------------------- /deps/winpty/src/shared/GetCommitHash.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | REM -- Echo the git commit hash. If git isn't available for some reason, 4 | REM -- output nothing instead. 5 | 6 | git rev-parse HEAD >NUL 2>NUL && ( 7 | git rev-parse HEAD 8 | ) || ( 9 | echo none 10 | ) 11 | 12 | REM -- Set ERRORLEVEL to 0 using this cryptic syntax. 13 | (call ) 14 | -------------------------------------------------------------------------------- /deps/winpty/src/shared/Mutex.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | // Recent 4.x MinGW and MinGW-w64 gcc compilers lack std::mutex and 22 | // std::lock_guard. I have a 5.2.0 MinGW-w64 compiler packaged through MSYS2 23 | // that *is* new enough, but that's one compiler against several deficient 24 | // ones. Wrap CRITICAL_SECTION instead. 25 | 26 | #ifndef WINPTY_SHARED_MUTEX_H 27 | #define WINPTY_SHARED_MUTEX_H 28 | 29 | #include 30 | 31 | class Mutex { 32 | CRITICAL_SECTION m_mutex; 33 | public: 34 | Mutex() { InitializeCriticalSection(&m_mutex); } 35 | ~Mutex() { DeleteCriticalSection(&m_mutex); } 36 | void lock() { EnterCriticalSection(&m_mutex); } 37 | void unlock() { LeaveCriticalSection(&m_mutex); } 38 | 39 | Mutex(const Mutex &other) = delete; 40 | Mutex &operator=(const Mutex &other) = delete; 41 | }; 42 | 43 | template 44 | class LockGuard { 45 | T &m_lock; 46 | public: 47 | LockGuard(T &lock) : m_lock(lock) { m_lock.lock(); } 48 | ~LockGuard() { m_lock.unlock(); } 49 | 50 | LockGuard(const LockGuard &other) = delete; 51 | LockGuard &operator=(const LockGuard &other) = delete; 52 | }; 53 | 54 | #endif // WINPTY_SHARED_MUTEX_H 55 | -------------------------------------------------------------------------------- /deps/winpty/src/shared/OsModule.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef WINPTY_SHARED_OS_MODULE_H 22 | #define WINPTY_SHARED_OS_MODULE_H 23 | 24 | #include 25 | 26 | #include 27 | 28 | #include "DebugClient.h" 29 | #include "WinptyAssert.h" 30 | #include "WinptyException.h" 31 | 32 | class OsModule { 33 | HMODULE m_module; 34 | public: 35 | enum class LoadErrorBehavior { Abort, Throw }; 36 | OsModule(const wchar_t *fileName, 37 | LoadErrorBehavior behavior=LoadErrorBehavior::Abort) { 38 | m_module = LoadLibraryW(fileName); 39 | if (behavior == LoadErrorBehavior::Abort) { 40 | ASSERT(m_module != NULL); 41 | } else { 42 | if (m_module == nullptr) { 43 | const auto err = GetLastError(); 44 | throwWindowsError( 45 | (L"LoadLibraryW error: " + std::wstring(fileName)).c_str(), 46 | err); 47 | } 48 | } 49 | } 50 | ~OsModule() { 51 | FreeLibrary(m_module); 52 | } 53 | HMODULE handle() const { return m_module; } 54 | FARPROC proc(const char *funcName) { 55 | FARPROC ret = GetProcAddress(m_module, funcName); 56 | if (ret == NULL) { 57 | trace("GetProcAddress: %s is missing", funcName); 58 | } 59 | return ret; 60 | } 61 | }; 62 | 63 | #endif // WINPTY_SHARED_OS_MODULE_H 64 | -------------------------------------------------------------------------------- /deps/winpty/src/shared/OwnedHandle.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #include "OwnedHandle.h" 22 | 23 | #include "DebugClient.h" 24 | #include "WinptyException.h" 25 | 26 | void OwnedHandle::dispose(bool nothrow) { 27 | if (m_h != nullptr && m_h != INVALID_HANDLE_VALUE) { 28 | if (!CloseHandle(m_h)) { 29 | trace("CloseHandle(%p) failed", m_h); 30 | if (!nothrow) { 31 | throwWindowsError(L"CloseHandle failed"); 32 | } 33 | } 34 | } 35 | m_h = nullptr; 36 | } 37 | -------------------------------------------------------------------------------- /deps/winpty/src/shared/OwnedHandle.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef WINPTY_SHARED_OWNED_HANDLE_H 22 | #define WINPTY_SHARED_OWNED_HANDLE_H 23 | 24 | #include 25 | 26 | class OwnedHandle { 27 | HANDLE m_h; 28 | public: 29 | OwnedHandle() : m_h(nullptr) {} 30 | explicit OwnedHandle(HANDLE h) : m_h(h) {} 31 | ~OwnedHandle() { dispose(true); } 32 | void dispose(bool nothrow=false); 33 | HANDLE get() const { return m_h; } 34 | HANDLE release() { HANDLE ret = m_h; m_h = nullptr; return ret; } 35 | OwnedHandle(const OwnedHandle &other) = delete; 36 | OwnedHandle(OwnedHandle &&other) : m_h(other.release()) {} 37 | OwnedHandle &operator=(const OwnedHandle &other) = delete; 38 | OwnedHandle &operator=(OwnedHandle &&other) { 39 | dispose(); 40 | m_h = other.release(); 41 | return *this; 42 | } 43 | }; 44 | 45 | #endif // WINPTY_SHARED_OWNED_HANDLE_H 46 | -------------------------------------------------------------------------------- /deps/winpty/src/shared/PrecompiledHeader.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef WINPTY_PRECOMPILED_HEADER_H 22 | #define WINPTY_PRECOMPILED_HEADER_H 23 | 24 | #include 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | #endif // WINPTY_PRECOMPILED_HEADER_H 44 | -------------------------------------------------------------------------------- /deps/winpty/src/shared/StringUtil.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #include "StringUtil.h" 22 | 23 | #include 24 | 25 | #include "WinptyAssert.h" 26 | 27 | // Workaround. MinGW (from mingw.org) does not have wcsnlen. MinGW-w64 *does* 28 | // have wcsnlen, but use this function for consistency. 29 | size_t winpty_wcsnlen(const wchar_t *s, size_t maxlen) { 30 | ASSERT(s != NULL); 31 | for (size_t i = 0; i < maxlen; ++i) { 32 | if (s[i] == L'\0') { 33 | return i; 34 | } 35 | } 36 | return maxlen; 37 | } 38 | 39 | std::string utf8FromWide(const std::wstring &input) { 40 | int mblen = WideCharToMultiByte( 41 | CP_UTF8, 0, 42 | input.data(), input.size(), 43 | NULL, 0, NULL, NULL); 44 | if (mblen <= 0) { 45 | return std::string(); 46 | } 47 | std::vector tmp(mblen); 48 | int mblen2 = WideCharToMultiByte( 49 | CP_UTF8, 0, 50 | input.data(), input.size(), 51 | tmp.data(), tmp.size(), 52 | NULL, NULL); 53 | ASSERT(mblen2 == mblen); 54 | return std::string(tmp.data(), tmp.size()); 55 | } 56 | -------------------------------------------------------------------------------- /deps/winpty/src/shared/StringUtil.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef WINPTY_SHARED_STRING_UTIL_H 22 | #define WINPTY_SHARED_STRING_UTIL_H 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | #include "WinptyAssert.h" 33 | 34 | size_t winpty_wcsnlen(const wchar_t *s, size_t maxlen); 35 | std::string utf8FromWide(const std::wstring &input); 36 | 37 | // Return a vector containing each character in the string. 38 | template 39 | std::vector vectorFromString(const std::basic_string &str) { 40 | return std::vector(str.begin(), str.end()); 41 | } 42 | 43 | // Return a vector containing each character in the string, followed by a 44 | // NUL terminator. 45 | template 46 | std::vector vectorWithNulFromString(const std::basic_string &str) { 47 | std::vector ret; 48 | ret.reserve(str.size() + 1); 49 | ret.insert(ret.begin(), str.begin(), str.end()); 50 | ret.push_back('\0'); 51 | return ret; 52 | } 53 | 54 | // A safer(?) version of wcsncpy that is accepted by MSVC's /SDL mode. 55 | template 56 | wchar_t *winpty_wcsncpy(wchar_t (&d)[N], const wchar_t *s) { 57 | ASSERT(s != nullptr); 58 | size_t i = 0; 59 | for (; i < N; ++i) { 60 | if (s[i] == L'\0') { 61 | break; 62 | } 63 | d[i] = s[i]; 64 | } 65 | for (; i < N; ++i) { 66 | d[i] = L'\0'; 67 | } 68 | return d; 69 | } 70 | 71 | // Like wcsncpy, but ensure that the destination buffer is NUL-terminated. 72 | template 73 | wchar_t *winpty_wcsncpy_nul(wchar_t (&d)[N], const wchar_t *s) { 74 | static_assert(N > 0, "array cannot be 0-size"); 75 | winpty_wcsncpy(d, s); 76 | d[N - 1] = L'\0'; 77 | return d; 78 | } 79 | 80 | #endif // WINPTY_SHARED_STRING_UTIL_H 81 | -------------------------------------------------------------------------------- /deps/winpty/src/shared/TimeMeasurement.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | // Convenience header library for using the high-resolution performance counter 22 | // to measure how long some process takes. 23 | 24 | #ifndef TIME_MEASUREMENT_H 25 | #define TIME_MEASUREMENT_H 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | class TimeMeasurement { 32 | public: 33 | TimeMeasurement() { 34 | static double freq = static_cast(getFrequency()); 35 | m_freq = freq; 36 | m_start = value(); 37 | } 38 | 39 | double elapsed() { 40 | uint64_t elapsedTicks = value() - m_start; 41 | return static_cast(elapsedTicks) / m_freq; 42 | } 43 | 44 | private: 45 | uint64_t getFrequency() { 46 | LARGE_INTEGER freq; 47 | BOOL success = QueryPerformanceFrequency(&freq); 48 | assert(success && "QueryPerformanceFrequency failed"); 49 | return freq.QuadPart; 50 | } 51 | 52 | uint64_t value() { 53 | LARGE_INTEGER ret; 54 | BOOL success = QueryPerformanceCounter(&ret); 55 | assert(success && "QueryPerformanceCounter failed"); 56 | return ret.QuadPart; 57 | } 58 | 59 | uint64_t m_start; 60 | double m_freq; 61 | }; 62 | 63 | #endif // TIME_MEASUREMENT_H 64 | -------------------------------------------------------------------------------- /deps/winpty/src/shared/UnixCtrlChars.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef UNIX_CTRL_CHARS_H 22 | #define UNIX_CTRL_CHARS_H 23 | 24 | inline char decodeUnixCtrlChar(char ch) { 25 | const char ctrlKeys[] = { 26 | /* 0x00 */ '@', /* 0x01 */ 'A', /* 0x02 */ 'B', /* 0x03 */ 'C', 27 | /* 0x04 */ 'D', /* 0x05 */ 'E', /* 0x06 */ 'F', /* 0x07 */ 'G', 28 | /* 0x08 */ 'H', /* 0x09 */ 'I', /* 0x0A */ 'J', /* 0x0B */ 'K', 29 | /* 0x0C */ 'L', /* 0x0D */ 'M', /* 0x0E */ 'N', /* 0x0F */ 'O', 30 | /* 0x10 */ 'P', /* 0x11 */ 'Q', /* 0x12 */ 'R', /* 0x13 */ 'S', 31 | /* 0x14 */ 'T', /* 0x15 */ 'U', /* 0x16 */ 'V', /* 0x17 */ 'W', 32 | /* 0x18 */ 'X', /* 0x19 */ 'Y', /* 0x1A */ 'Z', /* 0x1B */ '[', 33 | /* 0x1C */ '\\', /* 0x1D */ ']', /* 0x1E */ '^', /* 0x1F */ '_', 34 | }; 35 | unsigned char uch = ch; 36 | if (uch < 32) { 37 | return ctrlKeys[uch]; 38 | } else if (uch == 127) { 39 | return '?'; 40 | } else { 41 | return '\0'; 42 | } 43 | } 44 | 45 | #endif // UNIX_CTRL_CHARS_H 46 | -------------------------------------------------------------------------------- /deps/winpty/src/shared/UpdateGenVersion.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | rem -- Echo the git commit hash. If git isn't available for some reason, 4 | rem -- output nothing instead. 5 | 6 | mkdir ..\gen 2>nul 7 | 8 | set /p VERSION=<..\..\VERSION.txt 9 | set COMMIT=%1 10 | 11 | echo // AUTO-GENERATED BY %0 %*>..\gen\GenVersion.h 12 | echo const char GenVersion_Version[] = "%VERSION%";>>..\gen\GenVersion.h 13 | echo const char GenVersion_Commit[] = "%COMMIT%";>>..\gen\GenVersion.h 14 | 15 | rem -- The winpty.gyp file expects the script to output the include directory, 16 | rem -- relative to src. 17 | echo gen 18 | 19 | rem -- Set ERRORLEVEL to 0 using this cryptic syntax. 20 | (call ) 21 | -------------------------------------------------------------------------------- /deps/winpty/src/shared/WindowsVersion.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef WINPTY_SHARED_WINDOWS_VERSION_H 22 | #define WINPTY_SHARED_WINDOWS_VERSION_H 23 | 24 | bool isAtLeastWindowsVista(); 25 | bool isAtLeastWindows7(); 26 | bool isAtLeastWindows8(); 27 | void dumpWindowsVersion(); 28 | 29 | #endif // WINPTY_SHARED_WINDOWS_VERSION_H 30 | -------------------------------------------------------------------------------- /deps/winpty/src/shared/WinptyAssert.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #include "WinptyAssert.h" 22 | 23 | #include 24 | #include 25 | 26 | #include "DebugClient.h" 27 | 28 | void assertTrace(const char *file, int line, const char *cond) { 29 | trace("Assertion failed: %s, file %s, line %d", 30 | cond, file, line); 31 | } 32 | 33 | #ifdef WINPTY_AGENT_ASSERT 34 | 35 | void agentShutdown() { 36 | HWND hwnd = GetConsoleWindow(); 37 | if (hwnd != NULL) { 38 | PostMessage(hwnd, WM_CLOSE, 0, 0); 39 | Sleep(30000); 40 | trace("Agent shutdown: WM_CLOSE did not end agent process"); 41 | } else { 42 | trace("Agent shutdown: GetConsoleWindow() is NULL"); 43 | } 44 | // abort() prints a message to the console, and if it is frozen, then the 45 | // process would hang, so instead use exit(). (We shouldn't ever get here, 46 | // though, because the WM_CLOSE message should have ended this process.) 47 | exit(1); 48 | } 49 | 50 | void agentAssertFail(const char *file, int line, const char *cond) { 51 | assertTrace(file, line, cond); 52 | agentShutdown(); 53 | } 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /deps/winpty/src/shared/WinptyAssert.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef WINPTY_ASSERT_H 22 | #define WINPTY_ASSERT_H 23 | 24 | #ifdef WINPTY_AGENT_ASSERT 25 | 26 | void agentShutdown(); 27 | void agentAssertFail(const char *file, int line, const char *cond); 28 | 29 | // Calling the standard assert() function does not work in the agent because 30 | // the error message would be printed to the console, and the only way the 31 | // user can see the console is via a working agent! Moreover, the console may 32 | // be frozen, so attempting to write to it would block forever. This custom 33 | // assert function instead sends the message to the DebugServer, then attempts 34 | // to close the console, then quietly exits. 35 | #define ASSERT(cond) \ 36 | do { \ 37 | if (!(cond)) { \ 38 | agentAssertFail(__FILE__, __LINE__, #cond); \ 39 | } \ 40 | } while(0) 41 | 42 | #else 43 | 44 | void assertTrace(const char *file, int line, const char *cond); 45 | 46 | // In the other targets, log the assert failure to the debugserver, then fail 47 | // using the ordinary assert mechanism. In case assert is compiled out, fail 48 | // using abort. The amount of code inlined is unfortunate, but asserts aren't 49 | // used much outside the agent. 50 | #include 51 | #include 52 | #define ASSERT_CONDITION(cond) (false && (cond)) 53 | #define ASSERT(cond) \ 54 | do { \ 55 | if (!(cond)) { \ 56 | assertTrace(__FILE__, __LINE__, #cond); \ 57 | assert(ASSERT_CONDITION(#cond)); \ 58 | abort(); \ 59 | } \ 60 | } while(0) 61 | 62 | #endif 63 | 64 | #endif // WINPTY_ASSERT_H 65 | -------------------------------------------------------------------------------- /deps/winpty/src/shared/WinptyException.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #include "WinptyException.h" 22 | 23 | #include 24 | #include 25 | 26 | #include "StringBuilder.h" 27 | 28 | namespace { 29 | 30 | class ExceptionImpl : public WinptyException { 31 | public: 32 | ExceptionImpl(const wchar_t *what) : 33 | m_what(std::make_shared(what)) {} 34 | virtual const wchar_t *what() const WINPTY_NOEXCEPT override { 35 | return m_what->c_str(); 36 | } 37 | private: 38 | // Using a shared_ptr ensures that copying the object raises no exception. 39 | std::shared_ptr m_what; 40 | }; 41 | 42 | } // anonymous namespace 43 | 44 | void throwWinptyException(const wchar_t *what) { 45 | throw ExceptionImpl(what); 46 | } 47 | 48 | void throwWindowsError(const wchar_t *prefix, DWORD errorCode) { 49 | WStringBuilder sb(64); 50 | if (prefix != nullptr) { 51 | sb << prefix << L": "; 52 | } 53 | // It might make sense to use FormatMessage here, but IIRC, its API is hard 54 | // to figure out. 55 | sb << L"Windows error " << errorCode; 56 | throwWinptyException(sb.c_str()); 57 | } 58 | -------------------------------------------------------------------------------- /deps/winpty/src/shared/WinptyException.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef WINPTY_EXCEPTION_H 22 | #define WINPTY_EXCEPTION_H 23 | 24 | #include 25 | 26 | #if defined(__GNUC__) 27 | #define WINPTY_NOEXCEPT noexcept 28 | #elif defined(_MSC_VER) && _MSC_VER >= 1900 29 | #define WINPTY_NOEXCEPT noexcept 30 | #else 31 | #define WINPTY_NOEXCEPT 32 | #endif 33 | 34 | class WinptyException { 35 | public: 36 | virtual const wchar_t *what() const WINPTY_NOEXCEPT = 0; 37 | virtual ~WinptyException() {} 38 | }; 39 | 40 | void throwWinptyException(const wchar_t *what); 41 | void throwWindowsError(const wchar_t *prefix, DWORD error=GetLastError()); 42 | 43 | #endif // WINPTY_EXCEPTION_H 44 | -------------------------------------------------------------------------------- /deps/winpty/src/shared/WinptyVersion.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #include "WinptyVersion.h" 22 | 23 | #include 24 | #include 25 | 26 | #include "DebugClient.h" 27 | 28 | // This header is auto-generated by either the Makefile (Unix) or 29 | // UpdateGenVersion.bat (gyp). It is placed in a 'gen' directory, which is 30 | // added to the search path. 31 | #include "GenVersion.h" 32 | 33 | void dumpVersionToStdout() { 34 | printf("winpty version %s\n", GenVersion_Version); 35 | printf("commit %s\n", GenVersion_Commit); 36 | } 37 | 38 | void dumpVersionToTrace() { 39 | trace("winpty version %s (commit %s)", 40 | GenVersion_Version, 41 | GenVersion_Commit); 42 | } 43 | -------------------------------------------------------------------------------- /deps/winpty/src/shared/WinptyVersion.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef WINPTY_VERSION_H 22 | #define WINPTY_VERSION_H 23 | 24 | void dumpVersionToStdout(); 25 | void dumpVersionToTrace(); 26 | 27 | #endif // WINPTY_VERSION_H 28 | -------------------------------------------------------------------------------- /deps/winpty/src/subdir.mk: -------------------------------------------------------------------------------- 1 | include src/agent/subdir.mk 2 | include src/debugserver/subdir.mk 3 | include src/libwinpty/subdir.mk 4 | include src/tests/subdir.mk 5 | include src/unix-adapter/subdir.mk 6 | -------------------------------------------------------------------------------- /deps/winpty/src/tests/subdir.mk: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 Ryan Prichard 2 | # 3 | # Permission is hereby granted, free of charge, to any person obtaining a copy 4 | # of this software and associated documentation files (the "Software"), to 5 | # deal in the Software without restriction, including without limitation the 6 | # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | # sell copies of the Software, and to permit persons to whom the Software is 8 | # furnished to do so, subject to the following conditions: 9 | # 10 | # The above copyright notice and this permission notice shall be included in 11 | # all copies or substantial portions of the Software. 12 | # 13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | # IN THE SOFTWARE. 20 | 21 | build/%.exe : src/tests/%.cc build/winpty.dll 22 | $(info Building $@) 23 | @$(MINGW_CXX) $(MINGW_CXXFLAGS) $(MINGW_LDFLAGS) -o $@ $^ 24 | 25 | TEST_PROGRAMS = \ 26 | build/trivial_test.exe 27 | 28 | -include $(TEST_PROGRAMS:.exe=.d) 29 | -------------------------------------------------------------------------------- /deps/winpty/src/unix-adapter/InputHandler.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef UNIX_ADAPTER_INPUT_HANDLER_H 22 | #define UNIX_ADAPTER_INPUT_HANDLER_H 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #include "WakeupFd.h" 29 | 30 | // Connect a Cygwin blocking fd to winpty CONIN. 31 | class InputHandler { 32 | public: 33 | InputHandler(HANDLE conin, int inputfd, WakeupFd &completionWakeup); 34 | ~InputHandler() { shutdown(); } 35 | bool isComplete() { return m_threadCompleted; } 36 | void startShutdown() { m_shouldShutdown = 1; m_wakeup.set(); } 37 | void shutdown(); 38 | 39 | private: 40 | static void *threadProcS(void *pvthis) { 41 | reinterpret_cast(pvthis)->threadProc(); 42 | return NULL; 43 | } 44 | void threadProc(); 45 | 46 | HANDLE m_conin; 47 | int m_inputfd; 48 | pthread_t m_thread; 49 | WakeupFd &m_completionWakeup; 50 | WakeupFd m_wakeup; 51 | bool m_threadHasBeenJoined; 52 | volatile sig_atomic_t m_shouldShutdown; 53 | volatile sig_atomic_t m_threadCompleted; 54 | }; 55 | 56 | #endif // UNIX_ADAPTER_INPUT_HANDLER_H 57 | -------------------------------------------------------------------------------- /deps/winpty/src/unix-adapter/OutputHandler.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef UNIX_ADAPTER_OUTPUT_HANDLER_H 22 | #define UNIX_ADAPTER_OUTPUT_HANDLER_H 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #include "WakeupFd.h" 29 | 30 | // Connect winpty CONOUT/CONERR to a Cygwin blocking fd. 31 | class OutputHandler { 32 | public: 33 | OutputHandler(HANDLE conout, int outputfd, WakeupFd &completionWakeup); 34 | ~OutputHandler() { shutdown(); } 35 | bool isComplete() { return m_threadCompleted; } 36 | void shutdown(); 37 | 38 | private: 39 | static void *threadProcS(void *pvthis) { 40 | reinterpret_cast(pvthis)->threadProc(); 41 | return NULL; 42 | } 43 | void threadProc(); 44 | 45 | HANDLE m_conout; 46 | int m_outputfd; 47 | pthread_t m_thread; 48 | WakeupFd &m_completionWakeup; 49 | bool m_threadHasBeenJoined; 50 | volatile sig_atomic_t m_threadCompleted; 51 | }; 52 | 53 | #endif // UNIX_ADAPTER_OUTPUT_HANDLER_H 54 | -------------------------------------------------------------------------------- /deps/winpty/src/unix-adapter/Util.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef UNIX_ADAPTER_UTIL_H 22 | #define UNIX_ADAPTER_UTIL_H 23 | 24 | #include 25 | #include 26 | 27 | bool writeAll(int fd, const void *buffer, size_t size); 28 | bool writeStr(int fd, const char *str); 29 | void selectWrapper(const char *diagName, int nfds, fd_set *readfds); 30 | 31 | #endif // UNIX_ADAPTER_UTIL_H 32 | -------------------------------------------------------------------------------- /deps/winpty/src/unix-adapter/WakeupFd.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #include "WakeupFd.h" 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | static void setFdNonBlock(int fd) { 30 | int status = fcntl(fd, F_GETFL); 31 | fcntl(fd, F_SETFL, status | O_NONBLOCK); 32 | } 33 | 34 | WakeupFd::WakeupFd() { 35 | int pipeFd[2]; 36 | if (pipe(pipeFd) != 0) { 37 | perror("Could not create internal wakeup pipe"); 38 | abort(); 39 | } 40 | m_pipeReadFd = pipeFd[0]; 41 | m_pipeWriteFd = pipeFd[1]; 42 | setFdNonBlock(m_pipeReadFd); 43 | setFdNonBlock(m_pipeWriteFd); 44 | } 45 | 46 | WakeupFd::~WakeupFd() { 47 | close(m_pipeReadFd); 48 | close(m_pipeWriteFd); 49 | } 50 | 51 | void WakeupFd::set() { 52 | char dummy = 0; 53 | int ret; 54 | do { 55 | ret = write(m_pipeWriteFd, &dummy, 1); 56 | } while (ret < 0 && errno == EINTR); 57 | } 58 | 59 | void WakeupFd::reset() { 60 | char tmpBuf[256]; 61 | while (true) { 62 | int amount = read(m_pipeReadFd, tmpBuf, sizeof(tmpBuf)); 63 | if (amount < 0 && errno == EAGAIN) { 64 | break; 65 | } else if (amount <= 0) { 66 | perror("error reading from internal wakeup pipe"); 67 | abort(); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /deps/winpty/src/unix-adapter/WakeupFd.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef UNIX_ADAPTER_WAKEUP_FD_H 22 | #define UNIX_ADAPTER_WAKEUP_FD_H 23 | 24 | class WakeupFd { 25 | public: 26 | WakeupFd(); 27 | ~WakeupFd(); 28 | int fd() { return m_pipeReadFd; } 29 | void set(); 30 | void reset(); 31 | 32 | private: 33 | // Do not allow copying the WakeupFd object. 34 | WakeupFd(const WakeupFd &other); 35 | WakeupFd &operator=(const WakeupFd &other); 36 | 37 | private: 38 | int m_pipeReadFd; 39 | int m_pipeWriteFd; 40 | }; 41 | 42 | #endif // UNIX_ADAPTER_WAKEUP_FD_H 43 | -------------------------------------------------------------------------------- /deps/winpty/src/unix-adapter/subdir.mk: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2011-2015 Ryan Prichard 2 | # 3 | # Permission is hereby granted, free of charge, to any person obtaining a copy 4 | # of this software and associated documentation files (the "Software"), to 5 | # deal in the Software without restriction, including without limitation the 6 | # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | # sell copies of the Software, and to permit persons to whom the Software is 8 | # furnished to do so, subject to the following conditions: 9 | # 10 | # The above copyright notice and this permission notice shall be included in 11 | # all copies or substantial portions of the Software. 12 | # 13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | # IN THE SOFTWARE. 20 | 21 | ALL_TARGETS += build/$(UNIX_ADAPTER_EXE) 22 | 23 | $(eval $(call def_unix_target,unix-adapter,)) 24 | 25 | UNIX_ADAPTER_OBJECTS = \ 26 | build/unix-adapter/unix-adapter/InputHandler.o \ 27 | build/unix-adapter/unix-adapter/OutputHandler.o \ 28 | build/unix-adapter/unix-adapter/Util.o \ 29 | build/unix-adapter/unix-adapter/WakeupFd.o \ 30 | build/unix-adapter/unix-adapter/main.o \ 31 | build/unix-adapter/shared/DebugClient.o \ 32 | build/unix-adapter/shared/WinptyAssert.o \ 33 | build/unix-adapter/shared/WinptyVersion.o 34 | 35 | build/unix-adapter/shared/WinptyVersion.o : build/gen/GenVersion.h 36 | 37 | build/$(UNIX_ADAPTER_EXE) : $(UNIX_ADAPTER_OBJECTS) build/winpty.dll 38 | $(info Linking $@) 39 | @$(UNIX_CXX) $(UNIX_LDFLAGS) -o $@ $^ 40 | 41 | -include $(UNIX_ADAPTER_OBJECTS:.o=.d) 42 | -------------------------------------------------------------------------------- /deps/winpty/vcbuild.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | REM -- Script requirements: 4 | REM -- 5 | REM -- * git This program must be in the Path to check out 6 | REM -- build-gyp. If that directory already exists, then 7 | REM -- git isn't necessary, but if it is missing, no 8 | REM -- commit hash will be embedded into binaries. 9 | REM -- 10 | REM -- * python A non-Cygwin Python 2 python.exe must be in the 11 | REM -- Path to run gyp. 12 | REM -- 13 | REM -- * msbuild msbuild must be in the Path. It is probably 14 | REM -- important to have msbuild from the correct MSVC 15 | REM -- release. 16 | REM -- 17 | REM -- The script's output binaries are in the src/Release/{Win32,x64} 18 | REM -- directory. 19 | 20 | REM ------------------------------------------------------------------------- 21 | REM -- Parse arguments 22 | 23 | setlocal 24 | cd %~dp0 25 | set GYP_ARGS= 26 | set MSVC_PLATFORM=x64 27 | 28 | :ParamLoop 29 | if "%1" == "" goto :ParamDone 30 | if "%1" == "--msvc-platform" ( 31 | REM -- One of Win32 or x64. 32 | set MSVC_PLATFORM=%2 33 | shift && shift 34 | goto :ParamLoop 35 | ) 36 | if "%1" == "--gyp-msvs-version" ( 37 | set GYP_ARGS=%GYP_ARGS% -G msvs_version=%2 38 | shift && shift 39 | goto :ParamLoop 40 | ) 41 | if "%1" == "--toolset" ( 42 | set GYP_ARGS=%GYP_ARGS% -D WINPTY_MSBUILD_TOOLSET=%2 43 | shift && shift 44 | goto :ParamLoop 45 | ) 46 | if "%1" == "--commit-hash" ( 47 | set GYP_ARGS=%GYP_ARGS% -D WINPTY_COMMIT_HASH=%2 48 | shift && shift 49 | goto :ParamLoop 50 | ) 51 | echo error: Unrecognized argument: %1 52 | exit /b 1 53 | :ParamDone 54 | 55 | REM ------------------------------------------------------------------------- 56 | REM -- Check out GYP. GYP doesn't seem to have releases, so just use the 57 | REM -- current master commit. 58 | 59 | if not exist build-gyp ( 60 | git clone https://chromium.googlesource.com/external/gyp build-gyp || ( 61 | echo error: GYP clone failed 62 | exit /b 1 63 | ) 64 | ) 65 | 66 | REM ------------------------------------------------------------------------- 67 | REM -- Run gyp to generate MSVC project files. 68 | 69 | cd src 70 | 71 | call ..\build-gyp\gyp.bat winpty.gyp -I configurations.gypi %GYP_ARGS% 72 | if errorlevel 1 ( 73 | echo error: GYP failed 74 | exit /b 1 75 | ) 76 | 77 | REM ------------------------------------------------------------------------- 78 | REM -- Compile the project. 79 | 80 | msbuild winpty.sln /m /p:Platform=%MSVC_PLATFORM% || ( 81 | echo error: msbuild failed 82 | exit /b 1 83 | ) 84 | -------------------------------------------------------------------------------- /examples/electron/README.md: -------------------------------------------------------------------------------- 1 | This is a minimal example of getting a terminal running in Electron using [node-pty](https://github.com/Tyriar/node-pty) and [xterm.js](https://github.com/sourcelair/xterm.js). 2 | 3 | ![](./images/preview.png) 4 | 5 | ## Usage 6 | 7 | ```bash 8 | # Install npm dependencies using Electron's version of V8 9 | ./npm_install.sh 10 | # Launch the app 11 | npm start 12 | ``` 13 | -------------------------------------------------------------------------------- /examples/electron/images/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/node-pty/d738123f1faf7287513b0df8b9e327be54702e94/examples/electron/images/preview.png -------------------------------------------------------------------------------- /examples/electron/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | node-pty Electron example 6 | 7 | 8 | 9 |
10 | 11 | 14 | 15 | -------------------------------------------------------------------------------- /examples/electron/main.js: -------------------------------------------------------------------------------- 1 | const electron = require('electron') 2 | // Module to control application life. 3 | const app = electron.app 4 | // Module to create native browser window. 5 | const BrowserWindow = electron.BrowserWindow 6 | 7 | const path = require('path') 8 | const url = require('url') 9 | 10 | // Keep a global reference of the window object, if you don't, the window will 11 | // be closed automatically when the JavaScript object is garbage collected. 12 | let mainWindow 13 | 14 | // node-pty is not yet context aware 15 | app.allowRendererProcessReuse = false; 16 | 17 | function createWindow () { 18 | // Create the browser window. 19 | mainWindow = new BrowserWindow({ 20 | width: 800, 21 | height: 600, 22 | // Node integration is required to run node-pty in the renderer process 23 | webPreferences: { 24 | nodeIntegration: true 25 | } 26 | }) 27 | 28 | // and load the index.html of the app. 29 | mainWindow.loadURL(url.format({ 30 | pathname: path.join(__dirname, 'index.html'), 31 | protocol: 'file:', 32 | slashes: true 33 | })) 34 | 35 | // Open the DevTools. 36 | // mainWindow.webContents.openDevTools() 37 | 38 | // Emitted when the window is closed. 39 | mainWindow.on('closed', function () { 40 | // Dereference the window object, usually you would store windows 41 | // in an array if your app supports multi windows, this is the time 42 | // when you should delete the corresponding element. 43 | mainWindow = null 44 | }) 45 | } 46 | 47 | // This method will be called when Electron has finished 48 | // initialization and is ready to create browser windows. 49 | // Some APIs can only be used after this event occurs. 50 | app.on('ready', createWindow) 51 | 52 | // Quit when all windows are closed. 53 | app.on('window-all-closed', function () { 54 | // On OS X it is common for applications and their menu bar 55 | // to stay active until the user quits explicitly with Cmd + Q 56 | if (process.platform !== 'darwin') { 57 | app.quit() 58 | } 59 | }) 60 | 61 | app.on('activate', function () { 62 | // On OS X it's common to re-create a window in the app when the 63 | // dock icon is clicked and there are no other windows open. 64 | if (mainWindow === null) { 65 | createWindow() 66 | } 67 | }) 68 | 69 | // In this file you can include the rest of your app's specific main process 70 | // code. You can also put them in separate files and require them here. 71 | -------------------------------------------------------------------------------- /examples/electron/npm_install.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | set npm_config_disturl="https://atom.io/download/electron" 4 | set npm_config_target=9.1.0 5 | set npm_config_runtime="electron" 6 | set npm_config_cache=~\.npm-electron 7 | npm i 8 | endlocal 9 | -------------------------------------------------------------------------------- /examples/electron/npm_install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # Electron's version. 4 | export npm_config_target=9.1.0 5 | # The architecture of Electron, can be ia32 or x64. 6 | export npm_config_arch=x64 7 | export npm_config_target_arch=x64 8 | # Download headers for Electron. 9 | export npm_config_disturl=https://atom.io/download/electron 10 | # Tell node-pre-gyp that we are building for Electron. 11 | export npm_config_runtime=electron 12 | # Tell node-pre-gyp to build module from source code. 13 | export npm_config_build_from_source=true 14 | # Install all dependencies, and store cache to ~/.electron-gyp. 15 | HOME=~/.electron-gyp npm install 16 | -------------------------------------------------------------------------------- /examples/electron/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-pty-electron-example", 3 | "version": "1.0.0", 4 | "description": "A minimal node-pty Electron example", 5 | "main": "main.js", 6 | "scripts": { 7 | "start": "electron . --ignore-gpu-blacklist" 8 | }, 9 | "repository": "https://github.com/Tyriar/node-pty", 10 | "author": "Tyriar", 11 | "dependencies": { 12 | "electron": "^9.1.0", 13 | "node-pty": "^0.9.0", 14 | "xterm": "4.2.0" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /examples/electron/renderer.js: -------------------------------------------------------------------------------- 1 | var os = require('os'); 2 | var pty = require('node-pty'); 3 | var Terminal = require('xterm').Terminal; 4 | 5 | // Initialize node-pty with an appropriate shell 6 | const shell = process.env[os.platform() === 'win32' ? 'COMSPEC' : 'SHELL']; 7 | const ptyProcess = pty.spawn(shell, [], { 8 | name: 'xterm-color', 9 | cols: 80, 10 | rows: 30, 11 | cwd: process.cwd(), 12 | env: process.env 13 | }); 14 | 15 | // Initialize xterm.js and attach it to the DOM 16 | const xterm = new Terminal(); 17 | xterm.open(document.getElementById('xterm')); 18 | 19 | // Setup communication between xterm.js and node-pty 20 | xterm.onData(data => ptyProcess.write(data)); 21 | ptyProcess.on('data', function (data) { 22 | xterm.write(data); 23 | }); 24 | -------------------------------------------------------------------------------- /examples/fork/index.js: -------------------------------------------------------------------------------- 1 | import * as os from 'node:os'; 2 | import * as pty from '../../lib/index.js'; 3 | 4 | const isWindows = os.platform() === 'win32'; 5 | const shell = isWindows ? 'powershell.exe' : 'bash'; 6 | 7 | const ptyProcess = pty.spawn(shell, [], { 8 | name: 'xterm-256color', 9 | cols: 80, 10 | rows: 26, 11 | cwd: isWindows ? process.env.USERPROFILE : process.env.HOME, 12 | env: Object.assign({ TEST: "Environment vars work" }, process.env), 13 | useConpty: true, 14 | useConptyDll: true 15 | }); 16 | 17 | ptyProcess.onData(data => process.stdout.write(data)); 18 | 19 | ptyProcess.write(isWindows ? 'dir\r' : 'ls\r'); 20 | 21 | setTimeout(() => { 22 | ptyProcess.resize(30, 19); 23 | ptyProcess.write(isWindows ? '$Env:TEST\r' : 'echo $TEST\r'); 24 | }, 2000); 25 | 26 | process.on('exit', () => ptyProcess.kill()); 27 | 28 | setTimeout(() => process.exit(), 4000); 29 | -------------------------------------------------------------------------------- /examples/fork/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module" 3 | } 4 | -------------------------------------------------------------------------------- /examples/killDeepTree/README.md: -------------------------------------------------------------------------------- 1 | This is a manual test to verify deeply nested trees are getting killed correctly on Windows. 2 | 3 | To run: 4 | 5 | ```bash 6 | npm i 7 | node index.js 8 | ``` 9 | 10 | It should launch a notepad window and a webpack dev server, after 10 seconds the webpack dev server should be killed and the notepad instance should not. To verify the server is kill correctly either run the test again or check using ProcessExplorer. 11 | -------------------------------------------------------------------------------- /examples/killDeepTree/entry.js: -------------------------------------------------------------------------------- 1 | const test = 0; 2 | -------------------------------------------------------------------------------- /examples/killDeepTree/index.js: -------------------------------------------------------------------------------- 1 | var os = require('os'); 2 | var pty = require('../..'); 3 | 4 | var shell = os.platform() === 'win32' ? 'powershell.exe' : 'bash'; 5 | 6 | var ptyProcess = pty.spawn(shell, [], { 7 | name: 'xterm-color', 8 | cols: 80, 9 | rows: 30, 10 | cwd: __dirname, 11 | env: process.env 12 | }); 13 | 14 | ptyProcess.onData((data) => process.stdout.write(data)); 15 | 16 | ptyProcess.write('start notepad\r'); 17 | ptyProcess.write('npm start\r'); 18 | 19 | // Kill the tree at the end 20 | setTimeout(() => { 21 | console.log('Killing pty'); 22 | ptyProcess.kill(); 23 | }, 10000); 24 | -------------------------------------------------------------------------------- /examples/killDeepTree/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vscode-process-leak", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "webpack-dev-server" 8 | }, 9 | "private": true, 10 | "devDependencies": { 11 | "webpack": "^4.28.4", 12 | "webpack-dev-server": "^3.1.14" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /examples/killDeepTree/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | entry: './entry.js', 5 | output: { 6 | filename: 'bundle.js', 7 | path: path.resolve(__dirname, 'dist') 8 | }, 9 | devServer: { 10 | port: 8000 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /fixtures/utf8-character.txt: -------------------------------------------------------------------------------- 1 | æ -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-pty", 3 | "description": "Fork pseudoterminals in Node.JS", 4 | "author": { 5 | "name": "Microsoft Corporation" 6 | }, 7 | "version": "1.0.0", 8 | "license": "MIT", 9 | "main": "./lib/index.js", 10 | "types": "./typings/node-pty.d.ts", 11 | "repository": { 12 | "type": "git", 13 | "url": "git://github.com/microsoft/node-pty.git" 14 | }, 15 | "files": [ 16 | "binding.gyp", 17 | "lib/", 18 | "scripts/", 19 | "src/", 20 | "deps/", 21 | "third_party/", 22 | "typings/" 23 | ], 24 | "homepage": "https://github.com/microsoft/node-pty", 25 | "bugs": { 26 | "url": "https://github.com/microsoft/node-pty/issues" 27 | }, 28 | "keywords": [ 29 | "pty", 30 | "tty", 31 | "terminal", 32 | "pseudoterminal", 33 | "forkpty", 34 | "openpty" 35 | ], 36 | "scripts": { 37 | "build": "tsc -b ./src/tsconfig.json", 38 | "watch": "tsc -b -w ./src/tsconfig.json", 39 | "lint": "eslint -c .eslintrc.js --ext .ts src/", 40 | "postinstall": "node scripts/post-install.js", 41 | "test": "cross-env NODE_ENV=test mocha -R spec --exit lib/*.test.js", 42 | "posttest": "npm run lint", 43 | "prepare": "npm run build", 44 | "prepublishOnly": "npm run build" 45 | }, 46 | "dependencies": { 47 | "node-addon-api": "^7.1.0" 48 | }, 49 | "devDependencies": { 50 | "@types/mocha": "^7.0.2", 51 | "@types/node": "12", 52 | "@typescript-eslint/eslint-plugin": "^2.27.0", 53 | "@typescript-eslint/parser": "^2.27.0", 54 | "cross-env": "^5.1.4", 55 | "eslint": "^6.8.0", 56 | "mocha": "10", 57 | "node-gyp": "^10.0.1", 58 | "ps-list": "^6.0.0", 59 | "typescript": "^3.8.3" 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /publish.yml: -------------------------------------------------------------------------------- 1 | name: $(Date:yyyyMMdd)$(Rev:.r) 2 | 3 | trigger: 4 | branches: 5 | include: 6 | - main 7 | 8 | pr: none 9 | 10 | resources: 11 | repositories: 12 | - repository: templates 13 | type: github 14 | name: microsoft/vscode-engineering 15 | ref: main 16 | endpoint: Monaco 17 | 18 | parameters: 19 | - name: publishPackage 20 | displayName: 🚀 Publish node-pty 21 | type: boolean 22 | default: false 23 | - name: releaseQuality 24 | displayName: Quality 25 | type: string 26 | values: 27 | - beta 28 | - stable 29 | default: beta 30 | 31 | variables: 32 | - name: releaseQuality 33 | value: ${{ parameters.releaseQuality }} 34 | 35 | extends: 36 | template: azure-pipelines/npm-package/pipeline.yml@templates 37 | parameters: 38 | npmPackages: 39 | - name: node-pty 40 | 41 | buildSteps: 42 | - script: npm ci 43 | displayName: 'Install dependencies and build' 44 | # The following script leaves the version unchanged for 45 | # stable releases, but increments the version for beta releases. 46 | - script: node scripts/increment-version.js 47 | displayName: 'Increment version' 48 | 49 | testSteps: 50 | - script: npm ci 51 | displayName: 'Install dependencies and build' 52 | - script: npm test 53 | displayName: 'Test' 54 | - script: npm run lint 55 | displayName: 'Lint' 56 | 57 | publishPackage: ${{ parameters.publishPackage }} 58 | ${{ if eq(variables['releaseQuality'], 'stable') }}: 59 | tag: latest 60 | publishRequiresApproval: true 61 | ${{ else }}: 62 | tag: beta 63 | publishRequiresApproval: false 64 | 65 | apiScanExcludes: 'package/third_party/conpty/**/win10-arm64/*.*' 66 | apiScanSoftwareName: 'vscode-node-pty' 67 | apiScanSoftwareVersion: '1' 68 | -------------------------------------------------------------------------------- /scripts/increment-version.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019, Microsoft Corporation (MIT License). 3 | */ 4 | 5 | const cp = require('child_process'); 6 | const fs = require('fs'); 7 | const path = require('path'); 8 | const packageJson = require('../package.json'); 9 | 10 | // Determine if this is a stable or beta release 11 | const publishedVersions = getPublishedVersions(); 12 | const isStableRelease = !publishedVersions.includes(packageJson.version); 13 | 14 | // Get the next version 15 | const nextVersion = isStableRelease ? packageJson.version : getNextBetaVersion(); 16 | console.log(`Setting version to ${nextVersion}`); 17 | 18 | // Set the version in package.json 19 | const packageJsonFile = path.resolve(__dirname, '..', 'package.json'); 20 | packageJson.version = nextVersion; 21 | fs.writeFileSync(packageJsonFile, JSON.stringify(packageJson, null, 2)); 22 | 23 | function getNextBetaVersion() { 24 | if (!/^[0-9]+\.[0-9]+\.[0-9]+$/.exec(packageJson.version)) { 25 | console.error('The package.json version must be of the form x.y.z'); 26 | process.exit(1); 27 | } 28 | const tag = 'beta'; 29 | const stableVersion = packageJson.version.split('.'); 30 | const nextStableVersion = `${stableVersion[0]}.${parseInt(stableVersion[1]) + 1}.0`; 31 | const publishedVersions = getPublishedVersions(nextStableVersion, tag); 32 | if (publishedVersions.length === 0) { 33 | return `${nextStableVersion}-${tag}1`; 34 | } 35 | const latestPublishedVersion = publishedVersions.sort((a, b) => { 36 | const aVersion = parseInt(a.substr(a.search(/[0-9]+$/))); 37 | const bVersion = parseInt(b.substr(b.search(/[0-9]+$/))); 38 | return aVersion > bVersion ? -1 : 1; 39 | })[0]; 40 | const latestTagVersion = parseInt(latestPublishedVersion.substr(latestPublishedVersion.search(/[0-9]+$/)), 10); 41 | return `${nextStableVersion}-${tag}${latestTagVersion + 1}`; 42 | } 43 | 44 | function getPublishedVersions(version, tag) { 45 | const isWin32 = process.platform === 'win32'; 46 | const versionsProcess = isWin32 ? 47 | cp.spawnSync('npm.cmd', ['view', packageJson.name, 'versions', '--json'], { shell: true }) : 48 | cp.spawnSync('npm', ['view', packageJson.name, 'versions', '--json']); 49 | const versionsJson = JSON.parse(versionsProcess.stdout); 50 | if (tag) { 51 | return versionsJson.filter(v => !v.search(new RegExp(`${version}-${tag}[0-9]+`))); 52 | } 53 | return versionsJson; 54 | } 55 | -------------------------------------------------------------------------------- /scripts/post-install.js: -------------------------------------------------------------------------------- 1 | //@ts-check 2 | 3 | const { execSync } = require('child_process'); 4 | const fs = require('fs'); 5 | const os = require('os'); 6 | const path = require('path'); 7 | 8 | const RELEASE_DIR = path.join(__dirname, '../build/Release'); 9 | const BUILD_FILES = [ 10 | path.join(RELEASE_DIR, 'conpty.node'), 11 | path.join(RELEASE_DIR, 'conpty.pdb'), 12 | path.join(RELEASE_DIR, 'conpty_console_list.node'), 13 | path.join(RELEASE_DIR, 'conpty_console_list.pdb'), 14 | path.join(RELEASE_DIR, 'pty.node'), 15 | path.join(RELEASE_DIR, 'pty.pdb'), 16 | path.join(RELEASE_DIR, 'spawn-helper'), 17 | path.join(RELEASE_DIR, 'winpty-agent.exe'), 18 | path.join(RELEASE_DIR, 'winpty-agent.pdb'), 19 | path.join(RELEASE_DIR, 'winpty.dll'), 20 | path.join(RELEASE_DIR, 'winpty.pdb') 21 | ]; 22 | const CONPTY_DIR = path.join(__dirname, '../third_party/conpty'); 23 | const CONPTY_SUPPORTED_ARCH = ['x64', 'arm64']; 24 | 25 | console.log('\x1b[32m> Cleaning release folder...\x1b[0m'); 26 | 27 | function cleanFolderRecursive(folder) { 28 | var files = []; 29 | if (fs.existsSync(folder)) { 30 | files = fs.readdirSync(folder); 31 | files.forEach(function(file,index) { 32 | var curPath = path.join(folder, file); 33 | if (fs.lstatSync(curPath).isDirectory()) { // recurse 34 | cleanFolderRecursive(curPath); 35 | fs.rmdirSync(curPath); 36 | } else if (BUILD_FILES.indexOf(curPath) < 0){ // delete file 37 | fs.unlinkSync(curPath); 38 | } 39 | }); 40 | } 41 | }; 42 | 43 | try { 44 | cleanFolderRecursive(RELEASE_DIR); 45 | } catch(e) { 46 | console.log(e); 47 | process.exit(1); 48 | } 49 | 50 | console.log(`\x1b[32m> Moving conpty.dll...\x1b[0m`); 51 | if (os.platform() !== 'win32') { 52 | console.log(' SKIPPED (not Windows)'); 53 | } else { 54 | let windowsArch; 55 | if (process.env.npm_config_arch) { 56 | windowsArch = process.env.npm_config_arch; 57 | console.log(` Using $npm_config_arch: ${windowsArch}`); 58 | } else { 59 | windowsArch = os.arch(); 60 | console.log(` Using os.arch(): ${windowsArch}`); 61 | } 62 | 63 | if (!CONPTY_SUPPORTED_ARCH.includes(windowsArch)) { 64 | console.log(` SKIPPED (unsupported architecture ${windowsArch})`); 65 | } else { 66 | const versionFolder = fs.readdirSync(CONPTY_DIR)[0]; 67 | console.log(` Found version ${versionFolder}`); 68 | const sourceFolder = path.join(CONPTY_DIR, versionFolder, `win10-${windowsArch}`); 69 | const destFolder = path.join(RELEASE_DIR, 'conpty'); 70 | fs.mkdirSync(destFolder, { recursive: true }); 71 | for (const file of ['conpty.dll', 'OpenConsole.exe']) { 72 | const sourceFile = path.join(sourceFolder, file); 73 | const destFile = path.join(destFolder, file); 74 | console.log(` Copying ${sourceFile} -> ${destFile}`); 75 | fs.copyFileSync(sourceFile, destFile); 76 | } 77 | } 78 | } 79 | 80 | console.log(`\x1b[32m> Generating compile_commands.json...\x1b[0m`); 81 | execSync('npx node-gyp configure -- -f compile_commands_json'); 82 | 83 | process.exit(0); 84 | -------------------------------------------------------------------------------- /src/conpty_console_list_agent.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019, Microsoft Corporation (MIT License). 3 | * 4 | * This module fetches the console process list for a particular PID. It must be 5 | * called from a different process (child_process.fork) as there can only be a 6 | * single console attached to a process. 7 | */ 8 | 9 | let getConsoleProcessList: any; 10 | try { 11 | getConsoleProcessList = require('../build/Release/conpty_console_list.node').getConsoleProcessList; 12 | } catch (err) { 13 | getConsoleProcessList = require('../build/Debug/conpty_console_list.node').getConsoleProcessList; 14 | } 15 | 16 | const shellPid = parseInt(process.argv[2], 10); 17 | const consoleProcessList = getConsoleProcessList(shellPid); 18 | process.send!({ consoleProcessList }); 19 | process.exit(0); 20 | -------------------------------------------------------------------------------- /src/eventEmitter2.test.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019, Microsoft Corporation (MIT License). 3 | */ 4 | 5 | import * as assert from 'assert'; 6 | import { EventEmitter2 } from './eventEmitter2'; 7 | 8 | describe('EventEmitter2', () => { 9 | it('should fire listeners multiple times', () => { 10 | const order: string[] = []; 11 | const emitter = new EventEmitter2(); 12 | emitter.event(data => order.push(data + 'a')); 13 | emitter.event(data => order.push(data + 'b')); 14 | emitter.fire(1); 15 | emitter.fire(2); 16 | assert.deepEqual(order, [ '1a', '1b', '2a', '2b' ]); 17 | }); 18 | 19 | it('should not fire listeners once disposed', () => { 20 | const order: string[] = []; 21 | const emitter = new EventEmitter2(); 22 | emitter.event(data => order.push(data + 'a')); 23 | const disposeB = emitter.event(data => order.push(data + 'b')); 24 | emitter.event(data => order.push(data + 'c')); 25 | emitter.fire(1); 26 | disposeB.dispose(); 27 | emitter.fire(2); 28 | assert.deepEqual(order, [ '1a', '1b', '1c', '2a', '2c' ]); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /src/eventEmitter2.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019, Microsoft Corporation (MIT License). 3 | */ 4 | 5 | import { IDisposable } from './types'; 6 | 7 | interface IListener { 8 | (e: T): void; 9 | } 10 | 11 | export interface IEvent { 12 | (listener: (e: T) => any): IDisposable; 13 | } 14 | 15 | export class EventEmitter2 { 16 | private _listeners: IListener[] = []; 17 | private _event?: IEvent; 18 | 19 | public get event(): IEvent { 20 | if (!this._event) { 21 | this._event = (listener: (e: T) => any) => { 22 | this._listeners.push(listener); 23 | const disposable = { 24 | dispose: () => { 25 | for (let i = 0; i < this._listeners.length; i++) { 26 | if (this._listeners[i] === listener) { 27 | this._listeners.splice(i, 1); 28 | return; 29 | } 30 | } 31 | } 32 | }; 33 | return disposable; 34 | }; 35 | } 36 | return this._event; 37 | } 38 | 39 | public fire(data: T): void { 40 | const queue: IListener[] = []; 41 | for (let i = 0; i < this._listeners.length; i++) { 42 | queue.push(this._listeners[i]); 43 | } 44 | for (let i = 0; i < queue.length; i++) { 45 | queue[i].call(undefined, data); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2012-2015, Christopher Jeffrey, Peter Sunde (MIT License) 3 | * Copyright (c) 2016, Daniel Imms (MIT License). 4 | * Copyright (c) 2018, Microsoft Corporation (MIT License). 5 | */ 6 | 7 | import { ITerminal, IPtyOpenOptions, IPtyForkOptions, IWindowsPtyForkOptions } from './interfaces'; 8 | import { ArgvOrCommandLine } from './types'; 9 | 10 | let terminalCtor: any; 11 | if (process.platform === 'win32') { 12 | terminalCtor = require('./windowsTerminal').WindowsTerminal; 13 | } else { 14 | terminalCtor = require('./unixTerminal').UnixTerminal; 15 | } 16 | 17 | /** 18 | * Forks a process as a pseudoterminal. 19 | * @param file The file to launch. 20 | * @param args The file's arguments as argv (string[]) or in a pre-escaped 21 | * CommandLine format (string). Note that the CommandLine option is only 22 | * available on Windows and is expected to be escaped properly. 23 | * @param options The options of the terminal. 24 | * @throws When the file passed to spawn with does not exists. 25 | * @see CommandLineToArgvW https://msdn.microsoft.com/en-us/library/windows/desktop/bb776391(v=vs.85).aspx 26 | * @see Parsing C++ Comamnd-Line Arguments https://msdn.microsoft.com/en-us/library/17w5ykft.aspx 27 | * @see GetCommandLine https://msdn.microsoft.com/en-us/library/windows/desktop/ms683156.aspx 28 | */ 29 | export function spawn(file?: string, args?: ArgvOrCommandLine, opt?: IPtyForkOptions | IWindowsPtyForkOptions): ITerminal { 30 | return new terminalCtor(file, args, opt); 31 | } 32 | 33 | /** @deprecated */ 34 | export function fork(file?: string, args?: ArgvOrCommandLine, opt?: IPtyForkOptions | IWindowsPtyForkOptions): ITerminal { 35 | return new terminalCtor(file, args, opt); 36 | } 37 | 38 | /** @deprecated */ 39 | export function createTerminal(file?: string, args?: ArgvOrCommandLine, opt?: IPtyForkOptions | IWindowsPtyForkOptions): ITerminal { 40 | return new terminalCtor(file, args, opt); 41 | } 42 | 43 | export function open(options: IPtyOpenOptions): ITerminal { 44 | return terminalCtor.open(options); 45 | } 46 | 47 | /** 48 | * Expose the native API when not Windows, note that this is not public API and 49 | * could be removed at any time. 50 | */ 51 | export const native = (process.platform !== 'win32' ? require('../build/Release/pty.node') : null); 52 | -------------------------------------------------------------------------------- /src/native.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2018, Microsoft Corporation (MIT License). 3 | */ 4 | 5 | interface IConptyNative { 6 | startProcess(file: string, cols: number, rows: number, debug: boolean, pipeName: string, conptyInheritCursor: boolean, useConptyDll: boolean): IConptyProcess; 7 | connect(ptyId: number, commandLine: string, cwd: string, env: string[], useConptyDll: boolean, onExitCallback: (exitCode: number) => void): { pid: number }; 8 | resize(ptyId: number, cols: number, rows: number, useConptyDll: boolean): void; 9 | clear(ptyId: number, useConptyDll: boolean): void; 10 | kill(ptyId: number, useConptyDll: boolean): void; 11 | } 12 | 13 | interface IWinptyNative { 14 | startProcess(file: string, commandLine: string, env: string[], cwd: string, cols: number, rows: number, debug: boolean): IWinptyProcess; 15 | resize(pid: number, cols: number, rows: number): void; 16 | kill(pid: number, innerPid: number): void; 17 | getProcessList(pid: number): number[]; 18 | getExitCode(innerPid: number): number; 19 | } 20 | 21 | interface IUnixNative { 22 | fork(file: string, args: string[], parsedEnv: string[], cwd: string, cols: number, rows: number, uid: number, gid: number, useUtf8: boolean, helperPath: string, onExitCallback: (code: number, signal: number) => void): IUnixProcess; 23 | open(cols: number, rows: number): IUnixOpenProcess; 24 | process(fd: number, pty?: string): string; 25 | resize(fd: number, cols: number, rows: number): void; 26 | } 27 | 28 | interface IConptyProcess { 29 | pty: number; 30 | fd: number; 31 | conin: string; 32 | conout: string; 33 | } 34 | 35 | interface IWinptyProcess { 36 | pty: number; 37 | fd: number; 38 | conin: string; 39 | conout: string; 40 | pid: number; 41 | innerPid: number; 42 | } 43 | 44 | interface IUnixProcess { 45 | fd: number; 46 | pid: number; 47 | pty: string; 48 | } 49 | 50 | interface IUnixOpenProcess { 51 | master: number; 52 | slave: number; 53 | pty: string; 54 | } 55 | -------------------------------------------------------------------------------- /src/shared/conout.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2020, Microsoft Corporation (MIT License). 3 | */ 4 | 5 | export interface IWorkerData { 6 | conoutPipeName: string; 7 | } 8 | 9 | export const enum ConoutWorkerMessage { 10 | READY = 1 11 | } 12 | 13 | export function getWorkerPipeName(conoutPipeName: string): string { 14 | return `${conoutPipeName}-worker`; 15 | } 16 | -------------------------------------------------------------------------------- /src/testUtils.test.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019, Microsoft Corporation (MIT License). 3 | */ 4 | 5 | export function pollUntil(cb: () => boolean, timeout: number, interval: number): Promise { 6 | return new Promise((resolve, reject) => { 7 | const intervalId = setInterval(() => { 8 | if (cb()) { 9 | clearInterval(intervalId); 10 | clearTimeout(timeoutId); 11 | resolve(); 12 | } 13 | }, interval); 14 | const timeoutId = setTimeout(() => { 15 | clearInterval(intervalId); 16 | if (cb()) { 17 | resolve(); 18 | } else { 19 | reject(); 20 | } 21 | }, timeout); 22 | }); 23 | } 24 | -------------------------------------------------------------------------------- /src/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es5", 5 | "rootDir": ".", 6 | "outDir": "../lib", 7 | "sourceMap": true, 8 | "lib": [ 9 | "es2015" 10 | ], 11 | "strict": true 12 | }, 13 | "exclude": [ 14 | "node_modules", 15 | "scripts", 16 | "index.js", 17 | "demo.js", 18 | "lib", 19 | "test", 20 | "examples" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017, Daniel Imms (MIT License). 3 | * Copyright (c) 2018, Microsoft Corporation (MIT License). 4 | */ 5 | 6 | export type ArgvOrCommandLine = string[] | string; 7 | 8 | export interface IExitEvent { 9 | exitCode: number; 10 | signal: number | undefined; 11 | } 12 | 13 | export interface IDisposable { 14 | dispose(): void; 15 | } 16 | -------------------------------------------------------------------------------- /src/unix/spawn-helper.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main (int argc, char** argv) { 7 | char *slave_path = ttyname(STDIN_FILENO); 8 | // open implicit attaches a process to a terminal device if: 9 | // - process has no controlling terminal yet 10 | // - O_NOCTTY is not set 11 | close(open(slave_path, O_RDWR)); 12 | 13 | char *cwd = argv[1]; 14 | char *file = argv[2]; 15 | argv = &argv[2]; 16 | 17 | if (strlen(cwd) && chdir(cwd) == -1) { 18 | _exit(1); 19 | } 20 | 21 | execvp(file, argv); 22 | return 1; 23 | } 24 | -------------------------------------------------------------------------------- /src/utils.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017, Daniel Imms (MIT License). 3 | * Copyright (c) 2018, Microsoft Corporation (MIT License). 4 | */ 5 | 6 | export function assign(target: any, ...sources: any[]): any { 7 | sources.forEach(source => Object.keys(source).forEach(key => target[key] = source[key])); 8 | return target; 9 | } 10 | -------------------------------------------------------------------------------- /src/win/conpty.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | // This header prototypes the Pseudoconsole symbols from conpty.lib with their original names. 5 | // This is required because we cannot import __imp_CreatePseudoConsole from a static library 6 | // as it doesn't produce an import lib. 7 | // We can't use an /ALTERNATENAME trick because it seems that that name is only resolved when the 8 | // linker cannot otherwise find the symbol. 9 | 10 | #pragma once 11 | 12 | #include 13 | 14 | #ifndef CONPTY_IMPEXP 15 | #define CONPTY_IMPEXP __declspec(dllimport) 16 | #endif 17 | 18 | #ifndef CONPTY_EXPORT 19 | #ifdef __cplusplus 20 | #define CONPTY_EXPORT extern "C" CONPTY_IMPEXP 21 | #else 22 | #define CONPTY_EXPORT extern CONPTY_IMPEXP 23 | #endif 24 | #endif 25 | 26 | #define PSEUDOCONSOLE_RESIZE_QUIRK (2u) 27 | #define PSEUDOCONSOLE_PASSTHROUGH_MODE (8u) 28 | 29 | CONPTY_EXPORT HRESULT WINAPI ConptyCreatePseudoConsole(COORD size, HANDLE hInput, HANDLE hOutput, DWORD dwFlags, HPCON* phPC); 30 | CONPTY_EXPORT HRESULT WINAPI ConptyCreatePseudoConsoleAsUser(HANDLE hToken, COORD size, HANDLE hInput, HANDLE hOutput, DWORD dwFlags, HPCON* phPC); 31 | 32 | CONPTY_EXPORT HRESULT WINAPI ConptyResizePseudoConsole(HPCON hPC, COORD size); 33 | CONPTY_EXPORT HRESULT WINAPI ConptyClearPseudoConsole(HPCON hPC); 34 | CONPTY_EXPORT HRESULT WINAPI ConptyShowHidePseudoConsole(HPCON hPC, bool show); 35 | CONPTY_EXPORT HRESULT WINAPI ConptyReparentPseudoConsole(HPCON hPC, HWND newParent); 36 | CONPTY_EXPORT HRESULT WINAPI ConptyReleasePseudoConsole(HPCON hPC); 37 | 38 | CONPTY_EXPORT VOID WINAPI ConptyClosePseudoConsole(HPCON hPC); 39 | CONPTY_EXPORT VOID WINAPI ConptyClosePseudoConsoleTimeout(HPCON hPC, DWORD dwMilliseconds); 40 | 41 | CONPTY_EXPORT HRESULT WINAPI ConptyPackPseudoConsole(HANDLE hServerProcess, HANDLE hRef, HANDLE hSignal, HPCON* phPC); 42 | -------------------------------------------------------------------------------- /src/win/conpty_console_list.cc: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019, Microsoft Corporation (MIT License). 3 | */ 4 | 5 | #define NODE_ADDON_API_DISABLE_DEPRECATED 6 | #include 7 | #include 8 | 9 | static Napi::Value ApiConsoleProcessList(const Napi::CallbackInfo& info) { 10 | Napi::Env env(info.Env()); 11 | if (info.Length() != 1 || 12 | !info[0].IsNumber()) { 13 | throw Napi::Error::New(env, "Usage: getConsoleProcessList(shellPid)"); 14 | } 15 | 16 | const DWORD pid = info[0].As().Uint32Value(); 17 | 18 | if (!FreeConsole()) { 19 | throw Napi::Error::New(env, "FreeConsole failed"); 20 | } 21 | if (!AttachConsole(pid)) { 22 | throw Napi::Error::New(env, "AttachConsole failed"); 23 | } 24 | auto processList = std::vector(64); 25 | auto processCount = GetConsoleProcessList(&processList[0], static_cast(processList.size())); 26 | if (processList.size() < processCount) { 27 | processList.resize(processCount); 28 | processCount = GetConsoleProcessList(&processList[0], static_cast(processList.size())); 29 | } 30 | FreeConsole(); 31 | 32 | Napi::Array result = Napi::Array::New(env); 33 | for (DWORD i = 0; i < processCount; i++) { 34 | result.Set(i, Napi::Number::New(env, processList[i])); 35 | } 36 | return result; 37 | } 38 | 39 | Napi::Object init(Napi::Env env, Napi::Object exports) { 40 | exports.Set("getConsoleProcessList", Napi::Function::New(env, ApiConsoleProcessList)); 41 | return exports; 42 | }; 43 | 44 | NODE_API_MODULE(NODE_GYP_MODULE_NAME, init); 45 | -------------------------------------------------------------------------------- /src/win/path_util.cc: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-2015, Christopher Jeffrey, Peter Sunde (MIT License) 3 | * Copyright (c) 2016, Daniel Imms (MIT License). 4 | * Copyright (c) 2018, Microsoft Corporation (MIT License). 5 | */ 6 | 7 | #include 8 | #include // PathCombine 9 | #include 10 | #include "path_util.h" 11 | 12 | namespace path_util { 13 | 14 | std::wstring to_wstring(const Napi::String& str) { 15 | const std::u16string & u16 = str.Utf16Value(); 16 | return std::wstring(u16.begin(), u16.end()); 17 | } 18 | 19 | std::string wstring_to_string(const std::wstring &wide_string) { 20 | if (wide_string.empty()) { 21 | return ""; 22 | } 23 | const auto size_needed = WideCharToMultiByte(CP_UTF8, 0, &wide_string.at(0), (int)wide_string.size(), nullptr, 0, nullptr, nullptr); 24 | if (size_needed <= 0) { 25 | return ""; 26 | } 27 | std::string result(size_needed, 0); 28 | WideCharToMultiByte(CP_UTF8, 0, &wide_string.at(0), (int)wide_string.size(), &result.at(0), size_needed, nullptr, nullptr); 29 | return result; 30 | } 31 | 32 | const char* from_wstring(const wchar_t* wstr) { 33 | int bufferSize = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL); 34 | if (bufferSize <= 0) { 35 | return ""; 36 | } 37 | char *output = new char[bufferSize]; 38 | int status = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, output, bufferSize, NULL, NULL); 39 | if (status == 0) { 40 | return ""; 41 | } 42 | return output; 43 | } 44 | 45 | bool file_exists(std::wstring filename) { 46 | DWORD attr = ::GetFileAttributesW(filename.c_str()); 47 | if (attr == INVALID_FILE_ATTRIBUTES || (attr & FILE_ATTRIBUTE_DIRECTORY)) { 48 | return false; 49 | } 50 | return true; 51 | } 52 | 53 | // cmd.exe -> C:\Windows\system32\cmd.exe 54 | std::wstring get_shell_path(std::wstring filename) { 55 | std::wstring shellpath; 56 | 57 | if (file_exists(filename)) { 58 | return shellpath; 59 | } 60 | 61 | wchar_t* buffer_ = new wchar_t[MAX_ENV]; 62 | int read = ::GetEnvironmentVariableW(L"Path", buffer_, MAX_ENV); 63 | if (read) { 64 | std::wstring delimiter = L";"; 65 | size_t pos = 0; 66 | std::vector paths; 67 | std::wstring buffer(buffer_); 68 | while ((pos = buffer.find(delimiter)) != std::wstring::npos) { 69 | paths.push_back(buffer.substr(0, pos)); 70 | buffer.erase(0, pos + delimiter.length()); 71 | } 72 | 73 | const wchar_t *filename_ = filename.c_str(); 74 | 75 | for (size_t i = 0; i < paths.size(); ++i) { 76 | std::wstring path = paths[i]; 77 | wchar_t searchPath[MAX_PATH]; 78 | ::PathCombineW(searchPath, const_cast(path.c_str()), filename_); 79 | 80 | if (searchPath == NULL) { 81 | continue; 82 | } 83 | 84 | if (file_exists(searchPath)) { 85 | shellpath = searchPath; 86 | break; 87 | } 88 | } 89 | } 90 | 91 | delete[] buffer_; 92 | return shellpath; 93 | } 94 | 95 | } // namespace path_util 96 | -------------------------------------------------------------------------------- /src/win/path_util.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-2015, Christopher Jeffrey, Peter Sunde (MIT License) 3 | * Copyright (c) 2016, Daniel Imms (MIT License). 4 | * Copyright (c) 2018, Microsoft Corporation (MIT License). 5 | */ 6 | 7 | #ifndef NODE_PTY_PATH_UTIL_H_ 8 | #define NODE_PTY_PATH_UTIL_H_ 9 | 10 | #define NODE_ADDON_API_DISABLE_DEPRECATED 11 | #include 12 | #include 13 | 14 | #define MAX_ENV 65536 15 | 16 | namespace path_util { 17 | 18 | std::wstring to_wstring(const Napi::String& str); 19 | std::string wstring_to_string(const std::wstring &wide_string); 20 | const char* from_wstring(const wchar_t* wstr); 21 | bool file_exists(std::wstring filename); 22 | std::wstring get_shell_path(std::wstring filename); 23 | 24 | } // namespace path_util 25 | 26 | #endif // NODE_PTY_PATH_UTIL_H_ 27 | -------------------------------------------------------------------------------- /src/windowsConoutConnection.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2020, Microsoft Corporation (MIT License). 3 | */ 4 | 5 | import { Worker } from 'worker_threads'; 6 | import { Socket } from 'net'; 7 | import { IDisposable } from './types'; 8 | import { IWorkerData, ConoutWorkerMessage, getWorkerPipeName } from './shared/conout'; 9 | import { join } from 'path'; 10 | import { IEvent, EventEmitter2 } from './eventEmitter2'; 11 | 12 | /** 13 | * The amount of time to wait for additional data after the conpty shell process has exited before 14 | * shutting down the worker and sockets. The timer will be reset if a new data event comes in after 15 | * the timer has started. 16 | */ 17 | const FLUSH_DATA_INTERVAL = 1000; 18 | 19 | /** 20 | * Connects to and manages the lifecycle of the conout socket. This socket must be drained on 21 | * another thread in order to avoid deadlocks where Conpty waits for the out socket to drain 22 | * when `ClosePseudoConsole` is called. This happens when data is being written to the terminal when 23 | * the pty is closed. 24 | * 25 | * See also: 26 | * - https://github.com/microsoft/node-pty/issues/375 27 | * - https://github.com/microsoft/vscode/issues/76548 28 | * - https://github.com/microsoft/terminal/issues/1810 29 | * - https://docs.microsoft.com/en-us/windows/console/closepseudoconsole 30 | */ 31 | export class ConoutConnection implements IDisposable { 32 | private _worker: Worker; 33 | private _drainTimeout: NodeJS.Timeout | undefined; 34 | private _isDisposed: boolean = false; 35 | 36 | private _onReady = new EventEmitter2(); 37 | public get onReady(): IEvent { return this._onReady.event; } 38 | 39 | constructor( 40 | private _conoutPipeName: string, 41 | private _useConptyDll: boolean 42 | ) { 43 | const workerData: IWorkerData = { 44 | conoutPipeName: _conoutPipeName 45 | }; 46 | const scriptPath = __dirname.replace('node_modules.asar', 'node_modules.asar.unpacked'); 47 | this._worker = new Worker(join(scriptPath, 'worker/conoutSocketWorker.js'), { workerData }); 48 | this._worker.on('message', (message: ConoutWorkerMessage) => { 49 | switch (message) { 50 | case ConoutWorkerMessage.READY: 51 | this._onReady.fire(); 52 | return; 53 | default: 54 | console.warn('Unexpected ConoutWorkerMessage', message); 55 | } 56 | }); 57 | } 58 | 59 | dispose(): void { 60 | if (!this._useConptyDll && this._isDisposed) { 61 | return; 62 | } 63 | this._isDisposed = true; 64 | // Drain all data from the socket before closing 65 | this._drainDataAndClose(); 66 | } 67 | 68 | connectSocket(socket: Socket): void { 69 | socket.connect(getWorkerPipeName(this._conoutPipeName)); 70 | } 71 | 72 | private _drainDataAndClose(): void { 73 | if (this._drainTimeout) { 74 | clearTimeout(this._drainTimeout); 75 | } 76 | this._drainTimeout = setTimeout(() => this._destroySocket(), FLUSH_DATA_INTERVAL); 77 | } 78 | 79 | private async _destroySocket(): Promise { 80 | await this._worker.terminate(); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/worker/conoutSocketWorker.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2020, Microsoft Corporation (MIT License). 3 | */ 4 | 5 | import { parentPort, workerData } from 'worker_threads'; 6 | import { Socket, createServer } from 'net'; 7 | import { ConoutWorkerMessage, IWorkerData, getWorkerPipeName } from '../shared/conout'; 8 | 9 | const { conoutPipeName } = (workerData as IWorkerData); 10 | 11 | const conoutSocket = new Socket(); 12 | conoutSocket.setEncoding('utf8'); 13 | conoutSocket.connect(conoutPipeName, () => { 14 | const server = createServer(workerSocket => { 15 | conoutSocket.pipe(workerSocket); 16 | }); 17 | server.listen(getWorkerPipeName(conoutPipeName)); 18 | if (!parentPort) { 19 | throw new Error('worker_threads parentPort is null'); 20 | } 21 | parentPort.postMessage(ConoutWorkerMessage.READY); 22 | }); 23 | -------------------------------------------------------------------------------- /test/spam-close.js: -------------------------------------------------------------------------------- 1 | // This test creates a pty periodically, spamming it with echo calls and killing it shortly after. 2 | // It's a test case for https://github.com/microsoft/node-pty/issues/375, the script will hang 3 | // when it show this bug instead of continuing to create more processes. 4 | 5 | var os = require('os'); 6 | var pty = require('..'); 7 | 8 | var isWindows = os.platform() === 'win32'; 9 | var shell = isWindows ? 'cmd.exe' : 'bash'; 10 | 11 | let i = 0; 12 | 13 | setInterval(() => { 14 | console.log(`creating pty ${++i}`); 15 | var ptyProcess = pty.spawn(shell, [], { 16 | name: 'xterm-256color', 17 | cols: 80, 18 | rows: 26, 19 | cwd: isWindows ? process.env.USERPROFILE : process.env.HOME, 20 | env: Object.assign({ TEST: "Environment vars work" }, process.env), 21 | useConpty: true 22 | }); 23 | 24 | ptyProcess.onData(data => console.log(` data: ${data.replace(/\x1b|\n|\r/g, '_')}`)); 25 | 26 | setInterval(() => { 27 | ptyProcess.write('echo foo\r'.repeat(50)); 28 | }, 10); 29 | setTimeout(() => { 30 | console.log(` killing ${ptyProcess.pid}...`); 31 | ptyProcess.kill(); 32 | }, 100); 33 | }, 1200); 34 | -------------------------------------------------------------------------------- /third_party/conpty/1.22.250204002/win10-arm64/OpenConsole.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/node-pty/d738123f1faf7287513b0df8b9e327be54702e94/third_party/conpty/1.22.250204002/win10-arm64/OpenConsole.exe -------------------------------------------------------------------------------- /third_party/conpty/1.22.250204002/win10-arm64/conpty.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/node-pty/d738123f1faf7287513b0df8b9e327be54702e94/third_party/conpty/1.22.250204002/win10-arm64/conpty.dll -------------------------------------------------------------------------------- /third_party/conpty/1.22.250204002/win10-x64/OpenConsole.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/node-pty/d738123f1faf7287513b0df8b9e327be54702e94/third_party/conpty/1.22.250204002/win10-x64/OpenConsole.exe -------------------------------------------------------------------------------- /third_party/conpty/1.22.250204002/win10-x64/conpty.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/node-pty/d738123f1faf7287513b0df8b9e327be54702e94/third_party/conpty/1.22.250204002/win10-x64/conpty.dll --------------------------------------------------------------------------------