After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 588828 - gio should have a Console class
gio should have a Console class
Status: RESOLVED OBSOLETE
Product: glib
Classification: Platform
Component: gio
unspecified
Other All
: Normal enhancement
: ---
Assigned To: gtkdev
gtkdev
Depends on:
Blocks:
 
 
Reported: 2009-07-17 00:24 UTC by Colin Walters
Modified: 2018-05-24 11:55 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Colin Walters 2009-07-17 00:24:07 UTC
It'd be useful if gio had a class explicitly representing "the console", i.e. the controlling terminal on unix, and the win32 console streams on win32.

Something roughly like http://java.sun.com/javase/6/docs/api/java/io/Console.html probably.
Comment 1 Allison Karlitskaya (desrt) 2009-11-26 17:20:46 UTC
ya!  srsly!
Comment 2 Allison Karlitskaya (desrt) 2009-11-26 17:22:27 UTC
Actually, just to verify: we're talking about stdin/out here, right -- not /dev/tty?
Comment 3 Tor Lillqvist 2009-11-26 20:22:26 UTC
And what's wrong with stdin and stdout then, if that is what we are talking about, and not /dev/tty?

I don't think Java's (or .NET's) "Console" is a reason to introduce something similar in GLib. It has always seemed a bit silly to me that "Console" there actually means "whatever stdin or stdout is (re)directed from/to". The "Console" name would make me think of something curses-like or whatever to access the terminal (emulator) associated with /dev/tty, or on Windows its concept of console window.
Comment 4 Matthias Clasen 2009-11-26 20:27:58 UTC
I share tmls sentiment here.
Comment 5 Allison Karlitskaya (desrt) 2009-11-27 05:47:12 UTC
Both use cases make sense.

I guess we should probably have some sort of g_input_stream_new_for_stdin() and g_output_stream_new_for_std{out,err}() or something like that.

If we want to do /dev/tty-style console properly (and I'm not sure its necessary) then we could have a GIOStream for that.
Comment 6 Colin Walters 2009-11-30 16:24:06 UTC
ttys are in scope; when connected to a tty, the GIOConsole would have a few high level operations like g_console_read_password ().
Comment 8 Dan Winship 2013-01-25 14:28:28 UTC
As singletons, the console class and stdin/out/err streams probably ought to be thread-safe. (The streams already are I guess, assuming you don't make any of the changes mentioned below.)

It seems weird to have static methods for some things, but a singleton with instance methods for other things.

It also seems weird to have a stdout stream that doesn't implement printf. :)

Which leads to the thought: should stdout and stderr get automatically wrapped in GDataOutputStreams, and stdin in a GDataInputStream? (Not that GDataOutputStream implements printf either, but it could...). In particular, if we don't have a single canonical buffered stdin/stdout, then different parts of code might create their own wrapper buffered streams around them, and then the fact that they have separate buffers will lead to wackiness (especially on the input stream, where there's no way to "unflush" any buffered input). Alternatively, if you didn't want them to be always buffered, you could have separate get_stdout() and get_buffered_stdout(), but they'd be linked together so that if you wrote something to the non-buffered stdout, it would automatically flush the buffered stdout first, and if you read from the non-buffered stdin, it would read the remaining buffered stdin first. Or just have APIs to turn buffering on/off on a single stream...

And then, if the streams are going to be clever like that, then you could move the status line API onto GStdoutStream, and remove the _end_status_line method, because the stdout stream itself would know when it was doing a status line, and could just stop as soon as you did a non-status-line write. And the password API could be g_stdin_stream_read_password(), and then you don't need the console class at all...

OTOH, I note that you didn't port any of the non-status-line g_print()s in ostree to use the stdout stream, so maybe this is all irrelevant because people mostly won't be using the streams as a replacement for the existing stdio APIs and so we don't have to worry about these use cases.
Comment 9 Colin Walters 2013-01-25 15:09:21 UTC
You're totally right about thread safety - g_print() is threadsafe today because it calls into FILE * which in glibc is thread safe by default.

Buffering is a complex topic.  See "man setbuf".  It's very important for the stdio streams that if connected to a tty, we match the libc behavior of being line-buffered.

So maybe both of these argue for custom stream implementation which wraps the FILE * rather than the raw descriptors.

The downside with that is we'd have to jump through the same hoops GUnix{Input,Output}Stream do to implement GPollableOutputStream.  It's possible to share code though.

I think you're definitely right about separate classes.  But how would the user determine whether or not special "console" methods were available?  Would we just have 

GOutputStream * g_stdout_stream_get(void);

and they'd have to do:

if (G_IS_CONSOLE_OUTPUT_STREAM (out))
  pretty_status_line ((GConsoleOutputStream*)out);
else
  g_output_stream_write (out, "Working...");

?
Comment 10 Dan Winship 2013-01-25 15:43:54 UTC
(In reply to comment #9)
> Buffering is a complex topic.  See "man setbuf".  It's very important for the
> stdio streams that if connected to a tty, we match the libc behavior of being
> line-buffered.

Actually, I think the "fully buffered" mode was a bad design decision in C, because it means that programs behave differently when you redirect their output to a file. (Eg, the program may crash with some logging output still unflushed. Or if you redirect both stdout and stderr, they'll be interleaved incorrectly.) I think we should always default to line-buffered regardless of isatty().

> But how would the user
> determine whether or not special "console" methods were available?  Would we
> just have 
> 
> GOutputStream * g_stdout_stream_get(void);
> 
> and they'd have to do:
> 
> if (G_IS_CONSOLE_OUTPUT_STREAM (out))
>   pretty_status_line ((GConsoleOutputStream*)out);

i was imagining that g_stdout_stream_get() would always return a "GStdoutStream", and you could call g_stdout_stream_is_console() to see if it was attached to a console or not.

(Or maybe "GStandardOutputStream"... although I guess the stdout and stderr streams would probably be the same GType, so you wouldn't want a name that too strongly implied it was only stdout... Or we could have GStandardErrorStream as a no-op subclass of GStandardOutputStream...)
Comment 11 GNOME Infrastructure Team 2018-05-24 11:55:39 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to GNOME's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/glib/issues/232.