home *** CD-ROM | disk | FTP | other *** search
Modula Definition | 1994-05-31 | 40.2 KB | 738 lines |
- DEFINITION MODULE proc;
- __DEF_SWITCHES__
- #ifdef HM2
- #ifdef __LONG_WHOLE__
- (*$!i+: Modul muss mit $i- uebersetzt werden! *)
- (*$!w+: Modul muss mit $w- uebersetzt werden! *)
- #else
- (*$!i-: Modul muss mit $i+ uebersetzt werden! *)
- (*$!w-: Modul muss mit $w+ uebersetzt werden! *)
- #endif
- #endif
- (*****************************************************************************)
- (* Funktionen, die mit Prozessen zu tun haben. *)
- (* *)
- (* Ein Fehler ist immer dann aufgetreten, wenn bei Funktionen mit Typ INTEGER*)
- (* ein negativer Wert zurueckgegeben wird. *)
- (* Die genaue Fehlerursache kann bei Bedarf ueber "err.errno" und die ent- *)
- (* sprechenden Konstanten ermittelt werden. Die Funktionen veraendern "errno"*)
- (* nur dann, wenn ein Fehler aufgetreten ist, bei erfolgreicher Ausfuehrung *)
- (* wird "errno" nicht veraendert. *)
- (* *)
- (* GEMDOS: *)
- (* Die Eigenschaften der Funktionen unter dem ``blanken'' GEMDOS sind z.T. *)
- (* stark eingeschraenkt; unter dem Stichwort GEMDOS ist deswegen immer *)
- (* angegeben, in wieweit die Funktion emuliert werden kann. Ist MiNT-Unter- *)
- (* stuetzung angegeben, so ist unter der Betriebssystemerweiterung MiNT *)
- (* eine bessere Unterstuetzung der Funktionen zu erwarten; wie weit diese *)
- (* geht, ist unter dem Stichwort MiNT angegeben. *)
- (* --------------------------------------------------------------------------*)
- (* 31-Mai-94, Holger Kleinschmidt *)
- (*****************************************************************************)
-
- FROM PORTAB IMPORT
- (* TYPE *) ANYLONG, WORDSET;
-
- FROM types IMPORT
- (* TYPE *) int, unsigned, long, sizeT, uidT, gidT, pidT, clockT, StrPtr,
- StrArray;
-
- (*=========================== "times()" =====================================*)
-
- TYPE
- TmsRec = RECORD
- tmsUtime : clockT; (* CPU-Zeit im Benutzercode *)
- tmsStime : clockT; (* CPU-Zeit im System *)
- tmsCUtime : clockT; (* CPU-Zeit im Benutzercode aller beendeten Unterpr.*)
- tmsCStime : clockT; (* CPU-Zeit im System aller beendeten Unterprozesse *)
- END;
-
- (*=========================== "tfork()" =====================================*)
- (* nicht POSIX: *)
- CONST
- MINSTACKSIZE = 4096;
-
- TYPE
- ThreadProc = PROCEDURE(ANYLONG): int;
-
- (*======================= "wait()", "waitpid()" =============================*)
-
- TYPE
- WaitVal = WORDSET;
-
- (* Repraesentation des Typs 'WaitVal' ist nicht zur Benutzung
- * ausserhalb des Moduls gedacht.
- * Konstanten sind nicht POSIX.
- *)
- CONST
- #if reverse_set
- wRetcode = WaitVal{0..7};
- wTermsig = WaitVal{9..15};
- wCoredump = 8;
- wStopval = WaitVal{8..15};
- wStopsig = WaitVal{0..7};
-
- WSTOPPED = WaitVal{9..15};
- #else
- wRetcode = WaitVal{8..15};
- wTermsig = WaitVal{0..6};
- wCoredump = 7;
- wStopval = WaitVal{0..7};
- wStopsig = WaitVal{8..15};
-
- WSTOPPED = WaitVal{0..6};
- #endif
-
- (* IF state * wStopval = WSTOPPED THEN
- * stoppedBy := VAL(CARDINAL,CAST(UNSIGNEDWORD,state * wStopsig) DIV 256);
- * ...
- * ELSIF state * wTermsig <> WaitVal{} THEN
- * terminatedBy := VAL(CARDINAL,CAST(UNSIGNEDWORD,state * wTermsig));
- * coreDumped := wCoredump IN state;
- * ...
- * ELSE
- * retCode := VAL(INTEGER,CAST(SIGNEDWORD,state * wRetcode) DIV 256);
- * ...
- * END;
- *)
-
- TYPE
- #if reverse_set
- WaitOptions = (
- waitop15, waitop14, waitop13, waitop12, waitop11, waitop10, waitop9,
- waitop8, waitop7, waitop6, waitop5, waitop4, waitop3, waitop2,
- WUNTRACED, (* 0002H, Auch gestoppte Unterprozesse beruecksichtigen *)
- WNOHANG (* 0001H, Nicht auf Beendigung warten, sofort zurueck *)
- );
- #else
- WaitOptions = (
- WNOHANG, (* 0001H, Nicht auf Beendigung warten, sofort zurueck *)
- WUNTRACED, (* 0002H, Auch gestoppte Unterprozesse beruecksichtigen *)
- waitop2, waitop3, waitop4, waitop5, waitop6, waitop7, waitop8,
- waitop9, waitop10, waitop11, waitop12, waitop13, waitop14, waitop15
- );
- #endif
-
- WaitOption = PACKEDSET OF WaitOptions;
-
-
- (* Nicht POSIX: *)
- TYPE
- TimevalRec = RECORD
- tvSec : long;
- tvUSec : long;
- END;
-
- TimevalPtr = POINTER TO TimevalRec;
-
- (* Nicht POSIX: *)
- TYPE
- RusageRec = RECORD
- ruUtime : TimevalRec; (* user time used *)
- ruStime : TimevalRec; (* system time used *)
- ruMaxrss : long; (* maximum resident set size *)
- ruIxrss : long; (* integral shared memory size *)
- ruIdrss : long; (* integral unshared data size *)
- ruIsrss : long; (* integral unshared stack size *)
- ruMinflt : long; (* page reclaims *)
- ruMajflt : long; (* page faults (requiring I/O) *)
- ruNswap : long; (* memory swaps *)
- ruInblock : long; (* block input operations *)
- ruOublock : long; (* block output operations *)
- ruMsgsnd : long; (* messages sent *)
- ruMsgrcv : long; (* messages received *)
- ruNsignals : long; (* signals received *)
- ruNvcsw : long; (* voluntary context switches *)
- ruNivcsw : long; (* involuntary context switches *)
- END;
-
-
- (* Nicht POSIX: *)
- (*========= "select()","FDCLR()","FDSET()","FDZERO()","FDISSET()" ===========*)
-
- CONST
- FDSETSIZE = 32;
-
- CONST
- MAXFDSET = 1;
-
- (* 'fdSet' ist eine Menge von Dateikennungen *)
- TYPE
- fdSet = ARRAY [0..MAXFDSET] OF WORDSET;
-
- FdSetPtr = POINTER TO fdSet;
-
- (*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
-
- PROCEDURE chdir ((* EIN/ -- *) REF dir : ARRAY OF CHAR ): int;
-
- (*--------------------------------------------------------------------------
- | Setzt das neue aktuelle Verzeichnis auf <dir>, das bei allen relativen |
- | Pfadangaben benutzt wird. |
- | |
- | GEMDOS: Keine Besonderheiten. |
- | MiNT: -""- |
- --------------------------------------------------------------------------*)
-
- PROCEDURE getcwd ((* EIN/ -- *) buf : StrPtr;
- (* EIN/ -- *) bufsiz : sizeT ): StrPtr;
-
- (*--------------------------------------------------------------------------
- | In <buf>^ wird ein absoluter Pfad des augenblicklichen Arbeitsverzeich- |
- | nisses abgelegt. <bufsiz> bezeichnet den Platz in <buf> fuer Pfad ein- |
- | schliesslich Nullbyte. Der Pfad ist immer mit einem Nullbyte abgeschlos- |
- | sen. Wenn <buf> nicht gross genug ist, wird ein Fehler gemeldet und NULL |
- | als Funktionswert zurueckgeliefert, <buf>^ ist dann undefiniert; sonst |
- | ist der Funktionswert gleich <buf>. |
- | |
- | GEMDOS: Auch wenn <bufsiz> kleiner als 'PATHMAX' ist, wird intern min- |
- | destens ein Puffer dieser Groesse bereitgestellt, damit ein zu |
- | kleiner Wert sauber mit einer Fehlermeldung statt mit einem |
- | Absturz wegen Ueberschreiben fremden Speichers abgefangen wird. |
- | MiNT: Keine Besonderheiten |
- --------------------------------------------------------------------------*)
-
-
- PROCEDURE getlogin ( ): StrPtr;
-
- (*--------------------------------------------------------------------------
- | Liefert einen Zeiger auf einen statischen Speicherbereich, in dem der |
- | login-Name steht, der mit dem aufrufenden Prozess assoziiert ist. |
- | Wenn der login-Name nicht festgestellt werden kann, wird NULL geliefert. |
- | |
- | MiNT/GEMDOS: Der login-Name wird der Environmentvariablen 'LOGNAME' |
- | entnommen. Existiert diese Variable nicht oder ist sie leer,|
- | und die reale Benutzerkennung ist nicht groesser Null, |
- | lautet der name 'root'; sonst wird NULL zurueckgeliefert. |
- --------------------------------------------------------------------------*)
-
-
- PROCEDURE getpid ( ): pidT;
-
- PROCEDURE getppid ( ): pidT;
-
- (*--------------------------------------------------------------------------
- | Liefert die Kennung des eigenen bzw. des uebergeordneten Prozesses. |
- | |
- | GEMDOS: Aus der Adresse der BasePage wird ein eindeutiger Wert berechnet.|
- | MiNT: Keine Besonderheiten. |
- --------------------------------------------------------------------------*)
-
-
- PROCEDURE getuid ( ): uidT;
-
- PROCEDURE getgid ( ): gidT;
-
- PROCEDURE geteuid ( ): uidT;
-
- PROCEDURE getegid ( ): gidT;
-
- PROCEDURE setuid ((* EIN/ -- *) uid : uidT ): int;
-
- PROCEDURE setgid ((* EIN/ -- *) gid : gidT ): int;
-
- (* Noch nicht POSIX: *)
- PROCEDURE seteuid ((* EIN/ -- *) uid : uidT ): int;
-
- (* Noch nicht POSIX: *)
- PROCEDURE setegid ((* EIN/ -- *) gid : gidT ): int;
-
- (* Nicht POSIX: *)
- PROCEDURE setreuid ((* EIN/ -- *) ruid : uidT;
- (* EIN/ -- *) euid : uidT ): int;
-
- (* Nicht POSIX: *)
- PROCEDURE setregid ((* EIN/ -- *) rgid : gidT;
- (* EIN/ -- *) egid : gidT ): int;
-
- (*--------------------------------------------------------------------------
- | Funktionen fuer das Abfragen und Setzen diverser Kennungen: |
- | "getuid/gid" : liefern reale Benutzer- bzw. Gruppenkennung des aufrufen-|
- | den Prozesses. |
- | "geteuid/gid" : liefern effektive Benutzer- bzw. Gruppenkennung des auf- |
- | rufenden Prozesses. |
- | "setuid/gid" : setzen reale und effektive Benutzer- bzw. Gruppenkennung |
- | des aufrufenden Prozesses auf <uid> bzw. <gid>. |
- | Nur erlaubt, wenn der aufrufende Prozess die entsprechen-|
- | den rechte besitzt (-> 'root'), oder 'uid'/'gid' der |
- | Kennung entspricht. |
- | "seteuid/gid" : wie "setuid/gid", es wird aber nur die effektive Kennung |
- | gesetzt. |
- | "setreuid/gid": setzen reale und effektive Kennungen getrennt. |
- | |
- | Die realen Kennungen identifizieren den Benutzer bzw. die Gruppe. |
- | |
- | Der Zugriff auf Systemressourcen (z.B. Dateien) wird ueber die effektiven|
- | Kennungen geregelt, die normalerweise gleich den realen Kennungen sind, |
- | es sei denn, es wird ein Programm ausgefuehrt, das die ``set user id'' |
- | oder ``set group id'' Bits im Modusfeld gesetzt hat, wodurch der ausfueh-|
- | rende Prozess als effektive Kennung die Kennung des Dateibesitzers und |
- | damit auch seine Zugriffsberechtigung bekommt. Die realen Kennungen |
- | werden hiedurch aber nicht beeinflusst. |
- | |
- | GEMDOS: Die Kennung ist immer gleich Null (``Superuser''). |
- | MiNT: "seteuid/gid" ist gleich "setuid/gid", "setreuid/gid(r,e)" ist |
- | gleich "setuid/gid(e)". |
- --------------------------------------------------------------------------*)
-
-
- PROCEDURE getpgrp ( ): pidT;
-
- PROCEDURE setpgid ((* EIN/ -- *) pid : pidT;
- (* EIN/ -- *) pgid : pidT ): int;
-
- PROCEDURE setsid ( ): pidT;
-
- (*--------------------------------------------------------------------------
- | "getpgrp()": ermittelt die Prozessgruppe des aufrufenden Prozesses. |
- | "setpgid()": Setzt die Prozessgruppe des Prozesses <pid> auf den Wert |
- | <pgid>. Wenn <pid> oder <pgid> Null sind, wird stattdessen |
- | die Prozesskennung des aufrufenden Prozesses eingesetzt. |
- | "setsid()" : Der aufrufende Prozess verliert sein Kontrollterminal (von |
- | dem aus bestimmte Tasten Signale ausloesen koennen - fuer |
- | ``job control''), und wird zum einzigen Mitglied einer |
- | neuen Prozessgruppe, die das einzige Mitglied einer neuen |
- | ``Session'' ist. Die Prozessgruppe ist die Prozesskennung |
- | des aufrufenden Prozesses. Wenn der Prozess bereits eine |
- | Prozessgruppe anfuehrt (Kennung der Prozesses ist auch Ken- |
- | nung der Prozessgruppe), darf die Funktion nicht ausgefuehrt|
- | werden. |
- | |
- | GEMDOS: "getpgrp()" liefert den gleichen Wert wie "getpid()". Fuer <pid> |
- | und <pgid> bei "setpgid()" sind nur Null und der Wert von |
- | "getpid()" erlaubt. "setsid()" liefert immer -1 (errno = 'EPERM')|
- | MiNT: "getpgrp()" und "setpgid()": Keine Besonderheiten. |
- | "setsid()": Der Unterschied zwischen einer ``Session'' und einer |
- | Prozessgruppe ist mir nicht klar. Ueberhaupt ist mir unklar, in- |
- | wieweit "MiNT-psetpgrp()" den POSIX-Funktionen "setpgid()" und |
- | "setsid()" entspricht, deshalb kann es sein, dass die Funktions- |
- | weise nicht ganz korrekt ist. |
- --------------------------------------------------------------------------*)
-
-
- PROCEDURE fork ( ): pidT;
-
- (*--------------------------------------------------------------------------
- | Der aktuelle Prozess wird in zwei gleichartige Prozesse aufgeteilt, aber |
- | mit getrenntem Speicherbereich und unterschiedlichen Prozesskennungen. |
- | Konnte der neue Prozess nicht erzeugt werden, wird dem aufrufenden Pro- |
- | zess ein Fehler gemeldet; sonst liefert die Funktion dem aufrufenden |
- | (= Parent) die (positive) Prozesskennung des neuen Prozesses (= Child) |
- | und dem neuen Prozess eine Null. |
- | |
- | GEMDOS: Liefert immer -1 (errno = 'ENOSYS'). |
- | MiNT: Keine Besonderheiten. |
- --------------------------------------------------------------------------*)
-
-
- (* Nicht POSIX: *)
- PROCEDURE vfork ( ): pidT;
-
- (*--------------------------------------------------------------------------
- | Funktion wie "fork()", die Prozesse benutzen aber denselben Speicher- |
- | bereich, insbesondere benutzen sie auch denselben Stack. |
- | |
- | Bei der Anwendung der Funktion ist etwas Vorsicht geboten: |
- | Zwischen dem "vfork()" und dem Pterm oder "execv*()" des Kindprozesses |
- | darf der Stackpointer nicht hochgesetzt werden, etwa durch einen Aufruf |
- | von "vfork()" innerhalb einer WITH- oder FOR-Anweisung oder innerhalb |
- | einer Prozedur, und dem Aufruf von "execv*()" ausserhalb, denn sonst |
- | ueberschreibt der Kindprozess fuer den Elternprozess wichtige Informa- |
- | tionen, wenn er etwas auf dem Stack ablegt; und das geschieht spaetestens|
- | beim Terminieren des Kindprozesses oder dem Ueberlagern mit einem neuen |
- | Programm durch "execv*()", denn die Parameter werden auf dem Stack abge- |
- | legt. Das Ergebnis ist mit Sicherheit ein Absturz, vor allem, wenn |
- | "vfork()" innerhalb einer Prozedur aufgerufen wird -- dann fehlt naemlich|
- | die Return-Adresse fuer den Elternprozess. |
- | |
- | GEMDOS/MiNT: Die Gruende fuer die Schwierigkeiten sind allerdings bei |
- | GEMDOS und MiNT unterschiedlich: |
- | Unter MiNT wird fuer Eltern- und Kindprozess tatsaechlich derselbe Stack |
- | benutzt, mit den eben erwaehnten Folgen. Unter GEMDOS wird "vfork()" |
- | durch "tfork()" emuliert, wodurch der Kindprozess einen anderen Stack |
- | erhaelt, und folglich keine vorher auf dem Stack abgelegte Werte mehr |
- | gueltig sind. |
- | |
- | Mit Megamax-Modula funktioniert die Prozedur nur unter MiNT. |
- --------------------------------------------------------------------------*)
-
-
- (* Nicht POSIX: *)
- PROCEDURE SetStacksize ((* EIN/ -- *) stacksize : CARDINAL );
-
- (* Nicht POSIX: *)
- PROCEDURE tfork ((* EIN/ -- *) func : ThreadProc;
- (* EIN/ -- *) arg : ANYLONG ): int;
-
- (*--------------------------------------------------------------------------
- | "tfork()" generiert aus einer Funktion vom Typ 'ThreadProc' einen neuen |
- | Prozess mit eigener Prozesskennung und eigenem Stack, der sonstige |
- | Adressraum ist aber derselbe wie beim aufrufenden Prozess, d.h. auf |
- | globale Variablen wird gemeinsam zugegriffen. Deshalb ist auch Vorsicht |
- | bei der Benutzung von Bibliotheksfunktionen innerhalb des neuen Prozesses|
- | (``Thread'') geboten; insbesondere sollte die Speicherverwaltung nicht |
- | verwendet werden ("NEW()", "DISPOSE()" ...). Ansonsten muss ausprobiert |
- | werden, was funktioniert. |
- | Mit "SetStacksize()" laesst sich die Stackgroesse des neuen Prozesses |
- | festlegen; sie kann aber nicht kleiner als 'MINSTACKSIZE' werden. |
- --------------------------------------------------------------------------*)
-
-
- PROCEDURE execve ((* EIN/ -- *) REF prg : ARRAY OF CHAR;
- (* EIN/ -- *) argv : StrArray;
- (* EIN/ -- *) envp : StrArray ): int;
-
- PROCEDURE execv ((* EIN/ -- *) REF prg : ARRAY OF CHAR;
- (* EIN/ -- *) argv : StrArray ): int;
-
- PROCEDURE execvp ((* EIN/ -- *) REF prg : ARRAY OF CHAR;
- (* EIN/ -- *) argv : StrArray ): int;
-
- (*--------------------------------------------------------------------------
- | Ersetzt den aufrufenden Prozess durch einen neuen, der aus dem Programm |
- | gebildet wird, dessen Dateiname <prg> ist. <args> und <env> sind Felder |
- | aus Zeigern auf Parameter und Environment-Variablen, sodass der neue |
- | Prozess diese als Elemente der Kommandozeile bzw. als Environment-Variab-|
- | len holen kann. |
- | Ist <envp> = NULL, wird das augenblickliche Environment vererbt. |
- | Falls ein Fehler auftritt, wird ein negativer Wert zurueckgeliefert, |
- | andernfalls kehrt die Funktion NICHT zum Aufrufer zurueck, da dieser |
- | durch das neue Programm ersetzt wurde. |
- | Mit der Kombination "fork()" & "execve()" koennen somit neue Prozesse |
- | gestartet werden. |
- | |
- | Spezielle Versionen von "execve()": |
- | |
- | "execv()" : es wird das augenblickliche Environment vererbt. |
- | "execvp()": das augenblickliche Environment wird vererbt, und <prg> wird |
- | in allen in PATH angegebenen Verzeichnissen gesucht. |
- | |
- | GEMDOS: Funktioniert, ist aber ohne "fork()" nicht sinnvoll. |
- | MiNT: Keine Besonderheiten. |
- | Die Kommandozeilenparameter werden dem neuen Programm ueber die normale |
- | Kommandozeile in der BasePage und das ARGV-Verfahren (einschlisslich |
- | Erweiterung fuer leere Argumente) mitgeteilt. |
- | Falls <prg> bei "execvp()" keine Extension hat, werden die in der |
- | Environmentvariablen 'TOSEXT' angegebenen Extensionen ausprobiert, und |
- | zum Schluss immer die Datei OHNE Extension. Falls 'TOSEXT' nicht |
- | existiert, werden die Extensionen aus 'DosSupport.TOSEXT' probiert. |
- --------------------------------------------------------------------------*)
-
-
-
-
- PROCEDURE waitpid ((* EIN/ -- *) pid : pidT;
- (* -- /AUS *) VAR state : WaitVal;
- (* EIN/ -- *) options : WaitOption ): pidT;
-
- (*--------------------------------------------------------------------------
- | Wartet auf die Beendigung oder das Stoppen eines vom aufrufenden Prozess |
- | gestarteten Unterprozesses. Als Funktionswert wird die 'pid' des ent- |
- | sprechenden Prozesses oder -1 bei einem Fehler (z.B. wenn keine Prozesse |
- | gestartet wurden) zurueckgeliefert. In <state> steht kodiert die Ursache |
- | der Beendigung oder des Stoppens (siehe Definition von 'WaitVal'). |
- | Mit <options> wird das Verhalten der Prozedur festgelegt (siehe Def. von |
- | 'WaitOptions'). |
- | Mit <pid> wird festgelegt, welche Unterprozesse beruecksichtigt werden |
- | sollen: |
- | |
- | <pid> = -1: alle Unterprozesse |
- | <pid> > 0: nur Unterprozess mit dieser Prozesskennung |
- | <pid> = 0: alle Unterprozesse mit der gleichen Prozessgruppenkennung |
- | wie der aufrufende Prozess |
- | <pid> < -1: alle Unterprozesse, die |<pid>| als Prozessgruppenkennung |
- | haben |
- | |
- | GEMDOS: Wenn <pid> = 0 oder -1, wird die Prozesskennung des letzten mit |
- | "tfork()" gestarteten Unterprozesses geliefert, sonst wird immer |
- | -1 geliefert (errno = 'ECHILD'). |
- | MiNT: Keine Besonderheiten. |
- --------------------------------------------------------------------------*)
-
- PROCEDURE wait ((* -- /AUS *) VAR state : WaitVal ): pidT;
-
- (*--------------------------------------------------------------------------
- | Aequivalent zu "waitpid(-1, state, WaitOption{})", es werden also keine |
- | gestoppten Unterprozesse beruecksichtigt. |
- | |
- | GEMDOS: siehe "waitpid()". |
- | MiNT: Keine Besonderheiten. |
- --------------------------------------------------------------------------*)
-
- (* Nicht POSIX: *)
- PROCEDURE wait3 ((* -- /AUS *) VAR state : WaitVal;
- (* EIN/ -- *) options : WaitOption;
- (* -- /AUS *) VAR usage : RusageRec ): pidT;
-
- (*--------------------------------------------------------------------------
- | Variante von "waitpid()": <state> und <options> sind entsprechend, es |
- | werden alle Unterprozesse beruecksichtigt, und in <usage> werden Infor- |
- | mationen ueber die vom beendeten Unterprozess benoetigten Resourcen |
- | abgelegt. |
- | |
- | GEMDOS/MiNT: In <usage> enthalten nur die ersten beiden Felder einen |
- | sinnvollen Wert, sonst siehe "waitpid()". |
- --------------------------------------------------------------------------*)
-
- (* Nicht POSIX: *)
- PROCEDURE wait4 ((* EIN/ -- *) pid : pidT;
- (* -- /AUS *) VAR state : WaitVal;
- (* EIN/ -- *) options : WaitOption;
- (* -- /AUS *) VAR usage : RusageRec ): pidT;
-
- (*--------------------------------------------------------------------------
- | Falls <pid> gleich Null, entspricht die Funktion "wait3()". Falls <pid> |
- | groesser als Null ist, wird nur der Unterprozess mit dieser Kennung |
- | beruecksichtigt. |
- --------------------------------------------------------------------------*)
-
-
-
- PROCEDURE WIFEXITED ((* EIN/ -- *) state : WaitVal ): BOOLEAN;
- PROCEDURE WEXITSTATUS ((* EIN/ -- *) state : WaitVal ): int;
-
- PROCEDURE WIFSIGNALED ((* EIN/ -- *) state : WaitVal ): BOOLEAN;
- PROCEDURE WTERMSIG ((* EIN/ -- *) state : WaitVal ): int;
-
- PROCEDURE WIFSTOPPED ((* EIN/ -- *) state : WaitVal ): BOOLEAN;
- PROCEDURE WSTOPSIG ((* EIN/ -- *) state : WaitVal ): int;
-
- (*--------------------------------------------------------------------------
- | Diese Funktionen sind bei POSIX als Makros definiert. |
- | |
- | "WIFEXITED()" : TRUE, genau dann, wenn der Unterprozess ``normal'' been-|
- | det wurde, d.h. nicht durch ein Signal. |
- | "WEXITSTATUS()": Falls "WIFEXITED()" = TRUE, wird der Returncode des |
- | Unterprozesses geliefert. Dabei werden aber nur die |
- | unteren 8 Bit des Returncodes benutzt und vorzeichen- |
- | richtig erweitert. |
- | Wenn "WIFEXITED()" = FALSE, ist der Funktionswert nicht |
- | definiert ! |
- | "WIFSIGNALED()": TRUE, genau dann, wenn der Unterprozess durch ein Signal|
- | beendet wurde. |
- | "WTERMSIG()" : Falls "WIFSIGNALED()" = TRUE, wird der Ordinalwert des |
- | beendenden Signals geliefert. |
- | Wenn "WIFSIGNALED()" = FALSE,ist der Funktionswert nicht|
- | definiert ! |
- | "WIFSTOPPED()" : TRUE, genau dann, wenn der Unterprozess momentan ge- |
- | stoppt, aber nicht beendet ist (``Job Control''). |
- | "WSTOPSIG()" : Falls "WIFSTOPPED()" = TRUE, wird der Ordinalwert des |
- | Signals, das den Prozess gestoppt hat, geliefert. |
- | Wenn "WIFSTOPPED()" = FALSE, ist der Funktionswert nicht|
- | definiert ! |
- | |
- | Es sollten ausschliesslich diese Funktionen benutzt werden, um einen |
- | Status vom Typ 'WaitVal' zu analysieren. |
- | |
- | GEMDOS: keine Besonderheiten. |
- | MiNT: -""- |
- --------------------------------------------------------------------------*)
-
-
- (* Nicht POSIX: *)
- PROCEDURE FDZERO ((* -- /AUS *) VAR fdset : fdSet );
-
- PROCEDURE FDSET ((* EIN/ -- *) fd : int;
- (* -- /AUS *) VAR fdset : fdSet );
-
- PROCEDURE FDCLR ((* EIN/ -- *) fd : int;
- (* -- /AUS *) VAR fdset : fdSet );
-
- PROCEDURE FDISSET ((* EIN/ -- *) fd : int;
- (* EIN/ -- *) fdset : fdSet ): BOOLEAN;
-
- (*--------------------------------------------------------------------------
- | Funktionen zur Manipulation von Variablen des Typs 'fdSet'. |
- | Es MUESSEN(!) ausschliesslich diese Funktionen benutzt werden, um |
- | Variablen vom Typ 'fdSet' zu manipulieren, da die Zuordnung von Elementen|
- | zur unterliegenden Bitrepraesentation NICHT festgelegt ist! |
- | Die Funktionen sind unter *IX als Makros definiert. |
- | |
- | "FDZERO" : Loescht die Menge <fdSet>. |
- | "FDSET" : Setzt die Dateikennung <fd> in <fdSet>. |
- | "FDCLR" : Loescht die Dateikennung <fd> in <fdSet>. |
- | "FDISSET" : Testet, ob die Dateikennung <fd> in <fdSet> gesetzt ist. |
- | |
- | GEMDOS: Keine Besonderheiten. |
- | MiNT: -""- |
- --------------------------------------------------------------------------*)
-
- (* Nicht POSIX: *)
- PROCEDURE select ((* EIN/ -- *) width : int;
- (* EIN/ -- *) readfds : FdSetPtr;
- (* EIN/ -- *) writefds : FdSetPtr;
- (* EIN/ -- *) exceptfds : FdSetPtr;
- (* EIN/ -- *) timeout : TimevalPtr ): int;
-
- (*--------------------------------------------------------------------------
- | Mithilfe dieser Prozedur kann auf das Eintreten bestimmter Bedingungen |
- | bei geoeffneten Dateien unter Einhaltung eines Timeouts gewartet werden. |
- | |
- | Die Dateien werden als Elemente von Mengen angegeben, wobei die |
- | Ordnungszahl jedes Elements einer Dateikennung entspricht, also z.B. |
- | Element 0 fuer die Standardeingabe. Es werden nur die Dateikennungen |
- | beachtet, deren Wert kleiner als <width> ist; Ist <width> groesser oder |
- | gleich FDSETSIZE, werden alle Kennungen beachtet. Falls kein Fehler |
- | auftritt, werden in den angegebenen Mengen ausschliesslich die Datei- |
- | kennungen gesetzt, bei denen die Bedingungen eingetreten sind, die |
- | anderen Elemente werden geloescht; die Ergebnismengen sind immer Teil- |
- | mengen der urspruenglichen Mengen. <readfds>^ repraesentiert die Menge |
- | der Dateien, bei denen auf das Bereitwerden zum Lesen gewartet werden |
- | soll, <writefds>^ repraesentiert die Dateien, bei denen auf das Bereit- |
- | werden zum Schreiben gewartet werden soll und <exceptfds>^ repraesentiert|
- | die Dateien, bei denen auf das Eintreten einer Ausnahmebedingung gewartet|
- | werden soll. |
- | |
- | Die Funktion kehrt zurueck, sobald mindestens bei einer Datei die angege-|
- | bene Bedingung eingetreten oder der Timeout abgelaufen ist. Als |
- | Funktionswert wird die Anzahl der bereiten Kennungen geliefert (also die |
- | Anzahl der in allen Mengen zusammen enthaltenen Elemente) oder Null, |
- | falls der Timeout abgelaufen (dann sind auch alle Mengen leer) ist oder |
- | -1, falls ein Fehler aufgetreten ist (dann ist der Inhalt der Mengen |
- | undefiniert). Ist einer der Zeiger gleich NULL, wird er nicht beachtet. |
- | In <timeout> ist angegeben, wie lange maximal auf das Bereitwerden der |
- | angegebenen Dateien gewartet wird, bevor die Funktion von selbst |
- | zurueckkehrt. Ist <timeout> gleich NULL, wird ohne Timeout auf das |
- | Bereitwerden der angegebenen Dateien gewartet; ist <timeout>^ gleich |
- | Null, wird nur der augenblickliche Zustand der Dateien abgefragt, und die|
- | Funktion kehrt sofort zurueck -- dies kann fuer ein ``Pollen'' benutzt |
- | werden. |
- | |
- | GEMDOS: Nicht implementiert |
- | MiNT: <exceptfds>^ wird nicht ausgewertet und immer geloescht. |
- --------------------------------------------------------------------------*)
-
-
-
- PROCEDURE times ((* -- /AUS *) VAR buf : TmsRec ): clockT;
-
- (*--------------------------------------------------------------------------
- | Liefert Informationen ueber die vom Prozess und seine Unterprozesse ver- |
- | brauchte Zeit (siehe Def. von 'TmsRec'); die Zeiten sind in der Einheit |
- | 'sys.ClkTck's / Sekunde angegeben. |
- | Als Funktionswert wird die vergangene Zeit seit einem beliebigen, aber |
- | festen Zeitpunkt in der Vergangenheit zurueckgeliefert; durch mehrmaligen|
- | Aufruf der Funktion koennen so Zeitdifferenzen gemessen werden. Auch hier|
- | ist die Einheit 'sys.ClkTck's / Sekunde. |
- | |
- | GEMDOS: Die im System verbrachte Zeit kann nicht festgestellt werden. |
- | MiNT: Keine Besonderheiten. |
- --------------------------------------------------------------------------*)
-
- (* Nicht POSIX: *)
- PROCEDURE clock ( ): clockT;
-
- (*--------------------------------------------------------------------------
- | Liefert die (Prozessor)Zeit, die der aufrufende Prozess bisher verbraucht|
- | hat, in der Einheit 'sys.ClkTck's / Sekunde. |
- | |
- | GEMDOS/MiNT: Die Summe von 'TmsRec.tmsUtime' und 'TmsRec.tmsStime' eines |
- | "times()"-Aufrufs wird zurueckgeliefert. |
- --------------------------------------------------------------------------*)
-
-
-
- PROCEDURE Exit ((* EIN/ -- *) retval : int );
-
- (*--------------------------------------------------------------------------
- | Der aufrufende Prozess wird mit dem Returncode <retval> beendet. |
- | <retVal> sollte im Bereich [-128..127] liegen, da im Typ 'WaitVal' nur |
- | 8 Bit des Returncodes untergebracht werden koennen. |
- | Die Prozedur muesste eigentlich "_exit()" heissen! |
- | |
- | GEMDOS: keine Besonderheiten. |
- | MiNT: -""- |
- --------------------------------------------------------------------------*)
-
-
-
-
- (*===========================================================================*)
- (* Die folgenden Funktionen haben NICHTS mit POSIX oder *IX zu tun, sind *)
- (* jedoch fuer "PCDOS" und "GEMDOS" notwendig, um ein *IX-like *)
- (* Programmstarten zu ermoeglichen. Fuer *IX sind die Funktionen immerhin *)
- (* bequem. *)
- (*===========================================================================*)
-
- TYPE
- SpawnMode = (
- pOVERLAY, (* Aufrufer wird durch neuen Prozess ersetzt (= exec)*)
- pNOWAIT, (* neuer Prozess laeuft parallel zum erzeugenden Prozess *)
- pWAIT (* Erzeugender Prozess wird unterbrochen *)
- );
-
- (*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
-
- PROCEDURE spawnve ((* EIN/ -- *) mode : SpawnMode;
- (* EIN/ -- *) REF prg : ARRAY OF CHAR;
- (* EIN/ -- *) argv : StrArray;
- (* EIN/ -- *) envp : StrArray ): int;
-
- (*--------------------------------------------------------------------------
- | Diese Prozedur fasst die Prozeduren "fork()", "execve()" und "waitpid()" |
- | auf unterschiedliche Weise zusammen. |
- | |
- | <mode> = pOVERLAY: "spawnve()" entspricht "execve()" |
- | <mode> = pNOWAIT : es wird ein "fork()" ausgefuehrt, und dann <prg> mit |
- | "execve()" gestartet. |
- | Rueckgabewert ist entweder -1 und 'errno' wird gesetzt|
- | falls beim Aufruf von "spawnve()" etwas schiefgeht, |
- | oder die positive 'pid' des erzeugten Prozesses. |
- | <mode> = pWAIT : wie pNOWAIT, aber es wird mit "waitpid()" auf das Ende|
- | des erzeugten Prozesses gewartet. Falls beim Aufruf |
- | von "spawnve()" etwas schiefgeht, ist der Rueckgabe- |
- | wert gleich -1 und 'errno' wird gesetzt, ansonsten |
- | wird 'errno' auf Null gesetzt(!), und die unteren 16 |
- | Bit des Funktionswertes sind vom Typ 'WaitVal'. Da im |
- | oberen Byte von 'WaitVal' der Returncode des aufgeru- |
- | fenen Prozesses enthalten ist (falls der Prozess nicht|
- | durch ein Signal gestoppt oder terminiert wurde) und |
- | dieser auch negativ sein kann, und 'WaitVal' fuer den |
- | Funktionswert auch vorzeichenrichtig auf int-Groesse |
- | erweitert wird, muss ein Fehler von "spawnve()" |
- | durch Inspizieren von 'errno' ermittelt werden: |
- | |
- | ret := spawnve(pWAIT,...); |
- | IF errno <> 0 THEN |
- | (* "spawnve()"-Fehler *) |
- | ... |
- | |
- | GEMDOS/MiNT: |
- | Diese Prozedur laeuft fuer <mode> = 'pWAIT' oder 'pOVERLAY' |
- | auch ohne MiNT. |
- | ACHTUNG: Es wird wirklich nur das Programm ueber 'Pexec' ge- |
- | startet, es wird weder der Bildschirm geloescht, die Maus aus- |
- | geschaltet, noch der Critical-Error-Handler umgesetzt! Ehe man |
- | jetzt aber selbst daran geht dies zu tun, sollte man daran den-|
- | ken, dass es zum Chaos fuehrt, falls Prozesse parallel laufen |
- | (unter MiNT), da es nur einen Bildschirm, eine Maus und einen |
- | Error-Handler (vor MiNT 0.95) gibt! Das Problem laesst sich nur|
- | loesen, wenn TOS-Programme ihre Ausgaben in GEM-Fenster schrei-|
- | ben, wie dies unter MultiTOS der Fall sein wird. |
- | Wenn ein (Unter)Prozess keine Bidschirmausgaben macht, ist dies|
- | natuerlich kein Problem. |
- | Ohne MiNT wird Pexec mit Modus 0 (pWAIT) gestartet, sonst |
- | sind auch Modus 100 (pNOWAIT) und 200 (pOVERLAY) moeglich. |
- | ("MiNT"-Unterstuetzung.) |
- --------------------------------------------------------------------------*)
-
-
-
- PROCEDURE spawnv ((* EIN/ -- *) mode : SpawnMode;
- (* EIN/ -- *) REF prg : ARRAY OF CHAR;
- (* EIN/ -- *) argv : StrArray ): int;
-
- PROCEDURE spawnvp ((* EIN/ -- *) mode : SpawnMode;
- (* EIN/ -- *) REF prg : ARRAY OF CHAR;
- (* EIN/ -- *) argv : StrArray ): int;
-
- (*--------------------------------------------------------------------------
- | Spezielle Versionen von "spawnve()": |
- | |
- | "spawnv()" : es wird das augenblickliche Environment vererbt. |
- | "spawnvp()" : das augenblickliche Environment wird vererbt, und <prg> |
- | wird in allen in PATH angegebenen Verzeichnissen gesucht. |
- --------------------------------------------------------------------------*)
-
- END proc.
-