qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] curses.c: "We need a terminal output" ?


From: Laszlo Ersek
Subject: Re: [Qemu-devel] curses.c: "We need a terminal output" ?
Date: Wed, 17 Apr 2019 20:27:51 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.9.1

Hi Joachim,

On 04/17/19 19:09, Joachim Durchholz wrote:
> Sorry, I'm done having to argue against(!) a person who's stonewalling
> me by wilfully ignoring differences ("doesn't work perfectly"
> interpreted as "does not work at all"), discounting
> just-for-testing-purpose workarounds as if they were actual proposed
> solutions ("not a sane approach"), ignoring the use case (still
> insisting on terminal size mutability), and proposing a nonworking
> solution (-nographic does not give me any output, of course because it
> doesn't have a terminal to talk to).

you use the word "solution" twice above, but in this thread, I haven't
seen a problem statement from you.

What is the end goal you're trying to achieve?

The source file "ui/curses.c" carries the following comment at the top:

  QEMU curses/ncurses display driver

It is a display backend that is based on Curses.

Curses -- in its originally standardized form, XCURSES -- is an
interface specification for manipulating terminals. Please see:

  https://pubs.opengroup.org/onlinepubs/7908799/xcurses/intov.html

It writes:

    [...] a comprehensive API lets the application perform terminal
    operations. The Curses run-time system receives each terminal
    request and sends appropriate commands to the terminal to achieve
    the desired effect. [...]  Applications using Curses should not also
    control the terminal using capabilities of the general terminal
    interface defined in the XBD specification, General Terminal
    Interface. [...]

(I sent the link to the General Terminal Interface earlier.)

So, let's look at your original question again (which was not a problem
statement):

> what's the reasoning behind "We need a terminal output" in curses.c?

The reasoning is that "curses.c" is a QEMU display backend written in
terms of the Curses [XCURSES] interface specification, and that
interface specification is inherently based on terminals, as defined by
the General Terminal Interface of the Single Unix Specification. (BTW
SUS and POSIX have merged into one set of specs at SUSv3.)

If you tell us what you want to achieve in the end (i.e. you state the
problem), maybe we can tell you what to use *instead of* "ui/curses.c",
as the QEMU display backend. We might also be able to suggest ways to
use "ui/curses.c", so that it give you what you need.


Let me speculate a bit. You mentioned wanting to connect "ui/curses.c"
to a pipe, possibly to transfer the output elsewhere. This is a common
use case -- it's what terminal emulators such as "xterm" do, also what
"ssh" does (when you log in interactively with it). "screen" and "tmux"
are other programs in this class.

The way they all work is, they set up a pseudo-terminal (pty). The pty
has a master end and a slave end. The slave end looks like a real
terminal and provides the General Terminal Interface -- so "ui/curses.c"
would consume that. The kernel driver for pseudo-terminals provides all
the necessary terminal features. On the master end, you get a file
descriptor to a bidirectional stream (similar to a unix domain stream
socket). The various terminal emulators (xterm, ssh, screen, tmux) read
and write the master end, and perform various stuff on the data received
(e.g. "screen" passes the data for display to the other screen process
for display, if there is such an "other" screen process; xterm draws the
characters, clears the screen, changes colors, and beeps; sshd encrypts
the data, transfers it over the network, ssh decrypts the data and
writes it to the local *slave* end; and so on).

One interface to check here is posix_openpt():

http://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_openpt.html

What's important here is that the translation between the master end and
the slave end is *thick*. For example, assuming appropriate settings, if
you write the appropriate character ("INTR") to the master-end file
descriptor, the program for which the slave-end is the "controlling
terminal" -- another term to look up in POSIX -- will get a SIGINT. This
translation (i.e. the raising of SIGINT) is done by the kernel's
pseudo-terminal (pty) driver. This is what happens e.g. when you press
"Ctrl-C" in xterm.

Anyway, you mentioned "pexpect":

https://pexpect.readthedocs.io/en/stable/

"pexpect" is a python facility for automating interactions with programs
that require a terminal (such as the QEMU display backend
"ui/curses.c"). I don't know "pexpect"'s internals, but it will
*unavoidably* have to use a pseudo-terminal.

I think that, if you need "just a pipe", you can satisfy "ui/curses.c"'s
need for a terminal by giving it a slave terminal device with "pexpect".
Then you can read the master-end (pexpect should let you do that as
well) -- the master-end will indeed read similarly to pipe. Just be
aware that all the terminal output goo, such as cursor positioning,
color change sequences, beeps, screen resolution changes, etc, will show
up as binary garbage in the stream.

Thanks
Laszlo



reply via email to

[Prev in Thread] Current Thread [Next in Thread]