* At least for now, I'm shipping Cygwin/MSYS binaries. On Cygwin (but
not MSYS), the console.exe executable previously linked dynamically
to cyggcc_s-1.dll and cygstdc++-6.dll.
Linking dynamically with cygstdc++-6.dll seems risky for a binary
not distributed by Cygwin, because G++'s Windows ABI is unstable, at
least as of G++ 4.7, which turned on the __thiscall calling
convention. If a binary I ship ever comes into contact with a
4.7-versioned cygstdc++-6.dll, then my binary will (very likely)
segfault.
So far, I've only observed this ABI incompatibility with MinGW,
where a sufficiently upgraded MinGW configuration comes with a
libstdc++-6.dll that is completely incompatible with every previous
libstdc++-6.dll, so that every program built against the older
libstdc++-6.dll segfaults immediately. For now, Cygwin seems stuck
at G++ 4.5, and my impression (possibly incorrect), is that G++'s
Windows ABI was stable prior to 4.7. I think G++'s Linux ABI is
stable. Presumably Cygwin will eventually update its compiler,
though, so it makes sense to fix the problem early.
I believe I originally chose to dynamically link the libraries
because it was the default behavior, and I was afraid that a
non-default option would break something. It turns out that
linking statically with cygstdc++-6 *does* break something -- it
causes linker errors if the code uses std::cerr. The workaround
is not to use std::cerr. This is not a problem for the
unix-adapter, which already has to put up with MSYS' gimpy G++ 3.4
compiler.
This should fix issue 5.
The copying appeared to be necessary only for Cygwin, not for MSYS. I'm
not sure why this is. I added a call to cygwin_internal(CW_SYNC_WINENV)
for both anyway, because I didn't think it would hurt.
* Quoting is needed for empty arguments (i.e. put double-quotes in the
command line) and for arguments containing tabs because both spaces and
tabs can separate arguments.
* A double-quote in the argument doesn't by itself necessitate quoting.
* As of this change, argvToCommandLine quotes an argument in the same
cases as Python's subprocess module.
* This avoids a name conflict with an existing unrelated project.
* I think winpty is a better name anyway. (i) It's more obviously
Windows-related. (ii) I think it more accurately describes what it
does. A "pseudo-console" ought to mirror the console API and allow
replacing the implementation built-in to Windows. This project is only
trying to provide functionality similar to using the master interface of
a Unix pty, but for native console programs.
* Work around UNICODE deficiencies:
- MSYS does not have wstring.
- mbstowcs(NULL, text, 0) returns 0 on MSYS instead of returning the
length of the converted string.
- printf("%ls") does not work on MSYS.
It doesn't work because it leaves in the Cygwin-style paths in variables
like PATH and TMP.
(Also, it doesn't build with MSYS because MSYS's old G++ toolchain lacks
std::wstring.)
I suspect that the library API (pconsole_open) should not be calling exit
if it can't start the agent process, but I don't want to deal with that
right now.
* Also propagate the UNIX environment to Win32. This code doesn't really
work because variables like PATH need path-translation, but I'd like to
save a record of it before killing it off.
- In my MSYS environment, gcc/g++ are the MinGW compilers that target
Win32. We really need compilers that target the MSYS environment.
Add a config-unix.mk for building the unix-adapter.
- My MSYS environment lacks a pipe2 function, but I can get the same
effect using pipe and fcntl, so do that instead.
- In the agent, poll for the process exit at the same time we pull for
output. Once the child exits, record the exit code and close the data
pipe.
- In the unix-adapter, shut the program down once the input or output
handlers abort. Before exiting, query the agent for the exit code.
- Also: in the unix-adapter, apparently receiving the SIGWINCH signal can
interrupt both select and the InputHandler's read system call. I hope
it doesn't affect the blocking Win32 APIs, but I'm not really sure.
- Update the Agent to use separate control and data pipes and to receive
arbitrary-sized packets. Handle child process creation in the agent.
- Fix bugs in libpconsole:
- Insert a space between the pipe names on the agent command line.
- Don't close the desktop and window station until after connecting
to the agent's pipes.
- Change the format of the pconsole_start_process env parameter from an
array of wide-character-string pointers to a single contiguous block of
memory, like that accepted by CreateProcess.
* Remove obsolete comments and APIs.
* In pconsole.exe, use two threads to handle pconsole<->pty communication.
I use blocking I/O for the pty. For the Win32 pipe to the pconsole
agent, I use overlapped I/O and emulate blocking I/O.
I'm not sure I *have* to open the pipe in overlapped mode. When I last
tried using non-overlapped I/O, I had a problem where a pending read
would block writes (or vice versa). Maybe setting the overlapped
parameter to {Read,Write}File would be sufficient.