home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / program / compiler / m2posx14 / src / proc.dpp < prev    next >
Encoding:
Modula Definition  |  1994-05-31  |  40.2 KB  |  738 lines

  1. DEFINITION MODULE proc;
  2. __DEF_SWITCHES__
  3. #ifdef HM2
  4. #ifdef __LONG_WHOLE__
  5. (*$!i+: Modul muss mit $i- uebersetzt werden! *)
  6. (*$!w+: Modul muss mit $w- uebersetzt werden! *)
  7. #else
  8. (*$!i-: Modul muss mit $i+ uebersetzt werden! *)
  9. (*$!w-: Modul muss mit $w+ uebersetzt werden! *)
  10. #endif
  11. #endif
  12. (*****************************************************************************)
  13. (* Funktionen, die mit Prozessen zu tun haben.                               *)
  14. (*                                                                           *)
  15. (* Ein Fehler ist immer dann aufgetreten, wenn bei Funktionen mit Typ INTEGER*)
  16. (* ein negativer Wert zurueckgegeben wird.                                   *)
  17. (* Die genaue Fehlerursache kann bei Bedarf ueber "err.errno" und die ent-   *)
  18. (* sprechenden Konstanten ermittelt werden. Die Funktionen veraendern "errno"*)
  19. (* nur dann, wenn ein Fehler aufgetreten ist, bei erfolgreicher Ausfuehrung  *)
  20. (* wird "errno" nicht veraendert.                                            *)
  21. (*                                                                           *)
  22. (* GEMDOS:                                                                   *)
  23. (* Die Eigenschaften der Funktionen unter dem ``blanken'' GEMDOS sind z.T.   *)
  24. (* stark eingeschraenkt; unter dem Stichwort GEMDOS ist deswegen immer       *)
  25. (* angegeben, in wieweit die Funktion emuliert werden kann. Ist MiNT-Unter-  *)
  26. (* stuetzung angegeben, so ist unter der Betriebssystemerweiterung MiNT      *)
  27. (* eine bessere Unterstuetzung der Funktionen zu erwarten; wie weit diese    *)
  28. (* geht, ist unter dem Stichwort MiNT angegeben.                             *)
  29. (* --------------------------------------------------------------------------*)
  30. (* 31-Mai-94, Holger Kleinschmidt                                            *)
  31. (*****************************************************************************)
  32.  
  33. FROM PORTAB IMPORT
  34. (* TYPE *) ANYLONG, WORDSET;
  35.  
  36. FROM types IMPORT
  37. (* TYPE *) int, unsigned, long, sizeT, uidT, gidT, pidT, clockT, StrPtr,
  38.            StrArray;
  39.  
  40. (*=========================== "times()" =====================================*)
  41.  
  42. TYPE
  43.   TmsRec = RECORD
  44.     tmsUtime  : clockT; (* CPU-Zeit im Benutzercode *)
  45.     tmsStime  : clockT; (* CPU-Zeit im System *)
  46.     tmsCUtime : clockT; (* CPU-Zeit im Benutzercode aller beendeten Unterpr.*)
  47.     tmsCStime : clockT; (* CPU-Zeit im System aller beendeten Unterprozesse *)
  48.   END;
  49.  
  50. (*=========================== "tfork()" =====================================*)
  51. (* nicht POSIX: *)
  52. CONST
  53.   MINSTACKSIZE = 4096;
  54.  
  55. TYPE
  56.   ThreadProc = PROCEDURE(ANYLONG): int;
  57.  
  58. (*======================= "wait()", "waitpid()" =============================*)
  59.  
  60. TYPE
  61.   WaitVal = WORDSET;
  62.  
  63. (* Repraesentation des Typs 'WaitVal' ist nicht zur Benutzung
  64.  * ausserhalb des Moduls gedacht.
  65.  * Konstanten sind nicht POSIX.
  66.  *)
  67. CONST
  68. #if reverse_set
  69.   wRetcode  = WaitVal{0..7};
  70.   wTermsig  = WaitVal{9..15};
  71.   wCoredump = 8;
  72.   wStopval  = WaitVal{8..15};
  73.   wStopsig  = WaitVal{0..7};
  74.  
  75.   WSTOPPED  = WaitVal{9..15};
  76. #else
  77.   wRetcode  = WaitVal{8..15};
  78.   wTermsig  = WaitVal{0..6};
  79.   wCoredump = 7;
  80.   wStopval  = WaitVal{0..7};
  81.   wStopsig  = WaitVal{8..15};
  82.  
  83.   WSTOPPED  = WaitVal{0..6};
  84. #endif
  85.  
  86.  (*  IF state * wStopval = WSTOPPED THEN
  87.   *    stoppedBy := VAL(CARDINAL,CAST(UNSIGNEDWORD,state * wStopsig) DIV 256);
  88.   *    ...
  89.   *  ELSIF state * wTermsig <> WaitVal{} THEN
  90.   *    terminatedBy := VAL(CARDINAL,CAST(UNSIGNEDWORD,state * wTermsig));
  91.   *    coreDumped   := wCoredump IN state;
  92.   *    ...
  93.   *  ELSE
  94.   *    retCode := VAL(INTEGER,CAST(SIGNEDWORD,state * wRetcode) DIV 256);
  95.   *    ...
  96.   *  END;
  97.   *)
  98.  
  99. TYPE
  100. #if reverse_set
  101.   WaitOptions = (
  102.     waitop15, waitop14, waitop13, waitop12, waitop11, waitop10, waitop9,
  103.     waitop8,  waitop7,  waitop6,  waitop5,  waitop4,  waitop3,  waitop2,
  104.     WUNTRACED, (* 0002H, Auch gestoppte Unterprozesse beruecksichtigen *)
  105.     WNOHANG    (* 0001H, Nicht auf Beendigung warten, sofort zurueck *)
  106.   );
  107. #else
  108.   WaitOptions = (
  109.     WNOHANG,   (* 0001H, Nicht auf Beendigung warten, sofort zurueck *)
  110.     WUNTRACED, (* 0002H, Auch gestoppte Unterprozesse beruecksichtigen *)
  111.     waitop2, waitop3,  waitop4,  waitop5,  waitop6,  waitop7,  waitop8,
  112.     waitop9, waitop10, waitop11, waitop12, waitop13, waitop14, waitop15
  113.   );
  114. #endif
  115.  
  116.   WaitOption = PACKEDSET OF WaitOptions;
  117.  
  118.  
  119. (* Nicht POSIX: *)
  120. TYPE
  121.   TimevalRec = RECORD
  122.     tvSec  : long;
  123.     tvUSec : long;
  124.   END;
  125.  
  126.   TimevalPtr = POINTER TO TimevalRec;
  127.  
  128. (* Nicht POSIX: *)
  129. TYPE
  130.   RusageRec = RECORD
  131.     ruUtime    : TimevalRec; (* user time used *)
  132.     ruStime    : TimevalRec; (* system time used *)
  133.     ruMaxrss   : long;       (* maximum resident set size *)
  134.     ruIxrss    : long;       (* integral shared memory size *)
  135.     ruIdrss    : long;       (* integral unshared data size *)
  136.     ruIsrss    : long;       (* integral unshared stack size *)
  137.     ruMinflt   : long;       (* page reclaims *)
  138.     ruMajflt   : long;       (* page faults (requiring I/O) *)
  139.     ruNswap    : long;       (* memory swaps *)
  140.     ruInblock  : long;       (* block input operations *)
  141.     ruOublock  : long;       (* block output operations *)
  142.     ruMsgsnd   : long;       (* messages sent *)
  143.     ruMsgrcv   : long;       (* messages received *)
  144.     ruNsignals : long;       (* signals received *)
  145.     ruNvcsw    : long;       (* voluntary context switches *)
  146.     ruNivcsw   : long;       (* involuntary context switches *)
  147.   END;
  148.  
  149.  
  150. (* Nicht POSIX: *)
  151. (*========= "select()","FDCLR()","FDSET()","FDZERO()","FDISSET()" ===========*)
  152.  
  153. CONST
  154.   FDSETSIZE = 32;
  155.  
  156. CONST
  157.   MAXFDSET = 1;
  158.  
  159. (* 'fdSet' ist eine Menge von Dateikennungen *)
  160. TYPE
  161.   fdSet = ARRAY [0..MAXFDSET] OF WORDSET;
  162.  
  163.   FdSetPtr = POINTER TO fdSet;
  164.  
  165. (*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
  166.  
  167.  PROCEDURE chdir ((* EIN/ -- *) REF dir : ARRAY OF CHAR ): int;
  168.  
  169. (*--------------------------------------------------------------------------
  170.  | Setzt das neue aktuelle Verzeichnis auf <dir>, das bei allen relativen   |
  171.  | Pfadangaben benutzt wird.                                                |
  172.  |                                                                          |
  173.  | GEMDOS: Keine Besonderheiten.                                            |
  174.  |   MiNT: -""-                                                             |
  175.   --------------------------------------------------------------------------*)
  176.  
  177.  PROCEDURE getcwd ((* EIN/ -- *) buf    : StrPtr;
  178.                    (* EIN/ -- *) bufsiz : sizeT   ): StrPtr;
  179.  
  180. (*--------------------------------------------------------------------------
  181.  | In <buf>^ wird ein absoluter Pfad des augenblicklichen Arbeitsverzeich-  |
  182.  | nisses abgelegt. <bufsiz> bezeichnet den Platz in <buf> fuer Pfad ein-   |
  183.  | schliesslich Nullbyte. Der Pfad ist immer mit einem Nullbyte abgeschlos- |
  184.  | sen. Wenn <buf> nicht gross genug ist, wird ein Fehler gemeldet und NULL |
  185.  | als Funktionswert zurueckgeliefert, <buf>^ ist dann undefiniert; sonst   |
  186.  | ist der Funktionswert gleich <buf>.                                      |
  187.  |                                                                          |
  188.  | GEMDOS: Auch wenn <bufsiz> kleiner als 'PATHMAX' ist, wird intern min-   |
  189.  |         destens ein Puffer dieser Groesse bereitgestellt, damit ein zu   |
  190.  |         kleiner Wert sauber mit einer Fehlermeldung statt mit einem      |
  191.  |         Absturz wegen Ueberschreiben fremden Speichers abgefangen wird.  |
  192.  |   MiNT: Keine Besonderheiten                                             |
  193.   --------------------------------------------------------------------------*)
  194.  
  195.  
  196.  PROCEDURE getlogin ( ): StrPtr;
  197.  
  198. (*--------------------------------------------------------------------------
  199.  | Liefert einen Zeiger auf einen statischen Speicherbereich, in dem der    |
  200.  | login-Name steht, der mit dem aufrufenden Prozess assoziiert ist.        |
  201.  | Wenn der login-Name nicht festgestellt werden kann, wird NULL geliefert. |
  202.  |                                                                          |
  203.  | MiNT/GEMDOS: Der login-Name wird der Environmentvariablen 'LOGNAME'      |
  204.  |              entnommen. Existiert diese Variable nicht oder ist sie leer,|
  205.  |              und die reale Benutzerkennung ist nicht groesser Null,      |
  206.  |              lautet der name 'root'; sonst wird NULL zurueckgeliefert.   |
  207.   --------------------------------------------------------------------------*)
  208.  
  209.  
  210.  PROCEDURE getpid ( ): pidT;
  211.  
  212.  PROCEDURE getppid ( ): pidT;
  213.  
  214. (*--------------------------------------------------------------------------
  215.  | Liefert die Kennung des eigenen bzw. des uebergeordneten Prozesses.      |
  216.  |                                                                          |
  217.  | GEMDOS: Aus der Adresse der BasePage wird ein eindeutiger Wert berechnet.|
  218.  |   MiNT: Keine Besonderheiten.                                            |
  219.   --------------------------------------------------------------------------*)
  220.  
  221.  
  222.  PROCEDURE getuid ( ): uidT;
  223.  
  224.  PROCEDURE getgid ( ): gidT;
  225.  
  226.  PROCEDURE geteuid ( ): uidT;
  227.  
  228.  PROCEDURE getegid ( ): gidT;
  229.  
  230.  PROCEDURE setuid ((* EIN/ -- *) uid : uidT ): int;
  231.  
  232.  PROCEDURE setgid ((* EIN/ -- *) gid : gidT ): int;
  233.  
  234. (* Noch nicht POSIX: *)
  235.  PROCEDURE seteuid ((* EIN/ -- *) uid : uidT ): int;
  236.  
  237. (* Noch nicht POSIX: *)
  238.  PROCEDURE setegid ((* EIN/ -- *) gid : gidT ): int;
  239.  
  240. (* Nicht POSIX: *)
  241.  PROCEDURE setreuid ((* EIN/ -- *) ruid : uidT;
  242.                      (* EIN/ -- *) euid : uidT ): int;
  243.  
  244. (* Nicht POSIX: *)
  245.  PROCEDURE setregid ((* EIN/ -- *) rgid : gidT;
  246.                      (* EIN/ -- *) egid : gidT ): int;
  247.  
  248. (*--------------------------------------------------------------------------
  249.  | Funktionen fuer das Abfragen und Setzen diverser Kennungen:              |
  250.  | "getuid/gid"  : liefern reale Benutzer- bzw. Gruppenkennung des aufrufen-|
  251.  |                 den Prozesses.                                           |
  252.  | "geteuid/gid" : liefern effektive Benutzer- bzw. Gruppenkennung des auf- |
  253.  |                 rufenden Prozesses.                                      |
  254.  | "setuid/gid"  : setzen reale und effektive Benutzer- bzw. Gruppenkennung |
  255.  |                 des aufrufenden Prozesses auf <uid> bzw. <gid>.          |
  256.  |                 Nur erlaubt, wenn der aufrufende Prozess die entsprechen-|
  257.  |                 den rechte besitzt (-> 'root'), oder 'uid'/'gid' der     |
  258.  |                 Kennung entspricht.                                      |
  259.  | "seteuid/gid" : wie "setuid/gid", es wird aber nur die effektive Kennung |
  260.  |                 gesetzt.                                                 |
  261.  | "setreuid/gid": setzen reale und effektive Kennungen getrennt.           |
  262.  |                                                                          |
  263.  | Die realen Kennungen identifizieren den Benutzer bzw. die Gruppe.        |
  264.  |                                                                          |
  265.  | Der Zugriff auf Systemressourcen (z.B. Dateien) wird ueber die effektiven|
  266.  | Kennungen geregelt, die normalerweise gleich den realen Kennungen sind,  |
  267.  | es sei denn, es wird ein Programm ausgefuehrt, das die ``set user id''   |
  268.  | oder ``set group id'' Bits im Modusfeld gesetzt hat, wodurch der ausfueh-|
  269.  | rende Prozess als effektive Kennung die Kennung des Dateibesitzers und   |
  270.  | damit auch seine Zugriffsberechtigung bekommt. Die realen Kennungen      |
  271.  | werden hiedurch aber nicht beeinflusst.                                  |
  272.  |                                                                          |
  273.  | GEMDOS: Die Kennung ist immer gleich Null (``Superuser'').               |
  274.  |   MiNT: "seteuid/gid" ist gleich "setuid/gid", "setreuid/gid(r,e)" ist   |
  275.  |         gleich "setuid/gid(e)".                                          |
  276.   --------------------------------------------------------------------------*)
  277.  
  278.  
  279.  PROCEDURE getpgrp ( ): pidT;
  280.  
  281.  PROCEDURE setpgid ((* EIN/ -- *) pid  : pidT;
  282.                     (* EIN/ -- *) pgid : pidT ): int;
  283.  
  284.  PROCEDURE setsid ( ): pidT;
  285.  
  286. (*--------------------------------------------------------------------------
  287.  | "getpgrp()": ermittelt die Prozessgruppe des aufrufenden Prozesses.      |
  288.  | "setpgid()": Setzt die Prozessgruppe des Prozesses <pid> auf den Wert    |
  289.  |              <pgid>. Wenn <pid> oder <pgid> Null sind, wird stattdessen  |
  290.  |              die Prozesskennung des aufrufenden Prozesses eingesetzt.    |
  291.  | "setsid()" : Der aufrufende Prozess verliert sein Kontrollterminal (von  |
  292.  |              dem aus bestimmte Tasten Signale ausloesen koennen - fuer   |
  293.  |              ``job control''), und wird zum einzigen Mitglied einer      |
  294.  |              neuen Prozessgruppe, die das einzige Mitglied einer neuen   |
  295.  |              ``Session'' ist. Die Prozessgruppe ist die Prozesskennung   |
  296.  |              des aufrufenden Prozesses. Wenn der Prozess bereits eine    |
  297.  |              Prozessgruppe anfuehrt (Kennung der Prozesses ist auch Ken- |
  298.  |              nung der Prozessgruppe), darf die Funktion nicht ausgefuehrt|
  299.  |              werden.                                                     |
  300.  |                                                                          |
  301.  | GEMDOS: "getpgrp()" liefert den gleichen Wert wie "getpid()". Fuer <pid> |
  302.  |         und <pgid> bei "setpgid()" sind nur Null und der Wert von        |
  303.  |         "getpid()" erlaubt. "setsid()" liefert immer -1 (errno = 'EPERM')|
  304.  |   MiNT: "getpgrp()" und "setpgid()": Keine Besonderheiten.               |
  305.  |         "setsid()": Der Unterschied zwischen einer ``Session'' und einer |
  306.  |         Prozessgruppe ist mir nicht klar. Ueberhaupt ist mir unklar, in- |
  307.  |         wieweit "MiNT-psetpgrp()" den POSIX-Funktionen "setpgid()" und   |
  308.  |         "setsid()" entspricht, deshalb kann es sein, dass die Funktions- |
  309.  |         weise nicht ganz korrekt ist.                                    |
  310.   --------------------------------------------------------------------------*)
  311.  
  312.  
  313.  PROCEDURE fork ( ): pidT;
  314.  
  315. (*--------------------------------------------------------------------------
  316.  | Der aktuelle Prozess wird in zwei gleichartige Prozesse aufgeteilt, aber |
  317.  | mit getrenntem Speicherbereich und unterschiedlichen Prozesskennungen.   |
  318.  | Konnte der neue Prozess nicht erzeugt werden, wird dem aufrufenden Pro-  |
  319.  | zess ein Fehler gemeldet; sonst liefert die Funktion dem aufrufenden     |
  320.  | (= Parent) die (positive) Prozesskennung des neuen Prozesses (= Child)   |
  321.  | und dem neuen Prozess eine Null.                                         |
  322.  |                                                                          |
  323.  | GEMDOS: Liefert immer -1 (errno = 'ENOSYS').                             |
  324.  |   MiNT: Keine Besonderheiten.                                            |
  325.   --------------------------------------------------------------------------*)
  326.  
  327.  
  328. (* Nicht POSIX: *)
  329.  PROCEDURE vfork ( ): pidT;
  330.  
  331. (*--------------------------------------------------------------------------
  332.  | Funktion wie "fork()", die Prozesse benutzen aber denselben Speicher-    |
  333.  | bereich, insbesondere benutzen sie auch denselben Stack.                 |
  334.  |                                                                          |
  335.  | Bei der Anwendung der Funktion ist etwas Vorsicht geboten:               |
  336.  | Zwischen dem "vfork()" und dem Pterm oder "execv*()" des Kindprozesses   |
  337.  | darf der Stackpointer nicht hochgesetzt werden, etwa durch einen Aufruf  |
  338.  | von "vfork()" innerhalb einer WITH- oder FOR-Anweisung oder innerhalb    |
  339.  | einer Prozedur, und dem Aufruf von "execv*()" ausserhalb, denn sonst     |
  340.  | ueberschreibt der Kindprozess fuer den Elternprozess wichtige Informa-   |
  341.  | tionen, wenn er etwas auf dem Stack ablegt; und das geschieht spaetestens|
  342.  | beim Terminieren des Kindprozesses oder dem Ueberlagern mit einem neuen  |
  343.  | Programm durch "execv*()", denn die Parameter werden auf dem Stack abge- |
  344.  | legt. Das Ergebnis ist mit Sicherheit ein Absturz, vor allem, wenn       |
  345.  | "vfork()" innerhalb einer Prozedur aufgerufen wird -- dann fehlt naemlich|
  346.  | die Return-Adresse fuer den Elternprozess.                               |
  347.  |                                                                          |
  348.  | GEMDOS/MiNT: Die Gruende fuer die Schwierigkeiten sind allerdings bei    |
  349.  | GEMDOS und MiNT unterschiedlich:                                         |
  350.  | Unter MiNT wird fuer Eltern- und Kindprozess tatsaechlich derselbe Stack |
  351.  | benutzt, mit den eben erwaehnten Folgen. Unter GEMDOS wird "vfork()"     |
  352.  | durch "tfork()" emuliert, wodurch der Kindprozess einen anderen Stack    |
  353.  | erhaelt, und folglich keine vorher auf dem Stack abgelegte Werte mehr    |
  354.  | gueltig sind.                                                            |
  355.  |                                                                          |
  356.  | Mit Megamax-Modula funktioniert die Prozedur nur unter MiNT.             |
  357.   --------------------------------------------------------------------------*)
  358.  
  359.  
  360. (* Nicht POSIX: *)
  361.  PROCEDURE SetStacksize ((* EIN/ -- *) stacksize : CARDINAL );
  362.  
  363. (* Nicht POSIX: *)
  364.  PROCEDURE tfork ((* EIN/ -- *) func : ThreadProc;
  365.                   (* EIN/ -- *) arg  : ANYLONG    ): int;
  366.  
  367. (*--------------------------------------------------------------------------
  368.  | "tfork()" generiert aus einer Funktion vom Typ 'ThreadProc' einen neuen  |
  369.  | Prozess mit eigener Prozesskennung und eigenem Stack, der sonstige       |
  370.  | Adressraum ist aber derselbe wie beim aufrufenden Prozess, d.h. auf      |
  371.  | globale Variablen wird gemeinsam zugegriffen. Deshalb ist auch Vorsicht  |
  372.  | bei der Benutzung von Bibliotheksfunktionen innerhalb des neuen Prozesses|
  373.  | (``Thread'') geboten; insbesondere sollte die Speicherverwaltung nicht   |
  374.  | verwendet werden ("NEW()", "DISPOSE()" ...). Ansonsten muss ausprobiert  |
  375.  | werden, was funktioniert.                                                |
  376.  | Mit "SetStacksize()" laesst sich die Stackgroesse des neuen Prozesses    |
  377.  | festlegen; sie kann aber nicht kleiner als 'MINSTACKSIZE' werden.        |
  378.   --------------------------------------------------------------------------*)
  379.  
  380.  
  381.  PROCEDURE execve ((* EIN/ -- *) REF prg  : ARRAY OF CHAR;
  382.                    (* EIN/ -- *)     argv : StrArray;
  383.                    (* EIN/ -- *)     envp : StrArray      ): int;
  384.  
  385.  PROCEDURE execv ((* EIN/ -- *) REF prg  : ARRAY OF CHAR;
  386.                   (* EIN/ -- *)     argv : StrArray      ): int;
  387.  
  388.  PROCEDURE execvp ((* EIN/ -- *) REF prg  : ARRAY OF CHAR;
  389.                    (* EIN/ -- *)     argv : StrArray      ): int;
  390.  
  391. (*--------------------------------------------------------------------------
  392.  | Ersetzt den aufrufenden Prozess durch einen neuen, der aus dem Programm  |
  393.  | gebildet wird, dessen Dateiname <prg> ist. <args> und <env> sind Felder  |
  394.  | aus Zeigern auf Parameter und Environment-Variablen, sodass der neue     |
  395.  | Prozess diese als Elemente der Kommandozeile bzw. als Environment-Variab-|
  396.  | len holen kann.                                                          |
  397.  | Ist <envp> = NULL, wird das augenblickliche Environment vererbt.         |
  398.  | Falls ein Fehler auftritt, wird ein negativer Wert zurueckgeliefert,     |
  399.  | andernfalls kehrt die Funktion NICHT zum Aufrufer zurueck, da dieser     |
  400.  | durch das neue Programm ersetzt wurde.                                   |
  401.  | Mit der Kombination "fork()" & "execve()" koennen somit neue Prozesse    |
  402.  | gestartet werden.                                                        |
  403.  |                                                                          |
  404.  | Spezielle Versionen von "execve()":                                      |
  405.  |                                                                          |
  406.  | "execv()" : es wird das augenblickliche Environment vererbt.             |
  407.  | "execvp()": das augenblickliche Environment wird vererbt, und <prg> wird |
  408.  |             in allen in PATH angegebenen Verzeichnissen gesucht.         |
  409.  |                                                                          |
  410.  | GEMDOS: Funktioniert, ist aber ohne "fork()" nicht sinnvoll.             |
  411.  |   MiNT: Keine Besonderheiten.                                            |
  412.  | Die Kommandozeilenparameter werden dem neuen Programm ueber die normale  |
  413.  | Kommandozeile in der BasePage und das ARGV-Verfahren (einschlisslich     |
  414.  | Erweiterung fuer leere Argumente) mitgeteilt.                            |
  415.  | Falls <prg> bei "execvp()" keine Extension hat, werden die in der        |
  416.  | Environmentvariablen 'TOSEXT' angegebenen Extensionen ausprobiert, und   |
  417.  | zum Schluss immer die Datei OHNE Extension. Falls 'TOSEXT' nicht         |
  418.  | existiert, werden die Extensionen aus 'DosSupport.TOSEXT' probiert.      |
  419.   --------------------------------------------------------------------------*)
  420.  
  421.  
  422.  
  423.  
  424.  PROCEDURE waitpid ((* EIN/ -- *)     pid     : pidT;
  425.                     (* -- /AUS *) VAR state   : WaitVal;
  426.                     (* EIN/ -- *)     options : WaitOption ): pidT;
  427.  
  428. (*--------------------------------------------------------------------------
  429.  | Wartet auf die Beendigung oder das Stoppen eines vom aufrufenden Prozess |
  430.  | gestarteten Unterprozesses. Als Funktionswert wird die 'pid' des ent-    |
  431.  | sprechenden Prozesses oder -1 bei einem Fehler (z.B. wenn keine Prozesse |
  432.  | gestartet wurden) zurueckgeliefert. In <state> steht kodiert die Ursache |
  433.  | der Beendigung oder des Stoppens (siehe Definition von 'WaitVal').       |
  434.  | Mit <options> wird das Verhalten der Prozedur festgelegt (siehe Def. von |
  435.  | 'WaitOptions').                                                          |
  436.  | Mit <pid> wird festgelegt, welche Unterprozesse beruecksichtigt werden   |
  437.  | sollen:                                                                  |
  438.  |                                                                          |
  439.  |   <pid> = -1: alle Unterprozesse                                         |
  440.  |   <pid> >  0: nur Unterprozess mit dieser Prozesskennung                 |
  441.  |   <pid> =  0: alle Unterprozesse mit der gleichen Prozessgruppenkennung  |
  442.  |               wie der aufrufende Prozess                                 |
  443.  |   <pid> < -1: alle Unterprozesse, die |<pid>| als Prozessgruppenkennung  |
  444.  |               haben                                                      |
  445.  |                                                                          |
  446.  | GEMDOS: Wenn <pid> = 0 oder -1, wird die Prozesskennung des letzten mit  |
  447.  |         "tfork()" gestarteten Unterprozesses geliefert, sonst wird immer |
  448.  |         -1 geliefert (errno = 'ECHILD').                                 |
  449.  |   MiNT: Keine Besonderheiten.                                            |
  450.   --------------------------------------------------------------------------*)
  451.  
  452.  PROCEDURE wait ((* -- /AUS *) VAR state : WaitVal ): pidT;
  453.  
  454. (*--------------------------------------------------------------------------
  455.  | Aequivalent zu "waitpid(-1, state, WaitOption{})", es werden also keine  |
  456.  | gestoppten Unterprozesse beruecksichtigt.                                |
  457.  |                                                                          |
  458.  | GEMDOS: siehe "waitpid()".                                               |
  459.  |   MiNT: Keine Besonderheiten.                                            |
  460.   --------------------------------------------------------------------------*)
  461.  
  462. (* Nicht POSIX: *)
  463.  PROCEDURE wait3 ((* -- /AUS *) VAR state   : WaitVal;
  464.                   (* EIN/ -- *)     options : WaitOption;
  465.                   (* -- /AUS *) VAR usage   : RusageRec   ): pidT;
  466.  
  467. (*--------------------------------------------------------------------------
  468.  | Variante von "waitpid()": <state> und <options> sind entsprechend, es    |
  469.  | werden alle Unterprozesse beruecksichtigt, und in <usage> werden Infor-  |
  470.  | mationen ueber die vom beendeten Unterprozess benoetigten Resourcen      |
  471.  | abgelegt.                                                                |
  472.  |                                                                          |
  473.  | GEMDOS/MiNT: In <usage> enthalten nur die ersten beiden Felder einen     |
  474.  |              sinnvollen Wert, sonst siehe "waitpid()".                   |
  475.   --------------------------------------------------------------------------*)
  476.  
  477. (* Nicht POSIX: *)
  478.  PROCEDURE wait4 ((* EIN/ -- *)     pid     : pidT;
  479.                   (* -- /AUS *) VAR state   : WaitVal;
  480.                   (* EIN/ -- *)     options : WaitOption;
  481.                   (* -- /AUS *) VAR usage   : RusageRec   ): pidT;
  482.  
  483. (*--------------------------------------------------------------------------
  484.  | Falls <pid> gleich Null, entspricht die Funktion "wait3()". Falls <pid>  |
  485.  | groesser als Null ist, wird nur der Unterprozess mit dieser Kennung      |
  486.  | beruecksichtigt.                                                         |
  487.   --------------------------------------------------------------------------*)
  488.  
  489.  
  490.  
  491.  PROCEDURE WIFEXITED   ((* EIN/ -- *) state : WaitVal ): BOOLEAN;
  492.  PROCEDURE WEXITSTATUS ((* EIN/ -- *) state : WaitVal ): int;
  493.  
  494.  PROCEDURE WIFSIGNALED ((* EIN/ -- *) state : WaitVal ): BOOLEAN;
  495.  PROCEDURE WTERMSIG    ((* EIN/ -- *) state : WaitVal ): int;
  496.  
  497.  PROCEDURE WIFSTOPPED ((* EIN/ -- *) state : WaitVal ): BOOLEAN;
  498.  PROCEDURE WSTOPSIG   ((* EIN/ -- *) state : WaitVal ): int;
  499.  
  500. (*--------------------------------------------------------------------------
  501.  | Diese Funktionen sind bei POSIX als Makros definiert.                    |
  502.  |                                                                          |
  503.  | "WIFEXITED()"  : TRUE, genau dann, wenn der Unterprozess ``normal'' been-|
  504.  |                  det wurde, d.h. nicht durch ein Signal.                 |
  505.  | "WEXITSTATUS()": Falls "WIFEXITED()" = TRUE, wird der Returncode des     |
  506.  |                  Unterprozesses geliefert. Dabei werden aber nur die     |
  507.  |                  unteren 8 Bit des Returncodes benutzt und vorzeichen-   |
  508.  |                  richtig erweitert.                                      |
  509.  |                  Wenn "WIFEXITED()" = FALSE, ist der Funktionswert nicht |
  510.  |                  definiert !                                             |
  511.  | "WIFSIGNALED()": TRUE, genau dann, wenn der Unterprozess durch ein Signal|
  512.  |                  beendet wurde.                                          |
  513.  | "WTERMSIG()"   : Falls "WIFSIGNALED()" = TRUE, wird der Ordinalwert des  |
  514.  |                  beendenden Signals geliefert.                           |
  515.  |                  Wenn "WIFSIGNALED()" = FALSE,ist der Funktionswert nicht|
  516.  |                  definiert !                                             |
  517.  | "WIFSTOPPED()" : TRUE, genau dann, wenn der Unterprozess momentan ge-    |
  518.  |                  stoppt, aber nicht beendet ist (``Job Control'').       |
  519.  | "WSTOPSIG()"   : Falls "WIFSTOPPED()" = TRUE, wird der Ordinalwert des   |
  520.  |                  Signals, das den Prozess gestoppt hat, geliefert.       |
  521.  |                  Wenn "WIFSTOPPED()" = FALSE, ist der Funktionswert nicht|
  522.  |                  definiert !                                             |
  523.  |                                                                          |
  524.  | Es sollten ausschliesslich diese Funktionen benutzt werden, um einen     |
  525.  | Status vom Typ 'WaitVal' zu analysieren.                                 |
  526.  |                                                                          |
  527.  | GEMDOS: keine Besonderheiten.                                            |
  528.  |   MiNT: -""-                                                             |
  529.   --------------------------------------------------------------------------*)
  530.  
  531.  
  532. (* Nicht POSIX: *)
  533.  PROCEDURE FDZERO ((* -- /AUS *) VAR fdset : fdSet );
  534.  
  535.  PROCEDURE FDSET ((* EIN/ -- *)     fd    : int;
  536.                   (* -- /AUS *) VAR fdset : fdSet );
  537.  
  538.  PROCEDURE FDCLR ((* EIN/ -- *)     fd    : int;
  539.                   (* -- /AUS *) VAR fdset : fdSet );
  540.  
  541.  PROCEDURE FDISSET ((* EIN/ -- *) fd    : int;
  542.                     (* EIN/ -- *) fdset : fdSet ): BOOLEAN;
  543.  
  544. (*--------------------------------------------------------------------------
  545.  | Funktionen zur Manipulation von Variablen des Typs 'fdSet'.              |
  546.  | Es MUESSEN(!) ausschliesslich diese Funktionen benutzt werden, um        |
  547.  | Variablen vom Typ 'fdSet' zu manipulieren, da die Zuordnung von Elementen|
  548.  | zur unterliegenden Bitrepraesentation NICHT festgelegt ist!              |
  549.  | Die Funktionen sind unter *IX als Makros definiert.                      |
  550.  |                                                                          |
  551.  | "FDZERO"  : Loescht die Menge <fdSet>.                                   |
  552.  | "FDSET"   : Setzt die Dateikennung <fd> in <fdSet>.                      |
  553.  | "FDCLR"   : Loescht die Dateikennung <fd> in <fdSet>.                    |
  554.  | "FDISSET" : Testet, ob die Dateikennung <fd> in <fdSet> gesetzt ist.     |
  555.  |                                                                          |
  556.  | GEMDOS: Keine Besonderheiten.                                            |
  557.  |   MiNT: -""-                                                             |
  558.   --------------------------------------------------------------------------*)
  559.  
  560. (* Nicht POSIX: *)
  561.  PROCEDURE select ((* EIN/ -- *) width     : int;
  562.                    (* EIN/ -- *) readfds   : FdSetPtr;
  563.                    (* EIN/ -- *) writefds  : FdSetPtr;
  564.                    (* EIN/ -- *) exceptfds : FdSetPtr;
  565.                    (* EIN/ -- *) timeout   : TimevalPtr ): int;
  566.  
  567. (*--------------------------------------------------------------------------
  568.  | Mithilfe dieser Prozedur kann auf das Eintreten bestimmter Bedingungen   |
  569.  | bei geoeffneten Dateien unter Einhaltung eines Timeouts gewartet werden. |
  570.  |                                                                          |
  571.  | Die Dateien werden als Elemente von Mengen angegeben, wobei die          |
  572.  | Ordnungszahl jedes Elements einer Dateikennung entspricht, also z.B.     |
  573.  | Element 0 fuer die Standardeingabe. Es werden nur die Dateikennungen     |
  574.  | beachtet, deren Wert kleiner als <width> ist; Ist <width> groesser oder  |
  575.  | gleich FDSETSIZE, werden alle Kennungen beachtet. Falls kein Fehler      |
  576.  | auftritt, werden in den angegebenen Mengen ausschliesslich die Datei-    |
  577.  | kennungen gesetzt, bei denen die Bedingungen eingetreten sind, die       |
  578.  | anderen Elemente werden geloescht; die Ergebnismengen sind immer Teil-   |
  579.  | mengen der urspruenglichen Mengen. <readfds>^ repraesentiert die Menge   |
  580.  | der Dateien, bei denen auf das Bereitwerden zum Lesen gewartet werden    |
  581.  | soll, <writefds>^ repraesentiert die Dateien, bei denen auf das Bereit-  |
  582.  | werden zum Schreiben gewartet werden soll und <exceptfds>^ repraesentiert|
  583.  | die Dateien, bei denen auf das Eintreten einer Ausnahmebedingung gewartet|
  584.  | werden soll.                                                             |
  585.  |                                                                          |
  586.  | Die Funktion kehrt zurueck, sobald mindestens bei einer Datei die angege-|
  587.  | bene Bedingung eingetreten oder der Timeout abgelaufen ist. Als          |
  588.  | Funktionswert wird die Anzahl der bereiten Kennungen geliefert (also die |
  589.  | Anzahl der in allen Mengen zusammen enthaltenen Elemente) oder Null,     |
  590.  | falls der Timeout abgelaufen (dann sind auch alle Mengen leer) ist oder  |
  591.  | -1, falls ein Fehler aufgetreten ist (dann ist der Inhalt der Mengen     |
  592.  | undefiniert). Ist einer der Zeiger gleich NULL, wird er nicht beachtet.  |
  593.  | In <timeout> ist angegeben, wie lange maximal auf das Bereitwerden der   |
  594.  | angegebenen Dateien gewartet wird, bevor die Funktion von selbst         |
  595.  | zurueckkehrt. Ist <timeout> gleich NULL, wird ohne Timeout auf das       |
  596.  | Bereitwerden der angegebenen Dateien gewartet; ist <timeout>^ gleich     |
  597.  | Null, wird nur der augenblickliche Zustand der Dateien abgefragt, und die|
  598.  | Funktion kehrt sofort zurueck -- dies kann fuer ein ``Pollen'' benutzt   |
  599.  | werden.                                                                  |
  600.  |                                                                          |
  601.  | GEMDOS: Nicht implementiert                                              |
  602.  |   MiNT: <exceptfds>^ wird nicht ausgewertet und immer geloescht.         |
  603.   --------------------------------------------------------------------------*)
  604.  
  605.  
  606.  
  607.  PROCEDURE times ((* -- /AUS *) VAR buf : TmsRec ): clockT;
  608.  
  609. (*--------------------------------------------------------------------------
  610.  | Liefert Informationen ueber die vom Prozess und seine Unterprozesse ver- |
  611.  | brauchte Zeit (siehe Def. von 'TmsRec'); die Zeiten sind in der Einheit  |
  612.  | 'sys.ClkTck's / Sekunde angegeben.                                       |
  613.  | Als Funktionswert wird die vergangene Zeit seit einem beliebigen, aber   |
  614.  | festen Zeitpunkt in der Vergangenheit zurueckgeliefert; durch mehrmaligen|
  615.  | Aufruf der Funktion koennen so Zeitdifferenzen gemessen werden. Auch hier|
  616.  | ist die Einheit 'sys.ClkTck's / Sekunde.                                 |
  617.  |                                                                          |
  618.  | GEMDOS: Die im System verbrachte Zeit kann nicht festgestellt werden.    |
  619.  |   MiNT: Keine Besonderheiten.                                            |
  620.   --------------------------------------------------------------------------*)
  621.  
  622. (* Nicht POSIX: *)
  623.  PROCEDURE clock ( ): clockT;
  624.  
  625. (*--------------------------------------------------------------------------
  626.  | Liefert die (Prozessor)Zeit, die der aufrufende Prozess bisher verbraucht|
  627.  | hat, in der Einheit 'sys.ClkTck's / Sekunde.                             |
  628.  |                                                                          |
  629.  | GEMDOS/MiNT: Die Summe von 'TmsRec.tmsUtime' und 'TmsRec.tmsStime' eines |
  630.  |              "times()"-Aufrufs wird zurueckgeliefert.                    |
  631.   --------------------------------------------------------------------------*)
  632.  
  633.  
  634.  
  635.  PROCEDURE Exit ((* EIN/ -- *) retval : int );
  636.  
  637. (*--------------------------------------------------------------------------
  638.  | Der aufrufende Prozess wird mit dem Returncode <retval> beendet.         |
  639.  | <retVal> sollte im Bereich [-128..127] liegen, da im Typ 'WaitVal' nur   |
  640.  | 8 Bit des Returncodes untergebracht werden koennen.                      |
  641.  | Die Prozedur muesste eigentlich "_exit()" heissen!                       |
  642.  |                                                                          |
  643.  | GEMDOS: keine Besonderheiten.                                            |
  644.  |   MiNT: -""-                                                             |
  645.   --------------------------------------------------------------------------*)
  646.  
  647.  
  648.  
  649.  
  650. (*===========================================================================*)
  651. (* Die folgenden Funktionen haben NICHTS mit POSIX oder *IX zu tun, sind     *)
  652. (* jedoch fuer "PCDOS" und "GEMDOS" notwendig, um ein *IX-like               *)
  653. (* Programmstarten zu ermoeglichen. Fuer *IX sind die Funktionen immerhin    *)
  654. (* bequem.                                                                   *)
  655. (*===========================================================================*)
  656.  
  657. TYPE
  658.   SpawnMode = (
  659.     pOVERLAY, (* Aufrufer wird durch neuen Prozess ersetzt (= exec)*)
  660.     pNOWAIT,  (* neuer Prozess laeuft parallel zum erzeugenden Prozess *)
  661.     pWAIT     (* Erzeugender Prozess wird unterbrochen *)
  662.   );
  663.  
  664. (*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
  665.  
  666.  PROCEDURE spawnve ((* EIN/ -- *)     mode : SpawnMode;
  667.                     (* EIN/ -- *) REF prg  : ARRAY OF CHAR;
  668.                     (* EIN/ -- *)     argv : StrArray;
  669.                     (* EIN/ -- *)     envp : StrArray      ): int;
  670.  
  671. (*--------------------------------------------------------------------------
  672.  | Diese Prozedur fasst die Prozeduren "fork()", "execve()" und "waitpid()" |
  673.  | auf unterschiedliche Weise zusammen.                                     |
  674.  |                                                                          |
  675.  | <mode> = pOVERLAY: "spawnve()" entspricht "execve()"                     |
  676.  | <mode> = pNOWAIT : es wird ein "fork()" ausgefuehrt, und dann <prg> mit  |
  677.  |                    "execve()" gestartet.                                 |
  678.  |                    Rueckgabewert ist entweder -1 und 'errno' wird gesetzt|
  679.  |                    falls beim Aufruf von "spawnve()" etwas schiefgeht,   |
  680.  |                    oder die positive 'pid' des erzeugten Prozesses.      |
  681.  | <mode> = pWAIT   : wie pNOWAIT, aber es wird mit "waitpid()" auf das Ende|
  682.  |                    des erzeugten Prozesses gewartet. Falls beim Aufruf   |
  683.  |                    von "spawnve()" etwas schiefgeht, ist der Rueckgabe-  |
  684.  |                    wert gleich -1 und 'errno' wird gesetzt, ansonsten    |
  685.  |                    wird 'errno' auf Null gesetzt(!), und die unteren 16  |
  686.  |                    Bit des Funktionswertes sind vom Typ 'WaitVal'. Da im |
  687.  |                    oberen Byte von 'WaitVal' der Returncode des aufgeru- |
  688.  |                    fenen Prozesses enthalten ist (falls der Prozess nicht|
  689.  |                    durch ein Signal gestoppt oder terminiert wurde) und  |
  690.  |                    dieser auch negativ sein kann, und 'WaitVal' fuer den |
  691.  |                    Funktionswert auch vorzeichenrichtig auf int-Groesse  |
  692.  |                    erweitert wird, muss ein Fehler von "spawnve()"       |
  693.  |                    durch Inspizieren von 'errno' ermittelt werden:       |
  694.  |                                                                          |
  695.  |                      ret := spawnve(pWAIT,...);                          |
  696.  |                      IF errno <> 0 THEN                                  |
  697.  |                        (* "spawnve()"-Fehler *)                          |
  698.  |                      ...                                                 |
  699.  |                                                                          |
  700.  | GEMDOS/MiNT:                                                             |
  701.  |           Diese Prozedur laeuft fuer <mode> = 'pWAIT' oder 'pOVERLAY'    |
  702.  |           auch ohne MiNT.                                                |
  703.  |           ACHTUNG: Es wird wirklich nur das Programm ueber 'Pexec' ge-   |
  704.  |           startet, es wird weder der Bildschirm geloescht, die Maus aus- |
  705.  |           geschaltet, noch der Critical-Error-Handler umgesetzt! Ehe man |
  706.  |           jetzt aber selbst daran geht dies zu tun, sollte man daran den-|
  707.  |           ken, dass es zum Chaos fuehrt, falls Prozesse parallel laufen  |
  708.  |           (unter MiNT), da es nur einen Bildschirm, eine Maus und einen  |
  709.  |           Error-Handler (vor MiNT 0.95) gibt! Das Problem laesst sich nur|
  710.  |           loesen, wenn TOS-Programme ihre Ausgaben in GEM-Fenster schrei-|
  711.  |           ben, wie dies unter MultiTOS der Fall sein wird.               |
  712.  |           Wenn ein (Unter)Prozess keine Bidschirmausgaben macht, ist dies|
  713.  |           natuerlich kein Problem.                                       |
  714.  |           Ohne MiNT wird Pexec mit Modus 0 (pWAIT) gestartet, sonst      |
  715.  |           sind auch Modus 100 (pNOWAIT) und 200 (pOVERLAY) moeglich.     |
  716.  |           ("MiNT"-Unterstuetzung.)                                       |
  717.   --------------------------------------------------------------------------*)
  718.  
  719.  
  720.  
  721.  PROCEDURE spawnv ((* EIN/ -- *)     mode : SpawnMode;
  722.                    (* EIN/ -- *) REF prg  : ARRAY OF CHAR;
  723.                    (* EIN/ -- *)     argv : StrArray      ): int;
  724.  
  725.  PROCEDURE spawnvp ((* EIN/ -- *)     mode : SpawnMode;
  726.                     (* EIN/ -- *) REF prg  : ARRAY OF CHAR;
  727.                     (* EIN/ -- *)     argv : StrArray      ): int;
  728.  
  729. (*--------------------------------------------------------------------------
  730.  | Spezielle Versionen von "spawnve()":                                     |
  731.  |                                                                          |
  732.  | "spawnv()"  : es wird das augenblickliche Environment vererbt.           |
  733.  | "spawnvp()" : das augenblickliche Environment wird vererbt, und <prg>    |
  734.  |               wird in allen in PATH angegebenen Verzeichnissen gesucht.  |
  735.   --------------------------------------------------------------------------*)
  736.  
  737. END proc.
  738.