The UNIX philosophy is that everything is a file, so you can read and write from files and pass data around with convenient tools... that mindset is also missing in Windows.
Command lines were not foreseen as a preferred way of interacting with the system in Windows until recently. PowerShell tried to fill some gaps, and many tools integrate with it... but it's not the same. It has a long way to go.
NT is more Unix than Unix in a lot of ways, where everything is an object (more or less)
Plan 9 though really ran with the whole file thing
Yep. NT's design in this respect is great. Each NT object also has a name in a global system namespace; each object has its own access control list; and most objects are dispatcher objects that you can use with functions like WaitForMultipleObjects. In Windows, it's trivial to wait for, say, a socket* and a process at the same time.
I've always wanted to add NT-style process handles to Linux. A few other people have tried, but Linus has rejected their patches on the grounds that if you can open a handle to a process (preserving its PID), a program can fill up the process table.
I've never bought this argument. You can fill up the process table in other ways today without a ulimit, and we can make the process ulimit apply to process handles too.
...
* Screw you, in-process winsock providers. My programs treat sockets as regular HANDLEs, and if you install some shim that breaks this model, shame on you.
Plan 9 did it right if you want to go "everything is a file"
For Linux subsystem processes fork works pretty well, but they are different animals
Message loops are per-thread and per-HWND (which are thread-affine) anyway. One way of making fork "make sense" in win32 processes is to say "Okay, you can fork, but your new process begins execution in a new thread, and none of the old threads survive."
New thread means new message loop. You could even do things like automatically tear down single-threaded COM apartments in the child process.
1) readline hardcodes the backslash in a bunch of places, especially in history expansion. Psh needs '^', not '\'.
2) the psh hosting APIs aren't ready: powershell.exe uses a few internal APIs to which other hosts don't have access, and without these APIs, psh does helpful things like wrap lines at 80 characters and paginates output.
I also recall there being some problem with psh's completion.
Still, it's amazing that embedding the CLR and posh inside a Cygwin process works at all.
IIRC, the only thing at this point stopping Microsoft creating a pseudoconsole API based on real, honest-to-god kernel HANDLEs is a willingness to externalize, document, and support what has been until now a Windows-internal API.
[1] https://msdn.microsoft.com/en-us/library/windows/desktop/ms7...
Aside: About a year ago, I studied how the console handles worked (especially in relation to console attach/detach/alloc and CreateProcess), and I discovered a bunch of interesting things. For example, the "fake" handles were inherited regardless of the bInheritHandles parameter to CreateProcess, and an entire "ConsoleHandleSet" was inherited if a process attached to another process' console. Real handles in Win8 seemed to be either "bound" to a particular input/screen buffer or "unbound" so they worked with any attached console. It was possible to have a console open with no attached processes.
I tried to formalize the behavior I observed here: https://github.com/rprichard/win32-console-docs
In the course of testing, I found some neat bugs like:
- A small program that blue-screens Vista
- The inheritable flag on a console handle can be changed on any Windows version, except for Windows 7.
- CreateProcess has an undocumented(?) behavior where it duplicates stdio handles into the new process rather than inherit them. (The handle values will generally change.) Up until Windows 8.1, a stdio handle of INVALID_HANDLE_VALUE was duplicated into a true handle to the parent process. (Because INVALID_HANDLE_VALUE is actually the GetCurrentProcess() pseudo-handle, you see.)
- Assorted inconsistencies in Windows XP and WOW64 (probably fixed in newer OSs).
I'm not sure how much confidence I have in the spec. It is backed by a big test suite, but there are so many cases to consider.
[1] https://github.com/Microsoft/BashOnWindows/issues/111#issuec...
Cool. There's a third option that you might want to consider for winpty. (I was experimenting with it before I left Microsoft.)
The basic idea is to use a DLL shim to provide your own console API implementation for a process and its children --- you can replace the system console API with your own by shimming DLL import and export tables. You'd use your own type of pseudohandle for your fake console handles; programs written to work with the old console pseudohandles should work correctly with your pseudohandles, provided you've hooked the relevant HANDLE-using APIs.
I was assuming I'd use genuine console handles, but recognize that they're associated with the special console, so divert their API calls.
Maybe the technique would make programs slower. I know that's a complaint people have about ConEmu.
There's a similar (4th?) technique I've considered -- instead of hooking every process attached to the console, hook APIs in the conhost process and reimplement the internal protocol. It should avoid the performance problems and confine the hackiness to one address space. The trouble is that the protocol is undocumented. A small change could break everything without warning, but MS could also redesign the whole thing, making a fix impossible.
The other interesting problems I found with that API were: (1) when editing an input line, EVENT_CONSOLE_CARET notifications were delayed, (2) if I hit ESC when editing an input line, the line would clear, but there'd be no update-region notification, and (3) it's impossible to distinguish between a call to ScrollConsoleScreenBuffer and the whole buffer scrolling because we've reached the end. ScrollConsoleScreenBuffer might scroll only part of the buffer.
winpty doesn't use the WinEvents API (yet), but it might be good enough to reduce polling when the console is idle.
You mean like on current up-to-date versions of Vista and Server 2008? With a PoC on the github page? You realise that you have found a security vulnerability and are disclosing it publicly, right? Userspace must never crash the kernel, even if not further exploitable, especially so if it's possible for an unprivileged user. Be responsible, send a mail to [email protected]
I did report it to Microsoft before making it public. The reply was:
> Thank you for contacting the Microsoft Security Response Center (MSRC). I would suggest trying on a local VM to confirm BSOD. However, this currently is just a local DOS, which would would not be something we would investigate further. If you have any additional information on how this could be further used to exploit another user or a remote DOS, please let us know and we will look into it.
> For an in-depth discussion of what constitutes a product vulnerability please see the following:
> "Definition of a Security Vulnerability" <https://technet.microsoft.com/library/cc751383.aspx>
>Again, we appreciate your report.
Update: it looks like the NULL pointer is accessed several times in the code. They mostly are 16-bit accesses, so it is probably not addresses. They seems to be in font-related code.
For a command line interface, I find it to be fairly unstable, too.
Basically, I've defined a function my profile to:
* Save the ConEmuHooks environment variable value * Set it to "Off" * Execute vim * Reset it to the previous value
I alias this command to "vim".
It's not pretty at all, and it caused me to use Sublime or VSCode most of the time, but it worked for me.
More info here: http://conemu.github.io/en/ConEmuEnvironment.html
Also, Emacs has a mode where it'll run as a Cygwin process, but use native win32 widgets. I've found using it to be the most pleasant way of interacting with Windows systems.
When I was at Microsoft, I joked that I wasn't so much running "Windows" as GNU/NT. :-)
I haven't experienced the instability that others have but I do find its configurability a bit excessive. Somehow I want it to be much simpler but still do everything that it does now. I don't know the way to achieve this but I believe it's possible.
Conemu does a decent job given all the restrictions the Windows platform has, but it's still miles behind a real Linux terminal emulator.
For the uninitiated: cmd.exe is the shell, like bash. conhost.exe is the terminal emulator, like xterm. bash or cmd (the shell) talks to the terminal via its standard input, output, and error file handles. Terminal handles are like full-duplex pipes, but richer: they transmit all the information needed for interaction with the user. Each terminal handle has two ends: master* and slave. The slave is the terminal to which cmd or bash talks; it basically emulates a teletype. The master handle allows for reading both in-band and out-of-band information from the slave terminal handle and supports special APIs that allow anyone with access to the master handle to fully emulate a terminal.
POSIX systems allow anyone to create master and slave terminal handles. When you start xterm, xterm calls openpty, gets master and slave handles, starts your shell with the slave handle, and uses the master terminal to get the information needed to draw characters.
There's no equivalent for Windows. The only Windows program that can call the Windows equivalent of openpty is conhost, which ships with the operating system. It's not possible for a different program to make a master-side terminal handle. There are two workarounds, which both suck: 1) use pipes, not console handles, and 2) make a hidden conhost.exe and scrape it. The former causes programs to think they're being run non-interactively, with all sorts of negative side effects (like excessive buffering). The latter loses screen updates, is inefficient, and is generally awful.
Microsoft could easily make this situation much better by opening the protocol that conhost uses to communicate with the kernel. If any program can create a console handle, it's much easier to implement things like ssh daemons, Cygwin, and terminal emulators that suck less than conhost.
...
* As an aside: when bash talks to xterm, it uses in-band signaling (mostly: see termios): it sends control code sequences, which xterm understands as "move cursor to 3,3" and "set color to green". By contrast, when cmd communicates to conhost, it uses out-of-band signaling: it uses special API functions to move the cursor and set the text color.