DEUTSCHE VERSION |
|
Links | | | Forums | | | Comments | | | Report news |
Chat | | | Polls | | | Newsticker | | | Archive |
amiga-news.de Forum > Programmierung > DOS-Handler | [ - Search - New posts - Register - Login - ] |
-1- | [ - Post reply - ] |
2004-02-24, 13:08 h Dietmar Posts: 166 User |
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? [ - Answer - Quote - Direct link - ] |
2004-02-24, 15:45 h cygnusEd Posts: 104 User |
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 [ - Answer - Quote - Direct link - ] |
2004-02-24, 19:13 h Dietmar Posts: 166 User |
Zitat: 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. [ - Answer - Quote - Direct link - ] |
2004-02-24, 19:20 h Mad_Dog Posts: 1944 User |
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 [ - Answer - Quote - Direct link - ] |
2004-02-25, 13:16 h gni Posts: 1106 User |
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. 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. [ - Answer - Quote - Direct link - ] |
2004-02-25, 13:19 h gni Posts: 1106 User |
Zitat:Vermutlich mit einem Handler, der als ConsoleTask agiert. Mehr kann ich Dir dazu aber auch nicht sagen. [ - Answer - Quote - Direct link - ] |
2004-02-25, 13:55 h Dietmar Posts: 166 User |
Zitat: Das müsste FrexxED sein. Glücklicherweise mit Sourcecode :) Danke für den Tip. [ - Answer - Quote - Direct link - ] |
2004-03-02, 09:40 h gni Posts: 1106 User |
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? [ - Answer - Quote - Direct link - ] |
2004-03-02, 12:00 h Solar Posts: 3680 User |
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... [ - Answer - Quote - Direct link - ] |
2004-03-02, 12:29 h Dietmar Posts: 166 User |
Original von gni:Zitat: 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: 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. [ - Answer - Quote - Direct link - ] |
2004-03-02, 13:22 h gni Posts: 1106 User |
Zitat:Das funktioniert mit _jeder_ UN*X Shell. Das hat nix mit bash zu tun. Zitat:Naja, das geht auch nur so wie unter UN*X mit ixemul und deren (pd)ksh. [ - Answer - Quote - Direct link - ] |
2004-03-03, 07:10 h Solar Posts: 3680 User |
Pfff... strlen("bash") < strlen("Unix-Shell")... ;-) [ - Answer - Quote - Direct link - ] |
2004-03-04, 18:09 h Holger Posts: 8116 User |
Zitat: strlen("sh") < strlen("bash") ? mfg -- Good coders do not comment. What was hard to write should be hard to read too. [ - Answer - Quote - Direct link - ] |
2004-03-04, 18:16 h Holger Posts: 8116 User |
Zitat: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. ] [ - Answer - Quote - Direct link - ] |
2004-03-05, 07:13 h Solar Posts: 3680 User |
Zitat: true. [ - Answer - Quote - Direct link - ] |
2004-03-05, 10:07 h gni Posts: 1106 User |
Zitat:Der wurde von der OS-Shell nur nicht benutzt... Die V45 Shell setzt ihn wohl (WShell eventuell auch). Zitat: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:Wer weis schon so genau, was da gemacht wird ;-) [ - Answer - Quote - Direct link - ] |
2004-03-07, 15:37 h Dietmar Posts: 166 User |
Zitat: 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: 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: 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. ] [ - Answer - Quote - Direct link - ] |
2004-03-07, 16:33 h Holger Posts: 8116 User |
Zitat:Tjaha, warum wohl schrieb ich, das das entsprechende Verhalten compiler-spezifisch ist? Zitat: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 mfg -- Good coders do not comment. What was hard to write should be hard to read too. [ - Answer - Quote - Direct link - ] |
2004-03-07, 18:34 h Dietmar Posts: 166 User |
Zitat: 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). [ - Answer - Quote - Direct link - ] |
-1- | [ - Post reply - ] |
amiga-news.de Forum > Programmierung > DOS-Handler | [ - Search - New posts - Register - Login - ] |
Masthead |
Privacy policy |
Netiquette |
Advertising |
Contact
Copyright © 1998-2024 by amiga-news.de - all rights reserved. |