Commit Graph

55 Commits

Author SHA1 Message Date
Ryan Prichard
00a6c3b90e Shut down the unix-adapter when the child process exits.
- 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.
2012-02-20 03:30:43 -08:00
Ryan Prichard
90164c34a9 Get the agent + libpconsole + unix-adapter trio working.
- 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.
2012-02-20 01:23:46 -08:00
Ryan Prichard
27f0c4d156 Get pconsole.exe and pconsole.dll building simultaneously.
* 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.
2012-02-16 03:49:17 -08:00
Ryan Prichard
40c7e87528 Checkpoint work on libpconsole. 2012-02-10 02:09:38 -08:00
Ryan Prichard
a53fcbbea6 Checkpoint work on libpconsole. 2012-01-31 00:45:04 -08:00
Ryan Prichard
19d9c1832c Add a Unix pty<->pconsole adapter. 2012-01-28 14:23:31 -08:00
Ryan Prichard
1aaf102905 Get libpconsole.dll building again with stubbed out functions. 2012-01-27 10:08:21 -08:00
Ryan Prichard
c0918b6db4 Update pconsole.h with a new non-blocking pconsole API.
This API is not implemented yet, so the code no longer builds after this
commit.
2012-01-27 09:05:34 -08:00
Ryan Prichard
b0555bbbcf Update the libpconsole's agent-finding code.
Look for the new pconsole-agent.exe program, and look for it in its new
location.
2012-01-23 22:05:37 -08:00
Ryan Prichard
410749a1b9 Update the TestNetServer.
- Replace the qmake pro file with a Makefile.

 - Move the AgentClient from Shared to TestNetServer.  This file is
   obsoleted by libpconsole.
2012-01-23 22:04:34 -08:00
Ryan Prichard
3abee55179 Work on agent's build system. 2012-01-21 17:39:22 -08:00
Ryan Prichard
4350fd40d5 Remove cruft. 2012-01-21 17:33:41 -08:00
Ryan Prichard
7e4c06c2e1 Rename Agent to agent. 2012-01-21 17:32:26 -08:00
Ryan Prichard
a4df196ed4 Work on switching from qmake to makefiles and reorganize code a little.
My plan now is to integrate the PseudoConsole with Cygwin and MSYS ptys,
with initial focus on Cygwin.  I think I'll keep the separate Agent and DLL
binaries, and they'll continue to be native Win32 binaries.  I don't want
to have two build systems (qmake vs whatever MSYS/Cygwin uses), and since
I'd like to remove the Qt dependency anyway, I'm trying to switch to
makefiles.
2012-01-21 17:30:41 -08:00
Ryan Prichard
e4e0effb03 Delete some dead code (Console directory) and reorganize. 2012-01-21 02:31:27 -08:00
Ryan Prichard
626849b253 Add TODO items. 2012-01-10 00:56:29 -08:00
Ryan Prichard
2aa8c26b55 Remove an unnecessary comment.
size_t wouldn't really be a reasonable type for Windows I/O because
ReadFile and WriteFile use a DWORD for byte counts.  A single I/O operation
of more than 2GB seems unreasonable anyway.
2012-01-09 01:02:11 -08:00
Ryan Prichard
a9d3250574 Remove an unused variable from AgentClient.cc. 2012-01-09 00:57:08 -08:00
Ryan Prichard
2345672c55 Add a PseudoConsole.dll library providing a client to the PseudoConsole
agent.

 * The code is based on that from AgentClient.cc, but without the Qt
   dependency.

 * The API currently uses blocking I/O.  The intent is for users to use
   a separate read thread and write thread.
2012-01-09 00:56:55 -08:00
Ryan Prichard
9ed85125db Comment out this line to reduce debug noise while I do performance testing. 2012-01-02 23:09:03 -08:00
Ryan Prichard
07317a3c8f Add a Python DebugClient. 2012-01-02 21:42:17 -08:00
Ryan Prichard
9e477bc014 Remove declarations for methods that I removed when I created the Terminal
class.
2011-11-27 02:59:37 -08:00
Ryan Prichard
b7a9415a58 Start the agent in a new window station.
The intent is to avoid a problem on Windows XP.  On that OS, sending
a "Select All" command to freeze one console window also interrupts any
"window activity" (e.g. moving/closing/scrolling/right-clicking/...) on
all other console windows.

My hope is that putting the console into a special window station will
isolate it enough to avoid this problem.  I noticed that the problem didn't
happen when I ran the TestNetServer as a service, which ran both the
TestNetServer and Agent processes with a special window station.

Note that even though the Agent runs in a special window station, the shell
and its children run in the normal window station.
2011-11-27 02:46:16 -08:00
Ryan Prichard
9f1bdd43ab Don't enable the agent auto-shutdown logic until after the TestNetServer
has started a shell.

I thought this change would fix a problem with the Windows 8 Preview where
the connection shut down immediately after starting.  It did not fix the
problem, which I still don't have an explanation for, but in any case, I
think the change is necessary.
2011-11-25 18:34:33 -08:00
Ryan Prichard
73b250da63 Support running TestNetServer as a Windows service.
* Add a note on how to use instsrv and srvany.

 * First look for Agent.exe in the same directory as TestNetServer.exe
   before looking for the executable in the build directory that Qt
   Creator uses.

 * Write a script that copies MinGW/Qt DLLs to a single directory.
2011-11-25 01:52:58 -08:00
Ryan Prichard
e9997d6372 Add another windows test case. 2011-11-25 00:02:46 -08:00
Ryan Prichard
2b4fe1c771 Add initial color support. 2011-11-24 03:03:25 -08:00
Ryan Prichard
a0e99867cd Factor some code out of Agent into a new Terminal class.
Also, now that freezing uses "Select All" instead of "Mark", remove the
cursor-related hacks from resizeWindow and scrapeOutput.
2011-11-24 03:03:25 -08:00
Ryan Prichard
bba54c0703 Use "Select All" instead of "Mark" to freeze the console.
The Mark command moves the cursor to the top-left, which interferes with
lynx, a full-screen Cygwin web browser, and probably other programs.
The Select All command also puts the console into selection mode, blocking
console output.
2011-11-24 03:03:25 -08:00
Ryan Prichard
023e5f333f Reset the terminal when the sync marker disappears or when the window moves
upward.

This commit gets the CMD/PowerShell CLS command working with the Agent.
Previously, the CLS command was broken in the following test case:
 - User opens a window of height N and types CLS.  The window now looks
   like:
    line0)
    line1) D:\rprichard\Scrape\TestNetServer-build-desktop>
 - User generates a bunch of output -- enough to scroll the window but not
   enough to create a sync marker.
 - User types CLS again.
 - The window scrolls back to the top and is cleared.
 - The agent thinks that lines [1..(N-1]] of the window (and screen buffer)
   have changed.  It omits line 0 because line 0 is blank before and after
   the CLS.  Therefore, it sends N-1 lines.  The first line is at line 1.
   We've already output a "remote line" larger than N, though, so we first
   try to CursorUp by >>N lines.
 - After moving the cursor up, we're actually on line 0 of the terminal
   instead of line 1.

I think the general rule is that it's safe to "reset the terminal," but we
want to avoid resetting because it breaks history.  For typical
command-line sessions that don't involve full-screen programs, (but which
*could* involve window resizing), I would like the history to be perfect.
2011-11-24 03:03:25 -08:00
Ryan Prichard
a364522006 Record a high-water-mark of "dirty" lines in the console screen buffer
and avoid sending lines in the window that aren't dirty yet.

The idea is that the bottom of the console screen commonly has blank lines
that do not need to be sent to the client, because nothing has been written
there yet.  For example, when the console first appears, there is typically
a command-line prompt at the top of the window.  When a console is expanded
vertically, blank lines commonly appear at the bottom.

Other misc changes to the output:
 - When we send one later, also send all following lines.
 - When we save a line into m_bufferData, fill in the rest of the line with
   spaces.  This way, it's possible to expand the console horizontally
   without the agent resending all the lines.
 - If nothing on the console has changed, then leave the cursor alone.
   Don't hide, show, or move it.
2011-11-24 03:03:25 -08:00
Ryan Prichard
b2f15c8f27 Fix terminal output bugs in the TestNet client.
* If the client was unable to write any data, write would return -1 with
   errno==EAGAIN, and the client would assert fail.

 * Apparently I thought that continue would jump to the start of the
   do-while(0) loop.  Replace the continue/do-while(0) with a
   did_something flag.

While I'm at it, replace a few hard-coded constants with constants.
2011-11-24 03:03:25 -08:00
Ryan Prichard
7e4b19dc79 Check in two test programs. 2011-11-24 03:03:25 -08:00
Ryan Prichard
9712f74b76 First cut at incremental console output scraping.
- On each polling, identify a range of lines to scan.  This range will
   include lines in the history if output has scrolled.

 - Line in scrapeOutput and the terminal output routines (e.g.
   sendLineToTerminal) are numbered as if writing to an infinitely-sized
   terminal.

 - Once history is large enough, write a string to column 1 ~200 lines
   up.  This synchronizing marker lets us know how much the console output
   has scrolled.

 - Freeze the console output by putting the console into select/mark mode.
   Unfreeze it by sending an ESC keypress.
2011-11-24 03:03:25 -08:00
Ryan Prichard
f77557aa95 Add a Win32Console class that provides a simpler, Qt/C++ interface to the
Win32 Console API.
2011-11-24 03:03:25 -08:00
Ryan Prichard
c74f82abdb Pass an initial window size to the agent on startup.
* The TestNet protocol starts with a terminal resize escape sequence, so
   the server discards all input until it sees the sequence, and it delays
   starting the agent.  Eventually, the goal is to implement an SSH server,
   and the SSH message that creates a PTY also provides the terminal size.
2011-11-24 03:03:25 -08:00
Ryan Prichard
662b140c62 Add a test program that uses the ioctl-like console interface to scroll
and write.
2011-11-24 03:03:25 -08:00
Ryan Prichard
8647405a6d Add comments regarding capturing console output. 2011-11-24 03:03:25 -08:00
Ryan Prichard
0bb71ee53c In the Unix client, send a resize escape sequence on startup and when the
terminal window is resized.
2011-11-24 03:03:25 -08:00
Ryan Prichard
166c553f15 Add initial server support for resizing terminal windows. 2011-11-24 03:03:25 -08:00
Ryan Prichard
3ae1f5f9a7 Add a TODO describing an EDIT/NTVDM-related bug. 2011-11-24 03:03:25 -08:00
Ryan Prichard
b491fd6378 Add a UnixSignalHandler class. It emits a Qt signal when a Unix signal is
handled.

Use the UnixSignalHandler to detect terminal resizing.  The client doesn't
do anything with the terminal size yet.  It should send the size to the
server.
2011-11-24 03:03:25 -08:00
Ryan Prichard
af5a742e57 Two Unix client changes:
* Use disconnected instead of readChannelFinished.

 * Fix a serious bug in doServerToClient.
2011-11-24 03:03:25 -08:00
Ryan Prichard
e3ce5c0ff0 Checkpoint work on the Windows server.
* Use disconnected() instead of readChannelFinished().

 * Cleanup.  There are three bidirectional pipes conceptually:
      console <-> agent
      agent <-> server
      server <-> client
   If one end of a pipe dies, start closing the other end, then clean up.
   If the console dies (e.g. because cmd.exe exits), we still want to
   collect the final console output and send it to the client.

   To help with this, in the Agent, I call GetConsoleProcessList, then
   scrapeOutput, then (potentially) disconnectFromServer.
2011-11-24 03:03:25 -08:00
Ryan Prichard
f9b713dc57 In the Unix client, stop the program when the read channel finishes. 2011-11-24 03:03:25 -08:00
Ryan Prichard
c0c261b2b5 Add simplistic console output polling in the server and feed the output
to the client.
2011-11-24 03:03:25 -08:00
Ryan Prichard
73bd43d051 Implement the Unix TestNet client. 2011-11-24 03:03:25 -08:00
Ryan Prichard
f70b2bd772 Add a mostly empty TestNetClient project. 2011-11-24 03:03:25 -08:00
Ryan Prichard
a7ae78b9b1 Add test programs that echo their input to stdout. 2011-11-24 03:03:25 -08:00
Ryan Prichard
d473320350 Rename TelnetServer to TestNetServer to accurately reflect its actual
functionality.
2011-11-24 03:03:25 -08:00