[Allegro] Trick 64: 1. FLEX ohne Db? / 2. Jedem seinen _start.flx

Thomas Berger ThB at Gymel.com
Fr Jan 11 01:43:50 CET 2008


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Liebe Frau Koczian,

| Dazu wiederhole ich eine Frage, die im Sommer unbeantwortet geblieben
ist: hat
| jemand ein Perl-Skript auf die Reihe gekriegt, das Avanti-cl mit einem
Job
| versorgt und seine Antwort entgegennimmt? Ohne dass der Job in eine
eigene
| Datei geschrieben werden muss?
|
| Nach Diskussionen in der deutschen Perl-Newsgroup habe ich den Verdacht
| bekommen, dass Perl für Windows hier eine Macke hat, aber ganz glauben
kann
| ich das dann doch nicht. Vergleichbares unter Linux geht locker vom
Hocker,
| mit Python auch unter Windows überhaupt kein Problem, Delphi tut es
auch, mit
| oder ohne .NET, aber Perl will einfach nicht oder mag mich einfach nicht.
|
| Ein Avanti-Problem ist es sicher nicht. Primitive Skriptlein, die intern
| nichts Vernünftiges tun, sich nach außen aber wie Avanti-cl verhalten,
tun in
| Perl-Skripten unter Windows genau so wenig.

Das Problem gilt als schwierig...

Vgl. <
http://search.cpan.org/~rgarcia/perl-5.10.0/pod/perlipc.pod#Bidirectional_Communication_with_Another_Process
|:

|>>
The problem with this is that Unix buffering is really going to ruin
your day. Even though your Writer filehandle is auto-flushed, and the
process on the other end will get your data in a timely manner, you
can't usually do anything to force it to give it back to you in a
similarly quick fashion. In this case, we could, because we gave cat a
- -u flag to make it unbuffered. But very few Unix commands are designed
to operate over pipes, so this seldom works unless you yourself wrote
the program on the other end of the double-ended pipe.
<<<


Ich habe es hier (das eher aeltliche ActivePerl 5.8.4 Build 810
unter Windows XP SP 2) trotz vielstuendigem Testen nicht hinbekommen,
sowohl mit diversen CPAN-Modulen als auch mit lowlevel-Programmierung
(fork + Fummeln mit Dateideskriptoren + exec): Die pipe-handles lassen
sich (anders als Sockets) nicht zuverlaessig darauf testen, ob Daten
anliegen, und der gestartete Prozess wird nicht beendet
(moeglicherweise bin ich aber nur in eine Newbie-Falle getappt und
irgendein weiterer Dateihandle blieb offen und hinderte avanti-cl
am sterben). Jedenfalls wird alles nicht einfacher dadurch, dass
es hier keinerlei "Protokoll" gibt, wie es fuer bidirektionale
Kommunikation typischerweise benoetigt wird: "AVANTI:EOJ" und
"AVANTI:EOR" werden vom echten Avanti-Server abgefangen bzw.
eingefuegt, avanti-cl kennt sie nicht und mag sie auch nicht.]

Bei Durchsicht der vielen Module zu diesem Thema sind mir viele
aufgefallen, die (mehr oder weniger versteckt) Temporaerdateien und
keine Pipes nutzen, um portabler zu sein. Oder sie nutzen ptys, um eine
echte interaktive Nutzung vorzugaukeln.

Allerdings ist auch Ihr Ansatz fragwuerdig: Schliesslich ist bekannt,
dass man mit avanti-cl nicht ueber Pipes kommunizieren kann, zumindest
nicht so, wie Ihre Diskussionspartner das vermutlich verstanden haben:
Avanti-cl buffert seinen Input ganz gewaltig, es beginnt erst zu
arbeiten, wenn der Sender sein Ende der Schreib-Pipe echt geschlossen
hat. Reaktion auf Spaeteres ist ueber dieselbe Verbindung damit
unmoeglich, insofern kann man den Job auch gleich in eine Datei
schreiben und spart sich viele Probleme. Dass es mit den von Ihnen
genannten Umgebungen funktioniert, ist wiederum ein Indiz dafuer,
dass dort eben auch innen drin Temporaerdateien genutzt werden, und
keine echten Pipes.

Ein guenstiger Weg scheint mir daher, auf den nicht erfuellbaren
"bidirektionalen" Anspruch zu verzichten und den Job in eine Datei zu
schreiben, avanti-cl darauf loszulassen und sein STDOUT einzusammeln.
Damit ist ein Geruest aeusserst trivial (und funktioniert):

|>>
#!perl -w
use strict;
use warnings;
use File::Temp;

my @slave = qw( G:/allegro/avanti-cl.exe );
my $job = <<"XxX";
&
help
help available
@
XxX

my $jobfile = new File::Temp (TEMPLATE =>  "av-temp-XXXX");
print $jobfile $job;
close($jobfile);

my $jobname = $jobfile->filename;
open (AVANTI, "@slave <$jobname 2>>avanti.log |") or die "could not
start @slave: $!";
while ( <AVANTI> ) {
~    print  # or process...
~  };

print "done";
exit 0;
<<<

Anmerkungen:
- - vermutlich wird nicht nur avanti-cl gestartet, sondern auch noch
~  ein Kommandointerpreter...
- - Nutzung von File::Temp garantiert einen eindeutigen, exklusiv
~  reservierten Namen fuer die Temporaerdatei, und auch, dass
~  abschliessend automatisch aufgeraeumt wird.
- - Ich habe keine Ahnung, wie (anonyme) Pipes in Windows realisiert
~  sind, der scheinbare Umweg ueber eine echte Datei fuer den Job
~  ist evtl. gar nicht so ineffizient...
- - Je nach Problemstellung sitzt der Job sowieso in einer eigenen
~  Datei und ist nicht ins Skript eingebettet?

[Minimal-"installation" von avanti-cl in einer regulaeren allegro-
Installation:

Die drei Dateien

bin\avanti-cl.exe
etc\uifsger
etc\avanti.conf

ins Programmverzeichnis kopieren, avanti.conf geeignet anpassen.
]

viele Gruesse
Thomas Berger
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3-nr1 (Windows XP)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFHhrvGhKFJT0F1FsoRAuD+AJ9TAUFqF31Nujm5hVSCjhx0a2XRoQCcDwy7
4B3zX/JJd6ux+myGQNAu+mg=
=JVyJ
-----END PGP SIGNATURE-----



Mehr Informationen über die Mailingliste Allegro