Commit Graph

395 Commits

Author SHA1 Message Date
Ryan Prichard
9675a911a1 Merge branch 'master' into libwinpty-rewrite 2016-02-21 01:35:57 -06:00
Ryan Prichard
30c6e9f7e0 Generate an import lib to accompany winpty.dll.
winpty.lib isn't needed for console.exe, but it could be useful to other
software embedding winpty.  MSVC needs it to link against winpty.dll.
2016-02-21 01:35:30 -06:00
Ryan Prichard
41762f3851 Link statically to the MSVC runtime library in configurations.gypi. 2016-01-24 02:26:58 -06:00
Ryan Prichard
b844635158 Remove support for the MinGW compiler packaged with Cygwin.
MinGW-w64 is still supported, as is the MinGW compiler distributed by
mingw.org.

Cygwin's MinGW toolchain uses the 4.0-1 mingw-runtime package by
default, which appears to correspond to the "WSL-4" 4.x version of the
MinGW project's mingwrt packages.  (The version numbers in the
/usr/i686-pc-mingw32/sys-root/mingw/include/_mingw.h file are also
consistent with this theory.)

The WSL-4 branch was repudiated by the MinGW project as a mistake [1].
The MinGW project claims no responsibility for Cygwin's MinGW packages
[2].  There were several releases in short succession [3]:
  4.0.3 2013-09-22
  4.0.2 2013-09-15
  4.0.1 2013-09-14
  4.0.0 2013-08-23
There have been no 4.x releases since then, though there have been more
3.x releases (3.21 and 3.21.1).  The FILE_FLAG_FIRST_PIPE_INSTANCE bug
that this project has worked around was fixed in 4.0.3 [4], which was
never propagated to the Cygwin package.

The MinGW packages were apparantly orphaned on 2014-09-18 [5] and are
still orphaned [6].

[1] http://sourceforge.net/p/mingw/bugs/1673/#5260/41ec
[2] http://sourceforge.net/p/mingw/bugs/1673/#2556/35d4
[3] http://sourceforge.net/projects/mingw/files/MinGW/Base/mingwrt/
[4] http://sourceforge.net/p/mingw/bugs/2050/
[5] https://cygwin.com/ml/cygwin/2014-09/msg00289.html
[6] https://cygwin.com/cygwin-pkg-maint
2016-01-23 06:19:56 -06:00
Ryan Prichard
9b69f67f56 Use precompiled headers when compiling with GCC.
The unix-adapter doesn't use PCH, because MSYS1's compiler doesn't support
them.
2016-01-23 05:50:30 -06:00
Ryan Prichard
e3c669ae56 Avoid invoking dirname and git for each compiled C++ source file 2016-01-23 04:36:44 -06:00
Ryan Prichard
7f1045972c Work around the MinGW -std=c++11 bug using -std=gnu++11. 2016-01-23 04:36:04 -06:00
Ryan Prichard
cfb5f81de3 Adjust error handling in libwinpty
* Use ASSERT() where the API is being misused.  Also use it when
   WaitForMultipleObjects or WriteFile return a value I don't expect to
   ever see.

 * Allow passing err to winpty_error_{code,msg}, though.  Instead of
   complaining about the NULL error pointer, instead return
   WINPTY_ERROR_SUCCESS and L"Success".
2016-01-23 04:12:25 -06:00
Ryan Prichard
6deb5e2c26 Make WinptyAssert.h behave more sensibly, both inside and outside the agent
* In agent: if the console is frozen, then calling abort hangs forever,
   because abort tries to write to stderr, which blocks.  Instead,
   use WM_CLOSE to close the console window.  If that doesn't work after
   waiting a while, then exit.

   We need to do the same thing doing normal agent shutdown, so factor out
   an agentShutdown function.  It's a bit unhappy living in
   WinptyAssert.cc, but it works.

 * Outside agent: trace an assertion failure message, then delegate to the
   ordinary assert() function.  If that's somehow turned off, then call
   abort().
2016-01-18 01:41:59 -06:00
Ryan Prichard
873733faa4 Move the toString functions into Coord.h and SmallRect.h.
I don't think these functions are actually called anywhere -- they only
exist for debugging.  Inlining them will probably reduce build times.
2016-01-18 00:28:15 -06:00
Ryan Prichard
3da3381859 Stop spawning cat/tr for each compiled source file 2016-01-18 00:16:45 -06:00
Ryan Prichard
80d4faa72c Compile each target's source files separately from other targets.
The gyp file already worked this way, but now the Makefile does too.

The motivation is to let the shared source files have different error
handling behavior (e.g. assert/ASSERT/stderr-print/abort/exception) in
winpty.dll and the other targets.
2016-01-18 00:10:02 -06:00
Ryan Prichard
834195074a The debugserver also needs FILE_FLAG_FIRST_PIPE_INSTANCE now. 2016-01-17 17:58:53 -06:00
Ryan Prichard
413f17a81e Rename c99_snprintf to winpty_snprintf and expand the header file.
* The c99_snprintf function was not actually a C99-conformant snprintf
   function, except perhaps when compiled for Cygwin/MSYS.

 * MSVCRT.DLL exposes _vsnprintf, _vswprintf, _vscprintf, and _vscwprintf,
   which are the four most relevant and fundamental printf functions.  It
   *doesn't* expose a function like _scprintf, even though MSDN documents
   it.  It seems that the simple wrapper functions are linked statically
   even when linking dynamically to the MS CRT.

   It appears that MinGW and MinGW-w64 generallY provide these four
   functions in all configurations.  Therefore, for predictable behavior,
   always use these functions.

 * Examples of non-predictability:

    - MinGW declares _vscprintf but not _scprintf.  MinGW-w64 declares
      both.
    - MinGW and MinGW-w64 sometimes override some printf functions with
      their own versions.  (It's easy to tell when this happens because
      "%zd" starts working.)  With MinGW, -std=c99 enables the overrides,
      as does -std=c++11.  -std=gnu++11 does NOT enable the overrides.
    - When the overrides are not in effect, MinGW declares swprintf as
      taking no size parameter.  When the overrides ARE in effect, MinGW
      does not declare swprintf.  MinGW-w64 and MSVC prefer swprintf with
      a size parameter, but they overload it in C++ mode to allow calling
      it either way.  Cygwin and ISO C require the size parameter.
    - With overrides off, MinGW's snprintf is still the MinGW override
      function.  MinGW-w64's snprintf instead calls MSVCRT.DLL _snprintf.
      MinGW-w64 changes its PRI??? strings when overrides are enabled, but
      MinGW does not.

 * In the native Windows mode, which I'm more interested in anyway, it's
   fairly easy to calculate the length of a formatted string before
   outputting it.  Add a few wrapper functions that do this.  I could
   enhance StringBuilder with easy ways to add stdio-formatted strings.
   Of course, these sizes are only valid if they're computed by the same
   printf implementation that writes into the string, and they will be.

Work around a MinGW header-file non-idempotency bug w.r.t _vscwprintf
2016-01-17 17:58:25 -06:00
Ryan Prichard
ede3244c26 Switch from std::[w]stringstream/std::cout to [W]StringBuilder/fwrite
Remove all references to the iostream and sstream headers from code in the
src directory.
2016-01-17 00:40:28 -06:00
Ryan Prichard
cf76665cfe Add a StringBuilder class that resembles an efficient std::stringstream 2016-01-16 23:46:15 -06:00
Ryan Prichard
ba0e3a49fd Remove a few unused assert.h includes. 2016-01-16 15:09:24 -06:00
Ryan Prichard
f2c4f6a59b Add a clean-msvs target for cleaning up after gyp and VisualStudio/msbuild 2016-01-16 13:27:52 -06:00
Ryan Prichard
f04774eb06 Try to fix an issue where make fails if a header file disappears
Currently, when a header file is removed (or renamed), there is a stale
dependency file still referring to the header, and GNU make aborts, because
the header is missing.  Attempt to work around this by adding a pattern
rule to generate any header in `src/`.  The rule prints a warning message.

The C source file whose header was missing will be recompiled because a
dependency was rebuilt.  Once it is, the removed header should be removed
from the dependency file.

(Aside: FWIW, the "ninja" build tool knows directly about depfiles, and it
does not have this problem.)
2016-01-16 12:49:05 -06:00
Ryan Prichard
840847624d Split error codes and flags into a separate file for the agent's sake. 2016-01-16 02:45:33 -06:00
Ryan Prichard
f6c6f0558e Add __attribute__((format)) to trace and c99_snprintf, fix two mismatches 2016-01-16 00:03:27 -06:00
Ryan Prichard
a532a7ce3b winpty-debugserver: add an --everyone flag to let other users log messages
* In general, harmonize the debugserver named pipe with the other named
   pipe instances: don't let remote users log messages and fail if the
   pipe already exists.
2016-01-15 23:41:52 -06:00
Ryan Prichard
1ec380ad61 Improve named pipe security
* Set the PIPE_REJECT_REMOTE_CLIENTS flag on Vista and up.

 * Set a DACL on named pipes that gives full control to the built-in
   administrators, the local system account, and the current security
   token's owner SID.  This is the same DACL that is used by default,
   except that the default also grants read access to the Everyone group
   and the anonymous account.

 * Also define WINVER=0x0501, because MinGW's sddl.h only defines
   ConvertSidToStringSidW and ConvertStringSidToSidW if WINVER is defined.
   (Ordinarily, defining _WIN32_WINNT is sufficient, and it's even
   sufficient with the i686-pc-mingw32-g++ compiler packaged with Cygwin.)

 * The createSecurityDescriptorOwnerFullControlEveryoneWrite function is
   not currently used (or tested), but I think I'll use it in the debug
   server to allow collecting trace output from other accounts on the
   machine.  (I think I'll make that behavior optional.)

I tested this commit with all of the supported compilers: MSYS1 MinGW,
Cygwin MinGW, MSYS2 MinGW-w64, Cygwin MinGW-w64, MSVC2013, and MSVC2015.
The code compiles and runs in all of them.  I also examined the DACL
attached to the control pipe, and its SDDL string looked correct.
2016-01-15 23:35:01 -06:00
Ryan Prichard
1fafbc2ef5 Strengthen unique pipe name generation.
* PIDs are recycled, so include the system time.

 * A program running on the same machine could predict the names of pipes
   winpty uses and block winpty, causing a denial-of-service.  I'm not sure
   this is really a concern, but I suppose in principle it is?  Try to
   guard against it by appending random bytes to the pipe name.  The
   CreatePrivateNamespace API looks relevant, but I'm not sure it applies
   to named pipes, and it's Vista only.
2016-01-15 18:55:43 -06:00
Ryan Prichard
95be1c291f Remove the ASSERT from OsModule to make it more suitable for winpty.dll 2016-01-15 18:50:24 -06:00
Ryan Prichard
fe60984ce4 Work around -std=c++11 MinGW compiler problem
This bug was already fixed 5 months ago, but AFAICT MinGW.org hasn't
released it yet.  MinGW-w64 is unaffected, as is the MinGW compiler
packaged with Cygwin.
2016-01-15 03:21:50 -06:00
Ryan Prichard
6b31bd9d8c Initial draft of a rewritten libwinpty with a new API.
The new API improves upon the old API in a number of ways:

 * The old API provided a single data pipe for input and output, and it
   provided the pipe in the form of a HANDLE opened with
   FILE_FLAG_OVERLAPPED.  Using a bare HANDLE is difficult in higher-level
   languages, and overlapped/asynchronous I/O is hard to get right.
   winpty_close closed the data pipe, which also didn't help things, though
   I think the handle could have been duplicated.

   Using a single handle for input and output complicates shutdown.  When
   the child process exits, the agent scrapes the final output, then closes
   the data pipe once its written.  It's possible that a winpty client will
   first detect the closed pipe when it's writing *input* rather than
   reading output, which seems wrong.  (On the other hand, the agent
   doesn't implement "backpressure" for either input or output (yet), and
   if it did, it's possible that post-exit shutdown should interrupt a
   blocked write into the console input queue.  I need to think about it
   more.)

   The new API splits the data pipe into CONIN and CONOUT pipes, which are
   accessed by filename.  After `winpty_open` returns, the client queries
   pipe names using `winpty_conin_name` and `winpty_conout_name`, then
   opens them using any mechanism, low-level or high-level, blocking or
   overlapped.

   (There are still many open design issues in this part of the API.)

 * The old libwinpty handled errors by killing the process.  The new
   libwinpty uses C++ exceptions internally and translates exceptions at
   API boundaries using:

    - a boolean error result (e.g. BOOL, NULL-vs-non-NULL)
    - a potentially heap-allocated winpty_error_t object returned via an
      optional winpty_error_ptr_t parameter.  That parameter can be NULL.
      If it isn't, then an error code and message can be queried from the
      error object.  The winpty_error_t object must be freed with
      winpty_error_free.

 * winpty_start_process is renamed to winpty_spawn.  winpty_open and
   winpty_spawn accept a "config" object which holds parameters.  New
   configuration options can be added without disturbing the source or
   binary API.  There are various flags I'm planning to add, which are
   currently documented but not implemented.

 * The winpty_get_exit_code and winpty_get_process_id APIs are removed.
   The winpty_spawn function has an out parameter providing the child's
   process and thread HANDLEs (duplicated from the agent via
   DuplicateHandle).  The winpty client can call GetExitCodeProcess and
   GetProcessId (as well as the WaitForXXX APIs to wait for child exit).

As of this libwinpty rewrite, all code outside the UNIX adapter uses a
subset of C++11.  The code will build with MSVC2013 or newer.  The oldest
MinGW G++ I see on my machine is the somewhat broken MinGW (not MinGW-w64)
compiler distributed with Cygwin.  That compiler is G++ 4.7.3, which is
new enough.
2016-01-15 03:21:50 -06:00
Ryan Prichard
d72f4a44f8 Get many misc test programs compiling again after the src reorg 2016-01-15 03:08:10 -06:00
Ryan Prichard
42cac8d24d Add a new debugflag, "input_separated_bytes", for testing incomplete input 2016-01-14 17:30:25 -06:00
Ryan Prichard
48e01facf4 Don't generate mouse input records on an incomplete mouse escape sequence 2016-01-14 17:02:59 -06:00
Ryan Prichard
79c9859805 Add missing copyright notices to WinptyVersion.{cc,h} 2016-01-05 06:43:29 -06:00
Ryan Prichard
f64a108868 Replace ASSERT with assert in TimeMeasurement.h
libwinpty does not include the agent's ASSERT mechanism currently, and
I'm only using this class during development.
2016-01-05 06:43:28 -06:00
Ryan Prichard
992cfcb363 Remove a copy of OsModule from ConsoleFont
This exact same class exists in src/shared.  It only compiles because the
copy in ConsoleFont is in an anonymous namespace.
2016-01-05 06:43:27 -06:00
Ryan Prichard
9086097c5c Fix a typo: this constant should have been unsigned.
Should have no effect at runtime.
2016-01-04 19:09:51 -06:00
Ryan Prichard
8292a8ef4f Flush winpty-agent --show-input output
This is useful when winpty-agent is invoked from the Win32-OpenSSH server,
which uses a proper console for STDIN, but sockets(!) for STDOUT and
STDERR.  The C++ runtime uses block buffering on the socket output, so
flush explicitly.
2016-01-04 19:09:50 -06:00
Ryan Prichard
eebc10bf36 gyp file: Remove the ".lib" suffix from "-luser32.lib" and document.
gyp tolerates all of:

  'user32'
  'user32.lib'
  '-luser32'
  '-luser32.lib'

With the --format=make generator, the exact string value is passed to gcc,
which only accepts the '-luser32' syntax.  The MSVC generator is also
happy with this format, so that's what I'll use.

With this change, it's possible to use the gyp file to build the C++
components.  I'm not sure if that's useful, but why not?  The resulting
Makefile can be configured by passing settings like CXX and LDFLAGS on the
make command-line.

Also: document use of gyp a bit.
2016-01-03 17:29:09 -06:00
Ryan Prichard
b45220b00d Mark *.gypi as text 2015-12-29 18:40:08 -06:00
Ryan Prichard
2ae966521e gyp improvements:
* Add a src/configurations.gypi file that can be included on the gyp
   command-line to enable 32-bit and 64-bit builds in the generated project
   files.

 * Make winpty.gyp work if gyp is run with Cygwin python.  It still works
   with normal python.
2015-12-29 18:33:55 -06:00
Ryan Prichard
f5e8b4cd28 Fix a possible concurrency issue with CancelIo and winpty shutdown.
CancelIo requests that the I/O operation end, but the I/O operation may
still be going when the function returns.

https://blogs.msdn.microsoft.com/oldnewthing/20110202-00/?p=11613/
2015-12-28 21:57:12 -06:00
Ryan Prichard
0fb98c03fa Recompile everything if VERSION.txt changes
The contents of that file are included on the compiler command-line for
every file.
2015-12-28 21:57:11 -06:00
Ryan Prichard
1c3f54caf4 Bump the version 2015-12-28 21:57:10 -06:00
Ryan Prichard
6720daa07a Avoid a possible buffer overflow in winpty-debugserver.exe
Also: use fwrite directly instead of printf; maybe it's a bit faster.
2015-12-24 21:25:06 -06:00
Ryan Prichard
6c8b7effe5 Add a TimeMeasurement class useful for measuring the run-time of code 2015-12-21 00:43:26 -06:00
Ryan Prichard
12935a722b Minor code fixup:
* Explicitly call the Unicode versions of various APIs

 * Add const in a couple of places

 * Improve a few assert error messages

 * Either initialize BackgroundDesktop fully or leave all its fields NULL
2015-12-20 23:56:24 -06:00
Ryan Prichard
83b6e9281d 0.2.1 -- update VERSION and changelog 2015-12-20 00:02:45 -08:00
Ryan Prichard
2cc2480b38 For --mouse: start by disabling mode 1005.
AFAIK, this change doesn't affect any actual terminals, but in theory, it
could matter.
2015-12-19 23:58:13 -08:00
Ryan Prichard
75fe19ae96 Respect the console's Quick Edit mode -- it suppresses mouse events
* winpty-agent: Respect the ENABLE_QUICK_EDIT_MODE flag.  If it's set,
   then mouse events are not generated (because they're supposed to control
   selection).

 * winpty-agent: Because of the above, turn ENABLE_QUICK_EDIT_MODE off at
   startup.

 * winpty-agent --show-input: Enable ENABLE_WINDOW_INPUT so we can see
   buffer resize events.

 * winpty-agent --show-input: Disable ENABLE_QUICK_EDIT_MODE with
   --with-mouse.  When Quick Edit mode is enabled, the mouse controls
   selection and does not produce mouse events in the input queue.
2015-12-16 19:52:45 -06:00
Ryan Prichard
f7e5e1f69a Update the release notes 2015-12-16 06:30:58 -06:00
Ryan Prichard
63ed815319 Get build/trivial_test.exe building again. 2015-12-16 06:22:25 -06:00
Ryan Prichard
4e6f0c852f Update the release notes for mouse support 2015-12-16 06:22:25 -06:00