diff --git a/contrib/win32/RedirectedIO-exp/RedirectedIO/RedirectedIO.sln b/contrib/win32/RedirectedIO-exp/RedirectedIO/RedirectedIO.sln index 6b8d1cf..04a8bef 100644 --- a/contrib/win32/RedirectedIO-exp/RedirectedIO/RedirectedIO.sln +++ b/contrib/win32/RedirectedIO-exp/RedirectedIO/RedirectedIO.sln @@ -5,6 +5,8 @@ VisualStudioVersion = 14.0.24720.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RedirectedIO", "RedirectedIO\RedirectedIO.vcxproj", "{47CB1D05-8813-415A-BB85-042E09B8A794}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shell-host", "shell-host\shell-host.vcxproj", "{BEFEFB98-000C-4DBB-A9E8-79EFAB305300}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -21,6 +23,14 @@ Global {47CB1D05-8813-415A-BB85-042E09B8A794}.Release|x64.Build.0 = Release|x64 {47CB1D05-8813-415A-BB85-042E09B8A794}.Release|x86.ActiveCfg = Release|Win32 {47CB1D05-8813-415A-BB85-042E09B8A794}.Release|x86.Build.0 = Release|Win32 + {BEFEFB98-000C-4DBB-A9E8-79EFAB305300}.Debug|x64.ActiveCfg = Debug|x64 + {BEFEFB98-000C-4DBB-A9E8-79EFAB305300}.Debug|x64.Build.0 = Debug|x64 + {BEFEFB98-000C-4DBB-A9E8-79EFAB305300}.Debug|x86.ActiveCfg = Debug|Win32 + {BEFEFB98-000C-4DBB-A9E8-79EFAB305300}.Debug|x86.Build.0 = Debug|Win32 + {BEFEFB98-000C-4DBB-A9E8-79EFAB305300}.Release|x64.ActiveCfg = Release|x64 + {BEFEFB98-000C-4DBB-A9E8-79EFAB305300}.Release|x64.Build.0 = Release|x64 + {BEFEFB98-000C-4DBB-A9E8-79EFAB305300}.Release|x86.ActiveCfg = Release|Win32 + {BEFEFB98-000C-4DBB-A9E8-79EFAB305300}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/contrib/win32/RedirectedIO-exp/RedirectedIO/RedirectedIO/RedirectedIO.cpp b/contrib/win32/RedirectedIO-exp/RedirectedIO/RedirectedIO/RedirectedIO.cpp index febe71f..aa007b6 100644 --- a/contrib/win32/RedirectedIO-exp/RedirectedIO/RedirectedIO/RedirectedIO.cpp +++ b/contrib/win32/RedirectedIO-exp/RedirectedIO/RedirectedIO/RedirectedIO.cpp @@ -18,43 +18,33 @@ DWORD WINAPI OutThreadProc( BOOL ret = TRUE; while (ret) { ret = ReadFile(out[0], buf, 1024, &tmp, NULL); - if (ret) + if (ret) { ret = WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buf, tmp, &tmp, NULL); + } } + printf("----- OUT STREAM CLOSED -------\n"); return ret; } -DWORD WINAPI InThreadProc( +DWORD WINAPI ErrThreadProc( _In_ LPVOID lpParameter ) { - DWORD mode; - char buf[1024]; - char *cmd = "dir/r/n"; DWORD tmp; BOOL ret = TRUE; while (ret) { - //ret = ReadFile(GetStdHandle(STD_INPUT_HANDLE), buf, 1024, &tmp, NULL); - if (ret) - //WriteFile(in[1], buf, tmp, &tmp, NULL); - ret = WriteFile(in[1], cmd, 5, &tmp, NULL); - Sleep(3000); + ret = ReadFile(err[0], buf, 1024, &tmp, NULL); + if (ret) { + ret = WriteFile(GetStdHandle(STD_ERROR_HANDLE), buf, tmp, &tmp, NULL); + } } + printf("-------------ERROR STREAM CLOSED -------------\n"); return ret; } -BOOL WINAPI HandlerRoutine( - _In_ DWORD dwCtrlType - ) { - if (dwCtrlType == CTRL_C_EVENT) { - return TRUE; - } - return FALSE; -} - int fileio_pipe(HANDLE pio[2]) { HANDLE read_handle = INVALID_HANDLE_VALUE, write_handle = INVALID_HANDLE_VALUE; @@ -135,17 +125,23 @@ int main() si.wShowWindow = 1; // FALSE ; si.cbReserved2 = 0; si.lpReserved2 = 0; - //si.hStdInput = in[0]; - si.hStdInput = GetStdHandle(STD_INPUT_HANDLE); + si.hStdInput = in[0]; si.hStdOutput = out[1]; si.hStdError = err[1]; - swprintf(cmd, L"%ls", L"cmd.exe"); + swprintf(cmd, L"%ls", L"shell-host.exe"); - ret = CreateProcessW(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi); + + ret = CreateProcessW(NULL, cmd, NULL, NULL, TRUE, DETACHED_PROCESS, NULL, NULL, &si, &pi); + //ret = CreateProcessW(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi); if (!ret) exit(-1); + /* close unwanted handles*/ + CloseHandle(in[0]); + CloseHandle(out[1]); + CloseHandle(err[1]); + DWORD mode; GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &mode); SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), mode & ~( ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT)); @@ -153,37 +149,15 @@ int main() HANDLE t[2]; t[0] = CreateThread(NULL, 0, OutThreadProc, NULL, 0, NULL); - //t[1] = CreateThread(NULL, 0, InThreadProc, NULL, 0, NULL); - - //WriteFile(in[1], "dir\n", 4, &tmp, NULL); - //WriteFile(in[1], "d", 1, &tmp, NULL); - //WriteFile(in[1], "i", 1, &tmp, NULL); - //WriteFile(in[1], "r", 1, &tmp, NULL); - //WriteFile(in[1], "\r", 1, &tmp, NULL); - //WriteFile(in[1], "\n", 1, &tmp, NULL); - - + t[1] = CreateThread(NULL, 0, ErrThreadProc, NULL, 0, NULL); ret = true; while (ret) { ret = ReadFile(GetStdHandle(STD_INPUT_HANDLE), buf, 1024, &tmp, NULL); if (ret) { - ret = WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buf, tmp, &tmp, NULL); - - if ((tmp == 1) && (buf[0] == 13)) - buf[0] = 10; - - if (ret) - //ret = WriteFile(in[1], buf, tmp, &tmp, NULL); - WriteFile(GetStdHandle(STD_INPUT_HANDLE), buf, tmp, &tmp, NULL); - //ret = WriteFile(in[1], "dir\r\n", 5, &tmp, NULL); + ret = WriteFile(in[1], buf, tmp, &tmp, NULL); } } - - //SetConsoleCtrlHandler(HandlerRoutine, TRUE); - - // WaitForMultipleObjects(2, t, TRUE, INFINITE); - - } + \ No newline at end of file diff --git a/contrib/win32/RedirectedIO-exp/RedirectedIO/shell-host/shell-host.c b/contrib/win32/RedirectedIO-exp/RedirectedIO/shell-host/shell-host.c new file mode 100644 index 0000000..0cdb131 --- /dev/null +++ b/contrib/win32/RedirectedIO-exp/RedirectedIO/shell-host/shell-host.c @@ -0,0 +1,201 @@ +/* + * Author: Manoj Ampalam + * Primitive shell-host to support parsing of cmd.exe input and async IO redirection + * + * Copyright (c) 2015 Microsoft Corp. + * All rights reserved + * + * Microsoft openssh win32 port + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include + +#define MAX_CMD_LEN 512 + +HANDLE pipe_in; +HANDLE pipe_out; +HANDLE pipe_err; +HANDLE child_pipe_read = INVALID_HANDLE_VALUE; +HANDLE child_pipe_write = INVALID_HANDLE_VALUE; +BOOL istty = TRUE; //TODO - set this to FALSE +HANDLE child = INVALID_HANDLE_VALUE, monitor_thread = INVALID_HANDLE_VALUE; +DWORD in_cmd_len = 0; +char in_cmd[MAX_CMD_LEN]; + +DWORD WINAPI MonitorChild( + _In_ LPVOID lpParameter + ) { + WaitForSingleObject(child, INFINITE); + CloseHandle(pipe_in); + //printf("XXXX CHILD PROCESS DEAD XXXXX"); + return 0; +} + +#define GOTO_CLEANUP_ON_ERR(exp) do { \ + ret = (exp); \ + if (ret == FALSE) \ + goto cleanup; \ +} while(0) \ + +int main() { + STARTUPINFO si; + PROCESS_INFORMATION pi; + wchar_t cmd[MAX_PATH]; + SECURITY_ATTRIBUTES sa; + BOOL ret; + + pipe_in = GetStdHandle(STD_INPUT_HANDLE); + pipe_out = GetStdHandle(STD_OUTPUT_HANDLE); + pipe_err = GetStdHandle(STD_ERROR_HANDLE); + + /* copy pipe handles passed through std io*/ + if ((pipe_in == INVALID_HANDLE_VALUE) + || (pipe_out == INVALID_HANDLE_VALUE) + || (pipe_err == INVALID_HANDLE_VALUE)) + return -1; + + memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES)); + sa.bInheritHandle = TRUE; + if (!CreatePipe(&child_pipe_read, &child_pipe_write, &sa, 128)) + return -1; + + /* A console is attached if a tty is requested */ + if (!AllocConsole()) + istty = TRUE; + + memset(&si, 0, sizeof(STARTUPINFO)); + memset(&pi, 0, sizeof(PROCESS_INFORMATION)); + + si.cb = sizeof(STARTUPINFO); + si.dwFlags = STARTF_USESTDHANDLES; + si.hStdInput = child_pipe_read; + si.hStdOutput = pipe_out; + si.hStdError = pipe_err; + + /* disable inheritance on child_pipe_write and pipe_in*/ + SetHandleInformation(pipe_in, HANDLE_FLAG_INHERIT, 0); + SetHandleInformation(child_pipe_write, HANDLE_FLAG_INHERIT, 0); + + /* create job to hold all child processes */ + { + /* TODO - this does not work as expected*/ + HANDLE job = CreateJobObject(NULL, NULL); + JOBOBJECT_EXTENDED_LIMIT_INFORMATION job_info; + memset(&job_info, 0, sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION)); + job_info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; + if (!SetInformationJobObject(job, JobObjectExtendedLimitInformation, &job_info, sizeof(job_info))) + return -1; + CloseHandle(job); + } + + swprintf(cmd, L"%ls", L"cmd.exe"); + GOTO_CLEANUP_ON_ERR(CreateProcess(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)); + + /* close unwanted handles*/ + CloseHandle(child_pipe_read); + child_pipe_read = INVALID_HANDLE_VALUE; + + child = pi.hProcess; + /* monitor child exist */ + monitor_thread = CreateThread(NULL, 0, MonitorChild, NULL, 0, NULL); + if (monitor_thread == INVALID_HANDLE_VALUE) + goto cleanup; + + /* disable Ctrl+C hander in this process*/ + SetConsoleCtrlHandler(NULL, TRUE); + + /* process data from pipe_in and route appropriately */ + while (1) { + char buf[128]; + DWORD rd = 0, wr = 0, i = 0; + GOTO_CLEANUP_ON_ERR(ReadFile(pipe_in, buf, 128, &rd, NULL)); + + if (!istty) { /* no tty, juet send it accross */ + GOTO_CLEANUP_ON_ERR(WriteFile(child_pipe_write, buf, rd, &wr, NULL)); + continue; + } + + while (i < rd) { + /* skip them for now*/ + if ((rd - i >= 3) && (buf[i] == '\033') && (buf[i + 1] == '[') + && (buf[i + 2] >= 'A') && (buf[i + 2] <= 'D')) { + i += 3; + continue; + } + + // Ctrl +C + if (buf[i] == '\003') { + GOTO_CLEANUP_ON_ERR(GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0)); + in_cmd_len = 0; + i++; + continue; + } + + // for backspace, we need to send space and another backspace for visual erase + if (buf[i] == '\b') { + if (in_cmd_len > 0) { + GOTO_CLEANUP_ON_ERR(WriteFile(pipe_out, "\b \b", 3, &wr, NULL)); + in_cmd_len--; + } + i++; + continue; + } + + //for CR and LF + if ((buf[i] == '\r') || (buf[i] == '\n')) { + + /* TODO - do a much accurate mapping */ + buf[i] = '\n'; + GOTO_CLEANUP_ON_ERR(WriteFile(pipe_out, buf + i, 1, &wr, NULL)); + in_cmd[in_cmd_len] = buf[i]; + in_cmd_len++; + GOTO_CLEANUP_ON_ERR(WriteFile(child_pipe_write, in_cmd, in_cmd_len, &wr, NULL)); + in_cmd_len = 0; + i++; + continue; + } + + + GOTO_CLEANUP_ON_ERR(WriteFile(pipe_out, buf + i, 1, &wr, NULL)); + in_cmd[in_cmd_len] = buf[i]; + in_cmd_len++; + if (in_cmd_len == MAX_CMD_LEN - 1) { + GOTO_CLEANUP_ON_ERR(WriteFile(child_pipe_write, in_cmd, in_cmd_len, &wr, NULL)); + in_cmd_len = 0; + } + + i++; + } + } + +cleanup: + + if (child != INVALID_HANDLE_VALUE) + TerminateProcess(child, 0); + if (monitor_thread != INVALID_HANDLE_VALUE) + WaitForSingleObject(monitor_thread, INFINITE); + return 0; +} + diff --git a/contrib/win32/RedirectedIO-exp/RedirectedIO/shell-host/shell-host.vcxproj b/contrib/win32/RedirectedIO-exp/RedirectedIO/shell-host/shell-host.vcxproj new file mode 100644 index 0000000..4ca7f7b --- /dev/null +++ b/contrib/win32/RedirectedIO-exp/RedirectedIO/shell-host/shell-host.vcxproj @@ -0,0 +1,154 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {BEFEFB98-000C-4DBB-A9E8-79EFAB305300} + Win32Proj + shellhost + 8.1 + + + + Application + true + v140 + Unicode + + + Application + false + v140 + true + Unicode + + + Application + true + v140 + Unicode + + + Application + false + v140 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + + + Level3 + Disabled + _WIN32_WINNT=0x501;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDebug + + + Console + true + + + + + + + Level3 + Disabled + _WIN32_WINNT=0x501;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDebug + + + Console + true + + + + + Level3 + + + MaxSpeed + true + true + _WIN32_WINNT=0x501;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreaded + + + Console + true + true + true + + + + + Level3 + + + MaxSpeed + true + true + _WIN32_WINNT=0x501;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreaded + + + Console + true + true + true + + + + + + + + + \ No newline at end of file diff --git a/contrib/win32/RedirectedIO-exp/RedirectedIO/shell-host/shell-host.vcxproj.filters b/contrib/win32/RedirectedIO-exp/RedirectedIO/shell-host/shell-host.vcxproj.filters new file mode 100644 index 0000000..1e976f2 --- /dev/null +++ b/contrib/win32/RedirectedIO-exp/RedirectedIO/shell-host/shell-host.vcxproj.filters @@ -0,0 +1,18 @@ + + + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + Resource Files\Source Files + + + \ No newline at end of file diff --git a/contrib/win32/win32compat/fileio.c b/contrib/win32/win32compat/fileio.c index e1ba9f3..b178fff 100644 --- a/contrib/win32/win32compat/fileio.c +++ b/contrib/win32/win32compat/fileio.c @@ -1,5 +1,31 @@ /* * Author: Manoj Ampalam +* +* Copyright (c) 2015 Microsoft Corp. +* All rights reserved +* +* Microsoft openssh win32 port +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include diff --git a/contrib/win32/win32compat/signal.c b/contrib/win32/win32compat/signal.c index 364e7e0..f2531ea 100644 --- a/contrib/win32/win32compat/signal.c +++ b/contrib/win32/win32compat/signal.c @@ -1,5 +1,31 @@ /* * Author: Manoj Ampalam +* +* Copyright (c) 2015 Microsoft Corp. +* All rights reserved +* +* Microsoft openssh win32 port +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "w32fd.h" diff --git a/contrib/win32/win32compat/socketio.c b/contrib/win32/win32compat/socketio.c index 52e216b..cf5002e 100644 --- a/contrib/win32/win32compat/socketio.c +++ b/contrib/win32/win32compat/socketio.c @@ -1,5 +1,31 @@ /* * Author: Manoj Ampalam +* +* Copyright (c) 2015 Microsoft Corp. +* All rights reserved +* +* Microsoft openssh win32 port +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include diff --git a/contrib/win32/win32compat/w32fd.c b/contrib/win32/win32compat/w32fd.c index 0de9363..1fbaf6c 100644 --- a/contrib/win32/win32compat/w32fd.c +++ b/contrib/win32/win32compat/w32fd.c @@ -2,6 +2,32 @@ * Author: Manoj Ampalam * * Implementation of POSIX APIs +* +* Copyright (c) 2015 Microsoft Corp. +* All rights reserved +* +* Microsoft openssh win32 port +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "inc\w32posix.h" #include "w32fd.h" @@ -694,6 +720,9 @@ int w32_temp_AddChildToWatch(HANDLE processtowatch) { HANDLE w32_fd_to_handle(int fd) { + HANDLE h = fd_table.w32_ios[fd]->handle; + if (fd <= STDERR_FILENO) + h = GetStdHandle(fd_table.w32_ios[fd]->std_handle); return fd_table.w32_ios[fd]->handle; }