Eine EXEC Funktion mit Speicherauslagerung Version 3.3b, Freigegeben 93-11-29 Public Domain Software von Thomas Wagner Ferrari electronic GmbH (Achtung Adress„nderung, siehe unten!) Dieses Archiv enth„lt die Quellen fr eine 'EXEC'-Funktion die den Aufruf externer Programme erlaubt, wobei der Programmspeicher optional auf EMS, XMS, oder Datei ausgelagert wird. Bei Auslagerung des Speichers werden nur noch wenige K des Hauptspeichers belegt w„hrend das externe Programm ausgefhrt wird. Der Code/Daten-Bereich betr„gt etwa 1k, der ben”tigte Speicherplatz ist abh„ngig von der Speicherfragmentierung, sowie besonders von der Gr”áe des Umgebungsvariablenblocks. šblicherweise werden zwischen 2K und 7K belegt. Die Routinen sind kompatibel mit Turbo C (Versionen 1.x, 2.x, sowie C++ 1.0) Borland C++ (Version 2.0 und h”her), Microsoft C (Versionen 5.1 und h”her), Watcom C (Version 8.0), Turbo Pascal (Versionen 4.x bis 6.x). EMS (LIM 3.0 und sp„tere Versionen) oder XMS werden benutzt sofern ausreichend Platz zur Verfgung steht. Wenn nicht, wird eine tempor„re Plattendatei angelegt. Diese Datei wird in dem durch die Umgebungsvariablen TEMP= oder TMP= gegebenen Pfad angelegt. Ist kein solcher Pfad angegeben, wird der aktuelle Pfad benutzt. Aufruf und Parameterversorgung sind in der Datei "exec.h" (C) bzw. "exec.pas" (Pascal) detailliert dokumentiert. Das allgemeine Format ist retcode = do_exec (Name des auszufhrenden Programms, Programm-Parameter und Redirection String, Spawn-Optionen, Ben”tigter Speicher (0xffff lagert stets aus, 0 nie), Umgebungsvariablen-Zeiger/Flag) zum Beispiel: rc = do_exec ("cl", "-c -Od exec.c >&errout", USE_ALL, 0xffff, NULL); oder, fr Pascal: rc := do_exec ('tpc', '/$D+ exec >&errout', USE_ALL, $ffff, false); Redirection fr Standard Input, Standard Output, und Standard Error wird optional behandelt indem der Parameter-String nach den folgenden Kombinationen durchsucht wird: stdin: file oder >>file zum Anfgen stderr: >&file oder >&>file zum Anfgen Redirection wird standardm„áig untersttzt. Um sie auszuschalten, mssen Sie die Definitionen sowohl in spawn.asm als auch in exec.c/exec.pas „ndern. Wenn das auszufhrende Kommando eine Batch-Datei ist, wird automatisch der Kommando-Prozessor aufgerufen. Der Kommandoprozessor wird auch aufgerufen wenn das Kommando leer ist. Dabei wird die COMSPEC-Umgebungsvariable benutzt um den Kommandoprozessor zu finden, zus„tzliche Parameter in der COMSPEC-Zeile werden in die Kommandoparameter eingefgt. Zum Beispiel: Es sei COMSPEC=C:\DOS\COMMAND.COM /E:960 PATH=C:\DOS;C:\CMD Datei B.BAT existiert in C:\CMD do_exec wird aufgerufen mit ('b', 'eins zwei >out', ...) Dann ist das aufgerufene Kommando C:\DOS\COMMAND.COM mit dem Parameter-String /E:720 /C C:\CMD\B.BAT eins zwei und Standard Output wird umgeleitet auf die Datei 'out'. INHALT ====== Dieses Archiv enth„lt die folgenden Dateien: LIESMICH.DOC Diese Datei README.DOC Englische Version dieser Datei GETLANG.EXE Ein Hilfsprogramm zur Extraktion einer ein- sprachigen Version aus der zweisprachigen Quelle. Alle C- und Assembler-Quellen (die Pascal-Quellen leider nur teilweise) sind sowohl in Deutsch als auch in Englisch dokumentiert, was die Quellen schwer lesbar macht. Fr bessere Lesbarkeit k”nnen Sie mit GETLANG eine der Sprachen eliminieren. Benutzung: GETLANG Sprache Compiler Ausgabe wobei Sprache 'E' fr Englisch oder 'D' fr Deutsch Compiler 'C' fr C Dateien, 'A' fr Assembler, 'P' fr Pascal. Beispiele: GETLANG d a spawnd.asm GETLANG d c extestd.c DEUTSCH.BAT Batch-File zur Ausfhrung von GETLANG fr alle Quelldateien, deutsche Version ENGLISH.BAT Batch-File zur Ausfhrung von GETLANG fr alle Quelldateien, englische Version SPAWN.ASM Die Hauptfunktion fr exec. Diese Datei ist fr die C und Pascal Versionen gleich. Fr Benutzung mit Turbo Pascal muá mit dem Turbo-Assembler assembliert werden. Die C Version kann mit TASM (geben Sie /JMASM51 an) oder MASM 5.1 bersetzt werden. Assemblieren mit: tasm /DPASCAL spawn,spawnp; Fr Turbo Pascal, near calls tasm /DPASCAL /DFARCALL spawn,spawnp; Fr Turbo Pascal, far calls ?asm spawn; Fr C (Default small model) ?asm /DMODL=xxx spawn; For C (model 'xxx') Beispiel: masm /DMODL=large spawn; Large model C tasm /DMODL=medium /JMASM51 spawn; Medium model C SPAWNP.OBJ SPAWN assembliert fr Pascal, near calls SPAWNCS.OBJ SPAWN assembliert fr C (small model) SPAWNCL.OBJ SPAWN assembliert fr C (large model) Die C Dateien wurden mit dem /MX-Schalter bersetzt um Groá-/Kleinschreibung beim Linken zu bercksichtigen. Hinweis fr Turbo Pascal: Sie k”nnen die "near call" Version von SPAWN auch dann nutzen wenn Sie mit "force far calls" kompilieren, indem Sie die "external"-Definitionen von do_spawn und prep_swap in Datei exec.pas in {$F-} und {$F+} einschlieáen. Um Konfusion bei der Verwendung mehrerer Compiler zu vermeiden, wurde das Pascal-Object "spawnp.obj" benannt. CHECKPAT.ASM Hilfsfunktion zur Prfung und Aufl”sung eines Pfades Diese Datei ist fr die C und Pascal Versionen gleich. Fr Benutzung mit Turbo Pascal muá mit dem Turbo-Assembler assembliert werden. Die C Version kann mit TASM (geben Sie /JMASM51 an) oder MASM 5.1 bersetzt werden. Assemblieren mit: tasm /DPASCAL checkpat,checkpap; Fr Turbo Pascal, near calls tasm /DPASCAL /DFARCALL checkpat,checkpap; Fr Turbo Pascal, far calls ?asm checkpat; Fr C (Default small model) ?asm /DMODL=xxx checkpat; Fr C (model 'xxx') Beispiel: masm /DMODL=large checkpat; Large model C tasm /DMODL=medium /JMASM51 checkpat; Medium model C CHECKPAP.OBJ CHECKPAT assembliert fr Pascal, far calls CHECKPCS.OBJ CHECKPAT assembliert fr C (small model) CHECKPCL.OBJ CHECKPAT assembliert fr C (large model) CHECKPAT.PAS Einbindungs-Unit fr checkpat (Nur Pascal) Die C Dateien wurden mit dem /MX-Schalter bersetzt um Groá-/Kleinschreibung beim Linken zu bercksichtigen. Die Pascal-Version muá mit dem FARCALL-Schalter assembliert werden wenn Sie sie mit der Einbindungs-Unit CHECKPAT.PAS zusammen benutzen. Zumindest Turbo Pascal Version 5.5 verwendet offenbar stets einen Far Call wenn eine externe Routine im Interface-Teil einer Unit definiert wird. EXEC.PAS Interface Routinen und Dokumentation fr Turbo Pascal EXEC.C Interface Routinen fr C EXEC.H Interface Definitionen und Dokumentation fr C COMPAT.H MS-C/TC Kompatibilit„ts-Definitionen fr C Diese Dateien bereiten die Parameter fr die Hauptfunktion vor und bearbeiten die Datei-Suche und Umgebungsvariablen. EXTEST.C C Test-Programm fr EXEC EXTEST.PAS Turbo Pascal Test-Programm fr EXEC Das EXTEST Programm testet die Funktionalit„t der do_exec Funktion. Es erwartet die Eingabe eines DOS-Kommandos und, durch Komma getrennt, seiner Parameter. Die Eingabe einer Leerzeile startet COMMAND.COM ohne Parameter. MAKEPAS Make-Datei fr Turbo Pascal (Borland Make) MAKETC Make-Datei fr Borland C++ (Borland Make) MAKEMS Make-Datei fr Microsoft C (MS NMAKE) Die Turbo Pascal Version von EXEC.PAS enth„lt Ersatzfunktionen fr die Umgebungsvariablen-Zugriffsfunktionen 'envcount', 'envstr', und 'getenv', sowie eine zus„tzliche Funktion 'putenv'. Diese Funktion erlaubt Ihnen, zur Umgebung des gerufenen Programms Strings hinzuzufgen. Die Definition ist procedure putenv (envvar: string); wobei 'envstr' einen String der Form 'ENVVAR=wert' enth„lt. Das '=' ist notwendig. Um einen Umgebungsvariablenstring zu l”schen geben Sie 'ENVVAR=' an. Bitte nutzen Sie nur die Funktionen aus der EXEC Unit, mischen Sie sie nicht mit Aufrufen der Funktionen der DOS Unit. SUPPORT ======= Diese Software ist "Public Domain", das heiát es gibt keinerlei Einschr„nkungen bezglich ihrer Nutzung, ob privat oder in kommerziellen Produkten. Es ist weder eine Registrierungsgebhr zu zahlen, noch sind zur Nutzung irgendwelche Lizenzen erforderlich. Dies heiát allerdings auch, daá der Autor zu keiner Leistung gegenber dem Nutzer verpflichtet ist. Jegliche Ansprche auf Schadenersatz bei Fehlfunktionen sind ausgeschlossen. Sie haben die Quellen, bitte prfen Sie sie vor Nutzung. Ich m”chte auch um Verst„ndnis bitten, daá ich nicht in der Lage bin, kostenlose Programmierberatung zu erteilen, Spezialversionen fr exotische Compiler zu erstellen, oder neue Versionen dieses Programms kostenlos zu versenden. Fehlermeldungen, Verbesserungsvorschl„ge und „hnliches senden Sie bitte an meine Firmen-Adresse: Ferrari electronic GmbH Ruhlsdorfer Strasse 138 D-14513 Teltow Tel.: (+49 3328) 474 626 Fax: (+49 3328) 438 04-0 BBS: (+49 3328) 438 04-8 Internet: twagner@bix.com BIX: twagner Compuserve: 100023,2042 Ein eingeschr„nkter Support ist ber BIX, das Teleconferencing System von McGraw-Hill, m”glich. Falls Sie Fragen oder Fehlermeldungen haben, senden sie BIXmail an 'twagner'. Details ber BIX finden Sie in der Englischsprachigen Version dieser Dokumentation. Die jeweils neueste Version finden Sie auch in unserem BBS. Dort k”nnen auch Fehlermeldungen etc. abgelegt werden. Das BBS untersttzt bis 14.400 bps, mit V.42bis und MNP5 Fehlerkorrektur und Kompression, und ist durchgehend ge”ffnet. EINSCHRŽNKUNGEN =============== Der "keine Rckkehr"-Modus von do_exec ist nur der Vollst„ndigkeit halber verfgbar. Er hat einige Nachteile gegenber den Standard-Funktionen der Compiler-Bibliotheken. Insbesondere werden offene Dateien nicht abgeschlossen, und durch die Laufzeitbibliothek belegte Interrupt-Vektoren werden nicht auf den DOS-Standardwert zurckgesetzt. Wenn m”glich, benutzen Sie fr diesen Modus die Standardfunktionen. Das Assembler-Modul "spawn" darf nicht das erste Modul beim Linken sein. Fgen Sie es in eine Bibliothek ein, oder geben Sie spawn.obj als eine der letzten zu linkenden Dateien an. Das spawn-Modul berschreibt etwa 1k am Anfang des Programmspeichers. Dieser Speicher wird zwar gesichert, er darf aber nicht Teile des Moduls selbst enthalten, da der Programmcode dabei zerst”rt wrde. Die do_exec-Funktion berprft diese Bedingung, und kehrt mit einem entsprechenden Fehlercode zurck falls der Code in Gefahr w„re. Bei Aufruf von do_exec drfen keine Interrupt-Handler installiert sein. Dies schlieát Handler fr Control-C und Critical Errors ein. Sofern Sie Interrupts bearbeiten wollen w„hrend Ihr Programm ausgelagert ist, mssen Sie das spawn-Modul modifizieren, sodaá die Handler in den residenten Teil bernommen werden. Offene Dateien bleiben w„hrend der do_exec-Funktion ge”ffnet. Dies reduziert die Zahl der m”glichen offenen Dateien fr das Kind-Programm. Die Umgebungsvariable "C_FILE_INFO", die von einigen C-Compilern bei Aufruf der Standard-Funktionen fr spawn erzeugt wird, wird nicht untersttzt. Wenn NO_INHERIT in spawn.asm gesetzt ist (Standard), werden alle offenen Dateien auáer den ersten fnf Standard-Dateien vor dem Kindprozess "versteckt" und damit nicht vererbt. Dies erlaubt dem Kindprozess, mehr Dateien zu ”ffnen, wobei allerdings das Systemweite Limit (FILES= in config.sys) hoch genug sein muá um alle offenen Dateien zu untersttzen. Interne Kommandos (CD, DIR usw.) werden nicht automatisch bearbeitet. Sie k”nnen diese ausfhren indem Sie den Kommandointerpreter laden (durch šbergabe eines leeren Strings fr das auszufhrende Programm). Zum Beispiel: (C) retcode = do_exec ("dir", "*.*", USE_ALL, 0xffff, environ); if (retcode == RC_NOFILE) retcode = do_exec ("", "/c dir *.*", USE_ALL, 0xffff, environ); (P) retcode := do_exec ('dir', '*.*', USE_ALL, $ffff, true); if (retcode = RC_NOFILE) retcode := do_exec ('', '/c dir *.*', USE_ALL, $ffff, true); HINWEISE ======== Die Funktion sollte mit DOS bis herunter zu Version 2.11 kompatibel sein. Getestet wurde jedoch nur unter DOS 3.3, DOS 4.0, DOS 5.0, DOS 6.0 und DR-DOS 5.0. Kompatibilit„t zu Compiler-Versionen wurde nur getestet mit Borland C++ 3.1, Microsoft Visual C 1.0, und Turbo Pascal 5.5. Auf andere Compiler habe ich leider keinen Zugriff. Turbo Pascal 6.0 scheint nach Benutzerberichten keine Probleme mit EXEC zu haben. Eine Benutzung mit dem DOS-Extender von Turbo Pascal 7.0 (oder anderen DOS-Extendern) ist nicht m”glich. Wird ein Kommando aufgerufen das resident bleibt (TSR), zum Beispiel PRINT oder Sidekick, ist eine Rckkehr in das rufende Programm nicht m”glich. Das Programm wird beendet, belegter Speicher in EMS/XMS wird freigegeben, eine Auslagerungsdatei wird gel”scht. Wenn der Programmspeicher aus mehreren DOS-Speicherbl”cken besteht, benutzt die Auslagerungsfunktion undokumentierte DOS-Interna. Insbesondere werden Speicherkontrollbl”cke direkt modifiziert. Dies kann theoretisch zu Inkompatibilit„ten mit sp„teren DOS-Versionen, oder mit DOS-Clones oder Emulatoren fhren. Im praktischen Betrieb wurden bisher noch keine Probleme mit irgendwelchen DOS-Versionen, einschlieálich DOS 6.0 und der DR-DOS Versionen, festgestellt. Wenn NO_INHERIT in spawn.asm auf TRUE gesetzt ist, werden einige undokumentierte Felder im PSP benutzt und modifiziert. Auch dies sollte mit allen DOS-Versionen und Clones funktionieren. Sollten Sie jedoch Probleme befrchten, k”nnen Sie NO_INHERIT auf FALSE setzen (nicht jedoch, wenn Sie die Handle-Tabelle erweitern). Žnderungsgeschichte =================== Žnderungen von Version 3.3a auf 3.3b: Unter bestimmten Umst„nden (der erste MCB eines Programms war nicht der Environment-Block, sondern der PSP, und es folgten unallozierte Bl”cke) konnte das wiederhergestellte Speicherabbild inkorrekt sein. Dieser Fehler wurde von Giorgio Angelotti entdeckt und behoben. Žnderungen von Version 3.3 auf 3.3a: Auáer der Adress„nderung ist die einzige signifikante Žnderung eine verbesserte Behandlung der Redirection. Wie unter DOS kann die Redirection jetzt auch gemischt mit sonstigen Parametern angegeben werden. In der Pascal-Version wurde die Redirection nicht korrekt behandelt, sofern mehr als eine Redirection angegeben war. Ebenso wurden Parameter in der COMSPEC-Zeile nicht erkannt. Dies wurde korrigiert. Žnderungen von Version 3.2a auf 3.3: Neu ist die Bercksichtigung des unbenutzten Heap-Bereichs fr Turbo Pascal. Dieser Bereich wird optional nicht ausgelagert, was in vielen F„llen sowohl die Auslagerungsgeschwindigkeit erh”ht, als auch den Speicherbedarf auf dem Auslagerungsmedium reduziert. Da dies Versionsabh„ngig ist (Turbo Pascal Version 6 hat eine andere Heap-Verwaltung als frhere Versionen), ist dieses Feature in der vorbersetzten Version nicht eingeschaltet. Bitte setzen Sie PAS_FREE in SPAWN.ASM auf TRUE, und setzen sie TPAS_6 je nach Ihrer Turbo-Pascal-Version auf TRUE oder FALSE, um es zu nutzen. Die Pascal "putenv" Funktion war fehlerhaft. Wenn eine Variable gesetzt wurde, die bereits im Environment vorhanden war, wurde ein doppelter Eintrag erzeugt statt den alten Eintrag zu l”schen. Fehlermeldung und Korrektur von A. Bailey. Bei der Bestimmung von Programmname und Pfad wurden Programme, deren Basis-Name (ohne Extension) gleich dem Namen einer Subdirectory war, unter Umst„nden nicht gefunden. Die checkpath Funktion wurde modifiziert um diesen Fall korrekt zu behandeln. Fehlermeldung von H. Lembke. Bei Auslagerung auf Datei mit NO_INHERIT true und einer erweiterten Handle-Tabelle war eine Rckkehr nicht m”glich. Dies lag daran, daá der Tabellen-Zeiger im PSP wiederhergestellt wurde bevor der dazugeh”rige MCB-Block alloziert und wiederhergestellt war. Der PSP-Eintrag wird jetzt erst nach dem Zurckladen gesetzt. Fehlermeldung von H. Lembke. EXEC konnte nicht auslagern wenn eine erweiterte Handle-Tabelle mit NO_INHERIT false verwendet wurde. Der MCB der die Handle-Tabelle enth„lt wird jetzt nicht mehr ausgelagert. Dies fhrt allerdings dazu, daá der Speicher fragmentiert wird, sodaá NO_INHERIT stets TRUE sein sollte wenn die Handle-Tabelle erweitert werden soll. Die C do_exec-Funktion verarbeitet jetzt auch NULL-Zeiger auf Kommandozeile und Parameterstring korrekt. Žnderungen von Version 3.2 auf 3.2a: Ein Fehler in checkpat.asm, der zu nicht vollst„ndigen Pfadangaben fhrte, wurde behoben. Ein Fehler in spawn.asm, der dazu fhrte, daá die Dateiumleitungs- Dateien selbst nach Programmende nicht geschlossen wurden, wurde behoben. Žnderungen von Version 3.1 auf 3.2: Neu ist der Aufruf einer benutzerdefinierbaren Funktion (ber einen Funktions-Pointer bzw. eine Prozedurvariable) aus do_exec vor Ausfhrung des Programmaufrufs. Diese Funktion kann z.B. Meldungen ausgeben und zus„tzliche Prfungen durchfhren. Die bisher interne Struktur mit den Auslagerungs-Parametern wurde zug„nglich gemacht um der Benutzerfunktion den Zugriff zu erlauben. Fr Details siehe exec.h bzw. exec.pas, sowie das Beispiel in extest.c/extest.pas. Ein Fehler in checkpat.asm, der bei Verwendung mit Turbo Pascal zu Problemen mit der "exists"-Funktion fhrte, wurde behoben. Die Pascal-Version von extest wurde (endlich) auf den gleichen Stand wie die C-Version gebracht, ein Beispiel fr die Nutzung der Benutzerfunktion wurde in beide Versionen eingefgt. In exec.c wurde die Definition der internen Routinen auf "static" ge„ndert, die Initialisierung einiger Variablen in do_exec wurde korrigiert. Žnderungen von Version 3.0a auf 3.1: Neu sind vor allem die automatische Behandlung von .BAT-Dateien und die Untersttzung der I/O-Dateiumleitung. Die Suchreihenfolge fr Kommandos entspricht jetzt exakt der DOS-Reihenfolge, bis auf die Bearbeitung interner Kommandos (es gibt keinen sicheren Weg fr die Erkennung, ob ein Kommando intern oder extern ist). Dateiumleitung ist optional. Das Interface zu do_exec hat sich nicht ge„ndert, do_spawn ben”tigt drei neue Parameter wenn Redirection eingeschaltet ist. Eine Routine (checkpat.asm) die einen Pfad prft und aufl”st sowie in seine Bestandteile aufteilt wurde hinzugefgt. Diese Routine fhrt einige Prfungen des Pfades und des Dateinamens durch und behandelt Critical Errors (ungltiges Laufwerk, Laufwerk nicht bereit) ohne Benutzereingriff. Die Routine wird zur Bearbeitung des Programm-Dateinamens, des Kommandoprozessor-Dateinamens und des tempor„ren Dateipfades verwendet. Die Routine ist unabh„ngig von den anderen EXEC/SPAWN-Funktionen, sie kann daher auch in anderen Applikationen ntzlich sein. Einige neue Fehlercodes erlauben eine bessere Analyse von Fehlerursachen. Der Pfad der tempor„ren Datei ist jetzt stets ein vollst„ndiger Pfad. Ein Wechsel von Laufwerk oder Pfad w„hrend der Auslagerung kann daher jetzt nicht mehr zum Verlust der Auslagerungsdatei fhren. Die Prfung auf Existenz einer Datei wurde in checkpat.asm verlagert, und von der 'find first'-Funktion auf 'get file attributes' umgestellt. Dies scheint geringfgig schneller und vermeidet Compiler-Abh„ngigkeiten. Das Programm GETLANG wurde korrigiert, die Hilfs-Meldungen werden jetzt auf stderr ausgegeben. Žnderungen von Version 3.0 auf 3.0a: Ein kleiner Fehler in EXEC.C wurde korrigiert: ein '<' fehlte in einem deutschen Kommentar, sodaá bei GETLANG E ein groáer Teil der Datei verschluckt wurde. Ein Problem (Fehler? Feature?) bei der Turbo C/Borland C "stat" Funktion, die fr Directories stets "read-only" liefern, verhinderte die Benutzung der TEMP Directory beim Auslagern. Die Schreib- Erlaubnis wird jetzt nicht mehr geprft. Die Pr„allozierung der Auslagerungsdatei, die mit Version 3.0 eingefhrt wurde um sicherzustellen daá das Laufwerk den kompletten Speicher fassen kann, fhrte zu starken Verz”gerungen wenn die Auslagerungsdatei auf einem Novell-Netzwerk Laufwerk lag. Um dieses Problem zu umgehen wurden zwei neue Flags fr den "method" Parameter eingefhrt: NO_PREALLOC - Nie Pr„allozieren CHECK_NET - Nicht Pr„allozieren wenn Datei auf Netzwerk Wenn die Datei nicht pr„alloziert wird, wird das Laufwerk nicht auf ausreichenden Platz geprft. Die Alternative, der "get disk free space" Aufruf, dauert im allgemeinen noch wesentlich l„nger als ein Pr„allozieren. Dies ist allerdings kein groáes Problem, die Auslagerung liefert lediglich den Fehlercode 0x502 wenn der Speicherplatz nicht ausreicht. Žnderungen fr Version 3.0: Dies ist die erste Version mit Deutscher Dokumentation. Falls Sie mit frheren Versionen gearbeitet haben, k”nnen Sie die Žnderungen in der Englischen Beschreibung nachlesen - denn dann k”nnen Sie doch Englisch, oder? :)