amiga-news ENGLISH VERSION
.
Links| Forum| Kommentare| News melden
.
Chat| Umfragen| Newsticker| Archiv
.

amiga-news.de Forum > Programmierung > DOS-Handler [ - Suche - Neue Beiträge - Registrieren - Login - ]

-1- [ - Beitrag schreiben - ]

24.02.2004, 13:08 Uhr

Dietmar
Posts: 166
Nutzer
Ich möchte alle (Compiler-)Ausgaben an eine Console in Echtzeit abfangen und per Messages an ein Programm schicken. Weiss jemand, wie man das ohne SetFunction() möglichst einfach machen könnte?

Zur Zeit patche ich Open() und Write() etc., merke mir die Handle der Console beim Öffnen und schicke in Write() die Daten an das Programm, das sie haben will. Zufriedenstellend funktioniert das nicht, da Konsolen oft mit "*" mehrmals geöffnet werden und unter OS4 würde es gar nicht funktionieren, da der m68k-Code keine Vektoren für PPC-Code setzen kann.

Ich vermute, dass man einen interaktiven Handler schreiben könnte, der wie eine Pipe funktioniert, die Daten an eine echte Console weiterleitet und ein Tear-Off für die Daten hat? Ich habe mal einen Handler geschrieben aber damals das Lesen und Schreiben auf der Basis der normalen DOS-Funktionen gemacht. Mit diesem Handler vor einer Console könnte man nur ausgeben. Vor einer interaktiven Console würde ich wohl Code brauchen, der auf Basis von DOS-Packets implementiert ist und diese Pakete asynchron hin- und herschickt? Weiss jemand, ob es irgendwo Source dafür gibt?

[ - Antworten - Zitieren - Direktlink - ]

24.02.2004, 15:45 Uhr

cygnusEd
Posts: 104
Nutzer

Wie wär's mit der Verwendung einer Pipe? Könnte so aussehen:

gcc >PIPE:a ...

Das Auslesen dann über Open("PIPE:a", MODE_OLDFILE) etc.


Gruß
CygnusEd

[ - Antworten - Zitieren - Direktlink - ]

24.02.2004, 19:13 Uhr

Dietmar
Posts: 166
Nutzer
Zitat:
Wie wär's mit der Verwendung einer Pipe? Könnte so aussehen:

Vieleicht, mit trickreichen Umleitungen (make <* >*|pipe:out). Ich will die make/gcc-Ausgaben haben (sofort, zeilenweise) aber make soll weiter in der Konsole ausgeben und dort auch Benutzereingaben annehmen. Andere Frage: kann man Handler auch aus einem Programm heraus mounten (und wie)? Ich habe in Beispielen nur den Weg über l: und mount gesehen.

[ - Antworten - Zitieren - Direktlink - ]

24.02.2004, 19:20 Uhr

Mad_Dog
Posts: 1944
Nutzer
Wie wär's mit system() ?
Ich habe mir da so geholfen, daß ich mit sprintf() das Kommando in einen String geschrieben habe und diesen anschließend mit system() aufgerufen habe. So kannst Du auch Mount mit entsprechenden Parametern aufrufen.

--

http://www.norman-interactive.com

[ - Antworten - Zitieren - Direktlink - ]

25.02.2004, 13:16 Uhr

gni
Posts: 1106
Nutzer
Zitat:
Dietmar:
Andere Frage: kann man Handler auch aus einem Programm heraus mounten (und wie)?

Ja, das geht. Man kann DOS: Devices auch aus Programmen heraus ohne c:mount erstellen. Da gabs mal einen Editor, der das bearbeitete File als DOS-Device zugänglich gemacht hat. AFAIK, benutzt auch die datatypes.library V44+ einen internen Handler für DTST_MEMORY. Wie man das genau macht, kann ich Dir aber nicht sagen. In der expansion.library gibts AddDosNode(). Lies da mal nach und im Guru-Buch. Eventuell kannst Du ja Olaf Barthel direkt fragen.

[ - Antworten - Zitieren - Direktlink - ]

25.02.2004, 13:19 Uhr

gni
Posts: 1106
Nutzer
Zitat:
Dietmar:
Ich möchte alle (Compiler-)Ausgaben an eine Console in Echtzeit abfangen und per Messages an ein Programm schicken. Weiss jemand, wie man das ohne SetFunction() möglichst einfach machen könnte?

Vermutlich mit einem Handler, der als ConsoleTask agiert. Mehr kann ich Dir dazu aber auch nicht sagen.

[ - Antworten - Zitieren - Direktlink - ]

25.02.2004, 13:55 Uhr

Dietmar
Posts: 166
Nutzer
Zitat:
Ja, das geht. Man kann DOS: Devices auch aus Programmen heraus ohne c:mount erstellen. Da gabs mal einen Editor, der das bearbeitete File als DOS-Device zugänglich gemacht hat.

Das müsste FrexxED sein. Glücklicherweise mit Sourcecode :) Danke für den Tip.

[ - Antworten - Zitieren - Direktlink - ]

02.03.2004, 09:40 Uhr

gni
Posts: 1106
Nutzer
Zitat:
Dietmar:
Zitat:
Ja, das geht. Man kann DOS: Devices auch aus Programmen heraus ohne c:mount erstellen. Da gabs mal einen Editor, der das bearbeitete File als DOS-Device zugänglich gemacht hat.
Das müsste FrexxED sein. Glücklicherweise mit Sourcecode :) Danke für den Tip.
Ich denke, ich meinte einen anderen, den ich noch irgendwo auf Diskette habe :-)
Wie ich sehe, hast Du das mit dem Handler hinbekommen. Könntest Du bitte Einzelheiten posten?

[ - Antworten - Zitieren - Direktlink - ]

02.03.2004, 12:00 Uhr

Solar
Posts: 3680
Nutzer
Hmmm... in einer bash würde ich auf "tee" verweisen, das "teilt" stdout in stdout und Ausgabe in eine Datei (oder named pipe).

Leider habe ich mich mit solchen Feinheiten erst nach meinen Amiga-Zeiten beschäftigt...

[ - Antworten - Zitieren - Direktlink - ]

02.03.2004, 12:29 Uhr

Dietmar
Posts: 166
Nutzer
Original von gni:
Zitat:
Ich denke, ich meinte einen anderen, den ich noch irgendwo auf Diskette habe :-) Wie ich sehe, hast Du das mit dem Handler hinbekommen. Könntest Du bitte Einzelheiten posten?

Ich habe auf das Mounten aus dem Programm heraus verzichtet und mounte den pipecon:-Handler beim Booten mit Mountlist. Es ist ein einfacher Vorsatz vor con:, nicht weiter erwähnenswert (er hat zusätzlich eine /PORT-Option, um alle Ausgaben an einen MsgPort zu verschicken). Intern arbeitet er mit normalen DOS-Funktionen. Ursprünglich hatte ich gedacht, dass er auf Basis von Paketen implementiert werden sollte, um die einzelnen Anforderungen voneinander zu entkoppeln. Zu dem Zeitpukt war der Handler aber noch ein Dateisystem (d.h. ein Prozess für den Handler). Das hat nicht funktioniert, Dateisystem-Handler können "*" nicht auflösen. Jetzt läuft der Handler in jeder Instanz als eigener Prozess. Mounten zur Laufzeit wäre übrigens kein Problem, im FrexxED-Sourcecode steht alles notwendige. Dann könne man den Editor aber nicht beenden, solange der Handler offene Fenster hat.

Original von Solar:
Zitat:
Hmmm... in einer bash würde ich auf "tee" verweisen, das "teilt" stdout in stdout und Ausgabe in eine Datei (oder named pipe)

Es gibt eine Amiga-Pipe (aminet: pipehandler.lha), die den Datenstrom abreissen kann und zusätzlich zu stdout in eine andere Datei schickt. Damit könnte man ein con-Fenster kriegen und gleichzeitig die Ausgaben. Aber wenn man die Compiler-Ausgaben in dem Moment haben will, in dem sie anfallen, kann man keine gebufferte Pipe verwenden. Das nächste Problem ist stderr: AmigaOS hat keine stderr-Unleitung. Programme wenden sich direkt an Console-"Tasks" (Message-Ports der Handler) und finden stderr, indem "*" auf dem Handler aufgelöst wird. Mit einer Pipe samt Abriss, also einem Dateisystem ohne "*", kommt man nicht an die stderr-Ausgaben: die gehen an die Console.

[ - Antworten - Zitieren - Direktlink - ]

02.03.2004, 13:22 Uhr

gni
Posts: 1106
Nutzer
Zitat:
Solar:
Hmmm... in einer bash würde ich auf "tee" verweisen, das "teilt" stdout in stdout und Ausgabe in eine Datei (oder named pipe).

Das funktioniert mit _jeder_ UN*X Shell. Das hat nix mit bash zu tun.
Zitat:
Leider habe ich mich mit solchen Feinheiten erst nach meinen Amiga-Zeiten beschäftigt...
Naja, das geht auch nur so wie unter UN*X mit ixemul und deren (pd)ksh.

[ - Antworten - Zitieren - Direktlink - ]

03.03.2004, 07:10 Uhr

Solar
Posts: 3680
Nutzer
Pfff... strlen("bash") < strlen("Unix-Shell")... ;-)

[ - Antworten - Zitieren - Direktlink - ]

04.03.2004, 18:09 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von Solar:
Pfff... strlen("bash") < strlen("Unix-Shell")... ;-)


strlen("sh") < strlen("bash") ? :lach:

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

04.03.2004, 18:16 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von Dietmar:
Das nächste Problem ist stderr: AmigaOS hat keine stderr-Unleitung. Programme wenden sich direkt an Console-"Tasks" (Message-Ports der Handler) und finden stderr, indem "*" auf dem Handler aufgelöst wird.

AmigaOS hat einen stderr Kanal, es fehlt nur die Möglichkeit, ihn in der Amiga-Shell zu setzen. Startet man ein Programm aus einem anderen heraus, kann man stderr aber durchaus setzen.
Was das Programm zur Fehlerausgabe tatsächlich macht, ist compiler- und programmspezifisch. Mag sein, daß einige Programme tatsächlich open("*",...) statt des einfacheren err() benutzten, aber mit dem Console-Task kommuniziert definitiv niemand direkt.
Standard Amiga-DOS Funktionen wie PrintFault() sollten aber eigentlich immer den gesetzten stderr benutzen.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ Dieser Beitrag wurde von Holger am 04.03.2004 editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

05.03.2004, 07:13 Uhr

Solar
Posts: 3680
Nutzer
Zitat:
Original von Holger:
Zitat:
Original von Solar:
Pfff... strlen("bash") < strlen("Unix-Shell")... ;-)

strlen("sh") < strlen("bash") ? :lach:

true. :glow: :smokin:

[ - Antworten - Zitieren - Direktlink - ]

05.03.2004, 10:07 Uhr

gni
Posts: 1106
Nutzer
Zitat:
Holger:
AmigaOS hat einen stderr Kanal, es fehlt nur die Möglichkeit, ihn in der Amiga-Shell zu setzen.

Der wurde von der OS-Shell nur nicht benutzt... Die V45 Shell setzt ihn wohl (WShell eventuell auch).
Zitat:
Was das Programm zur Fehlerausgabe tatsächlich macht, ist compiler- und programmspezifisch.
Mag sein, dennoch ist Open("*",...) _das_ Mittel, um ein FilHandle für stderr zu bekommen, da pr_CES selten gesetzt war/ist. Zudem kommt man an dieses Feld _nur_ durch direktes Peeken der Processstruktur...
Zitat:
Standard Amiga-DOS Funktionen wie PrintFault() sollten aber eigentlich immer den gesetzten stderr benutzen.
Wer weis schon so genau, was da gemacht wird ;-)

[ - Antworten - Zitieren - Direktlink - ]

07.03.2004, 15:37 Uhr

Dietmar
Posts: 166
Nutzer
Zitat:
Original von Holger:
AmigaOS hat einen stderr Kanal


Wenn Du genauer gelesen hättest: AmigaOS hat keine stderr-UMLEITUNG. Die Betonung liegt auf Umleitung, nicht auf stderr. Tatsächlich gibt es für eine Umleitung Tags (NP_Error, NP_CloseError), sie werden von System() aber ignoriert. Ein Zeile wie make >log leitet viele Ausgaben aber keine Fehler in die Datei log um.

Zitat:
Mag sein, daß einige Programme tatsächlich open("*",...) statt des einfacheren err() benutzten, aber mit dem Console-Task kommuniziert definitiv niemand direkt.

stderr wird nicht von Programmierern sondern vom Compiler geöffnet ;) Ausserdem war nicht die Rede davon, dass Programmierer direkt mit Console-Tasks kommunizieren: das passiert automatisch und ohne dass man es merkt, weil DOS über Pakete, dh. Messages, mit dem Console-Handler-Prozess kommuniziert. Ein puts("Hallo Welt!") bedeutet effektiv, dass Du mit dem Console-Task kommunizierst. Normalerweise startet man Programme mit System() und gibt über SYS_Input eine Console an: inhandle = Open("con:...). Da man Ausgaben und Eingaben in derselben Console haben will, übergibt man SYS_Output als NULL. DOS macht dann intern etwa das folgende, um eine zweite Handle auf die Console zu kriegen:

if (IsInteractive(inhandle))
{
struct MsgPort *oldconsole;

newconsole = ((struct FileHandle *)BADDR(inhandle))->fh_Type;

oldconsole = SetConsoleTask(newconsole);

outhandle = Open("*", MODE_OLDFILE);

SetConsoleTask(oldconsole);
}

Der Console-Handler kriegt durch die Open("*"...)-Zeile ein Paket vom Typ ACTION_FINDINPUT an seinen Port geschickt. Compiler öffnen im Startup-Code stderr auf die gleiche Weise: Open("*"...). Und weil sich Compiler mit dieser Aktion an stdout vorbeimogeln, hat man das Problem, dass man stderr nicht umlenken kann...

"*" und das äquivalente "console:" sind übrigens spezielle Dateinamen, die einem Handler sagen, dass er seine Datei bzw. in diesem Fall Console nochmal öffnen soll. Das funktioniert nur, wenn der Handler-Prozess exakt eine Datei verwaltet. con:-Handler sind so programmiert: ein Task für jedes con:-Fenster. Handler, die als Dateisystem implementiert sind, können mit "*" nichts anfangen, weil nicht klar ist, welche Datei mit "*" gemeint ist.

Zitat:
Startet man ein Programm aus einem anderen heraus, kann man stderr aber durchaus setzen.

Es ist unmöglich, ein Programm zu starten und dessen Fehlermeldungen umzulenken. Man könnte allerdings ein Starter-Programm (z.B. run) mit einer neuen Console starten, das seinerseits das "wirkliche" Programm startet. Dessen stderr würde dann an "*" des Starterprogramms gehen. Aber das setzt voraus, dass der entsprechende Handler "*" auflösen kann. Das ist bei einem Dateisystemen NICHT möglich. Deshalb kann man stderr mit diesem Trick zwar an eine andere Konsole aber NICHT an ein nicht-interaktives Ausgabegerät umleiten (z.B. Pipe vor Console, die Ausgaben abzweigt). Und genau deshalb habe ich den pipecon-Handler geschrieben, der eine Pipe implementiert, aber als Console programmiert ist. Alles klar?

[ Dieser Beitrag wurde von Dietmar am 07.03.2004 editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

07.03.2004, 16:33 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von Dietmar:
stderr wird nicht von Programmierern sondern vom Compiler geöffnet ;)

Tjaha, warum wohl schrieb ich, das das entsprechende Verhalten compiler-spezifisch ist?
Zitat:
Es ist unmöglich, ein Programm zu starten und dessen Fehlermeldungen umzulenken. Man könnte allerdings ein Starter-Programm (z.B. run) mit einer neuen Console starten, das seinerseits das "wirkliche" Programm startet. ... Und genau deshalb habe ich den pipecon-Handler geschrieben, der eine Pipe implementiert, aber als Console programmiert ist. Alles klar?
Ich benutze halt Anweisungen ala sh -c "make 2>ram:errors.txt" für diesen Zweck, ist umständlich und funktioniert vermutlich nur mit Programmen, die mit ixemul compiliert wurden, erfüllt aber für mich seinen Zweck und leichter, als einen eigenen dos-handler zu schreiben, ist es allemal.

Unmöglich ist nichts :O

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

07.03.2004, 18:34 Uhr

Dietmar
Posts: 166
Nutzer
Zitat:
Ich benutze halt Anweisungen ala sh -c "make 2>ram:errors.txt" für diesen Zweck

Den Handler habe ich auch noch aus einem anderen Grund geschrieben: ich wollte die Ausgaben sofort haben, damit man dem Makevorgang folgen kann (jederzeit Klick auf Fehlermeldung, um die Datei zu öffnen). Also keine temporäre Datei, die erst am Ende des make gelesen wird, und keine Pipe, die möglicherweise gebufferte DOS-Funktionen benutzt. Stattdessen werden Messages verschickt. Wenn man beispielsweise pipecon:///.../AUTO/WAIT/CLOSE/PORTGoldEDConsole öffnet, dann geht ein con:-Fenster auf und zusätzlich werden alle Ausgaben an dieses Fenster an den Port GoldEDConsole geschickt (dort könnte ein Plug-In lauschen, das die Ausgaben in einer Ecke des Editorfensters anzeigt).

[ - Antworten - Zitieren - Direktlink - ]


-1- [ - Beitrag schreiben - ]


amiga-news.de Forum > Programmierung > DOS-Handler [ - Suche - Neue Beiträge - Registrieren - Login - ]


.
Impressum | Datenschutzerklärung | Netiquette | Werbung | Kontakt
Copyright © 1998-2024 by amiga-news.de - alle Rechte vorbehalten.
.