Re: Terminal buffering, oder was?

Re: Terminal buffering, oder was?

am 21.01.2007 08:01:28 von Phil

Am Fri, 19 Jan 2007 19:06:05 +0000 schrieb Alexander Bartolich:

> Philipp E. Letschert schrieb:
>> [...]
>> Ich frage mich nun ob ich den Perl Code ändern oder das Programm
>> patchen muss, damit es sich dann in Perl so verhält wie im Terminal.
>> Dazu müsste ich aber erstmal wissen was da los ist...
>
> Die C-Laufzeitbibliothek entscheidet üblicherweise anhand von
> isatty(3), ob stdout zeilengepuffert oder blockgepuffert betrieben
> wird.
>
> Wenn das Zielprogramm da nicht mitspielt und explizit setvbuf(3)
> aufruft

Habe da nirgendwo einen Aufruf von setvbuf oder setbuf gefunden, also
verstehe ich das als normales Verhalten, dass die Ausgabe von
$Zielprogramm beim Aufruf aus dem Terminal zeilengepuffert und via Pipe
aus Perl blockgepuffert arbeitet.

> nennt sich die Lösung kurz und knapp "pseudo terminal".
> man IO::Pty

Da ist mir noch nicht klar, wie ich das benutzen muss:

$pty = IO::Pty->new;
$slave = $pty->slave;

open($slave, "$cmd |");

while (!$slave->eof) {
print $slave->getline;
}

soweit richtig?

arbeitet aber immer noch blockgepuffert, also sollte ich irgendwo
setvbuf(?) aufrufen. Die man page sagt mir aber:

WARNING: The IO::Handle::setvbuf() is not available by default on Perls
5.8.0 and later because setvbuf() is rather specific to using the stdio
library, while Perl prefers the new perlio subsystem instead.

Ah toll, es gibt bei PerlIO ein $obj->setlinebuf(FH)

> setlinebuf($slave)
Undefined subroutine &main::setlinebuf called

> PerlIO::setlinebuf($slave)
Undefined subroutine &PerlIO::setlinebuf called

Wo krieg ich denn $obj her? - also auch ziemlich dunkel hier... :)


Xpost & F'up

Re: Terminal buffering, oder was?

am 21.01.2007 16:42:28 von Alexander Bartolich

Philipp E. Letschert schrieb:
> [...]
> Da ist mir noch nicht klar, wie ich das benutzen muss:
>
> $pty = IO::Pty->new;
> $slave = $pty->slave;
>
> open($slave, "$cmd |");
>
> while (!$slave->eof) {
> print $slave->getline;
> }
>
> soweit richtig?

Nein, völlig daneben.

Der Kind-Prozess soll $pty->slave als STDOUT/STDIN benutzen, nicht
umgekehrt. Das macht man in POSIX nicht mit einem einzigen Funktions-
aufruf, sondern mit der Abfolge von dup2, fork und exec.
Wobei in Perl das dup2 etwas seltsam aussieht:

my $tty_fd = $tty->slave->fileno;
open STDIN, "<&$tty_fd" or die $!;

Ein vollständiges Beispiel:

http://www.cygwin.com/ml/cygwin/2002-03/msg00779.html

> [...]
> arbeitet aber immer noch blockgepuffert, also sollte ich irgendwo
> setvbuf(?) aufrufen.

Da verfolgst du die falsche Idee konsequent weiter. :-)

--

Re: Terminal buffering, oder was?

am 22.01.2007 05:52:15 von Phil

Am Sun, 21 Jan 2007 15:42:28 +0000 schrieb Alexander Bartolich:

> Philipp E. Letschert schrieb:
>> [...]
>> Da ist mir noch nicht klar, wie ich das benutzen muss:
>> [mist]
>> soweit richtig?
>
> Nein, völlig daneben.
>
> Der Kind-Prozess soll $pty->slave als STDOUT/STDIN benutzen, nicht
> umgekehrt. Das macht man in POSIX nicht mit einem einzigen Funktions-
> aufruf, sondern mit der Abfolge von dup2, fork und exec.
> Wobei in Perl das dup2 etwas seltsam aussieht:
>
> my $tty_fd = $tty->slave->fileno;
> open STDIN, "<&$tty_fd" or die $!;
>
> Ein vollständiges Beispiel:
>
> http://www.cygwin.com/ml/cygwin/2002-03/msg00779.html
>
>> [...]
>> arbeitet aber immer noch blockgepuffert, also sollte ich irgendwo
>> setvbuf(?) aufrufen.
>
> Da verfolgst du die falsche Idee konsequent weiter. :-)

Und kaum macht man es richtig, funktioniert es. Vielen Dank für
die Erklärung und den Link!


Grüße, Phil