[Mono-dev] Problem with Console.In.Peek() [hungs]

Jonathan Pryor jonpryor at vt.edu
Sat May 6 07:44:35 EDT 2006


On Sat, 2006-05-06 at 00:59 +0200, Manfred Braun wrote:
> I am new on the road to make some things on my Unix box [which is
> NetBSD 3.0/i386] and I started using some simple console programs. My
> problem is, that the method "Console.In.Peek()" hungs, if no input
> stream is provided and I just execute the application.

So if you do this:

        $ mono ct.exe
        Test.

The program hangs.  That's by design. :-)

You are incorrect in your statement that "no input stream is provided"
-- an input stream *is* provided, the console you're typing at.

Furthermore, the documented return value of Peek() is this:

        The next character to be read, or -1 if no more characters are
        available or the stream does not support seeking.

Since your program is reading standard input, and you haven't typed
anything, there is no next character to read, more characters _may_ be
available (end-of-stream hadn't been reached yet), and the underlying
stdin stream _is_ seekable (at least in the forward direction, ignoring
anything previously entered).

Since none of those circumstances are met, the method "hangs" waiting
for input from the console.

So to fix the "hang", provide some input, such as "a<RETURN>" or Ctrl+D
(which ends the stream).  Typing Ctrl+D will generate a -1 return value,
as expected (because there was no data within the stream).

> So no wonder, that MS has the Console.In/Out implemented as TextReader
> and not as some stream

Exposing Console.In/Console.Out as a Stream still wouldn't help you, for
the precise reasons stated above -- the stream hasn't been closed yet
(so no EndOfFile for you, which System.IO.Stream doesn't have anyway!),
the stream is seekable, and no data is available.  So you'd still end up
blocking, waiting for some data to appear.

> and there is no way to make a connection between that, what the
> console is and a device, like the keyboard and or the screen/terminal.

Define "make a connection".  System.Console.SetIn() allows you to set a
new TextReader, and nothing stops you from opening /dev/hda1 into a
Stream and constructing a StreamReader around that, e.g.

	System.Console.SetIn (new System.IO.StreamReader (
		new System.IO.TextReader (
			new System.IO.FileStream ("/dev/hda1",
				System.IO.FileMode.Open,
				System.IO.FileAccess.Read)
		)
	));

This probably won't work (/dev/hda1 is unlikely to have character
data :-), but you get the point -- any device that has character data
can become the source of System.Console.In.

Granted, you can't tell what device System.Console.In is connected to,
but you usually can't tell that on Unix anyway (except for isatty(3),
which only tells you the file is a TTY, but it won't tell you what
file/device you're actually reading).

> Does Mono implement the usual signals for processes so far?

If you want to handle Unix signals, see
Mono.Unix.Native.Syscall.signal(), within Mono.Posix.dll.

 - Jon





More information about the Mono-devel-list mailing list