home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / program / m2posx02 / proc.dpp < prev    next >
Encoding:
Modula Definition  |  1993-10-23  |  22.7 KB  |  419 lines

  1. DEFINITION MODULE proc;
  2.  
  3. (*****************************************************************************)
  4. (* Funktionen, die mit Prozessen zu tun haben.                               *)
  5. (*                                                                           *)
  6. (* Ein Fehler ist immer dann aufgetreten, wenn bei Funktionen mit Typ INTEGER*)
  7. (* ein negativer Wert zurueckgegeben wird.                                   *)
  8. (* Die genaue Fehlerursache kann bei Bedarf ueber "err.errno" und die ent-   *)
  9. (* sprechenden Konstanten ermittelt werden. Die Funktionen veraendern "errno"*)
  10. (* nur dann, wenn ein Fehler aufgetreten ist, bei erfolgreicher Ausfuehrung  *)
  11. (* wird "errno" nicht veraendert.                                            *)
  12. (*                                                                           *)
  13. (* "GEMDOS":                                                                 *)
  14. (* Die Eigenschaften der Funktionen unter dem ``blanken'' "GEMDOS" sind z.T. *)
  15. (* stark eingeschraenkt; unter dem Stichwort "GEMDOS" ist deswegen immer     *)
  16. (* angegeben, in wieweit die Funktion emuliert werden kann. Ist MiNT-Unter-  *)
  17. (* stuetzung angegeben, so ist unter der Betriebssystemerweiterung "MiNT"    *)
  18. (* eine bessere Unterstuetzung der Funktionen zu erwarten.                   *)
  19. (*                                                                           *)
  20. (* Intern sind alle Pfadangaben auf die Laenge von 'PathName' begrenzt. Ist  *)
  21. (* ein Pfad laenger (evtl. nach der Umwandlung vom "*IX"-Stil in den "DOS"-  *)
  22. (* Stil), wird ein Fehler gemeldet, und 'errno' auf 'ENAMETOOLONG' gesetzt.  *)
  23. (* --------------------------------------------------------------------------*)
  24. (* 14-Feb-93, Holger Kleinschmidt                                            *)
  25. (*****************************************************************************)
  26.  
  27. FROM types IMPORT
  28. (* TYPE *) UNSIGNEDLONG, WORDSET, uidT, gidT, pidT, clockT;
  29.  
  30. FROM pSTRING IMPORT
  31. (* TYPE *) StrArray;
  32.  
  33. (*=========================== "times()" =====================================*)
  34.  
  35. TYPE
  36.   TmsRec = RECORD
  37.     tmsUtime  : clockT; (* CPU-Zeit im Benutzercode *)
  38.     tmsStime  : clockT; (* CPU-Zeit im System *)
  39.     tmsCUtime : clockT; (* CPU-Zeit im Benutzercode aller beendeten Unterpr.*)
  40.     tmsCStime : clockT; (* CPU-Zeit im System aller beendeten Unterprozesse *)
  41.   END;
  42.  
  43. (*======================= "wait()", "waitpid()" =============================*)
  44.  
  45. TYPE
  46.   WaitVal = WORDSET;
  47.  
  48. (* Repraesentation des Typs 'WaitVal' ist nicht zur Benutzung
  49.  * ausserhalb des Moduls gedacht.
  50.  * Konstanten sind nicht POSIX.
  51.  *)
  52. CONST
  53. #if reverse_set
  54.   wRetcode  = WaitVal{0..7};
  55.   wTermsig  = WaitVal{9..15};
  56.   wCoredump = 8;
  57.   wStopval  = WaitVal{8..15};
  58.   wStopsig  = WaitVal{0..7};
  59.  
  60.   WSTOPPED  = WaitVal{9..15};
  61. #else
  62.   wRetcode  = WaitVal{8..15};
  63.   wTermsig  = WaitVal{0..6};
  64.   wCoredump = 7;
  65.   wStopval  = WaitVal{0..7};
  66.   wStopsig  = WaitVal{8..15};
  67.  
  68.   WSTOPPED  = WaitVal{0..6};
  69. #endif
  70.  
  71.  (*  IF state * wStopval = WSTOPPED THEN
  72.   *    stoppedBy := VAL(CARDINAL,CAST(UNSIGNEDWORD,state * wStopsig) DIV 256);
  73.   *    ...
  74.   *  ELSIF state * wTermsig <> WaitVal{} THEN
  75.   *    terminatedBy := VAL(CARDINAL,CAST(UNSIGNEDWORD,state * wTermsig));
  76.   *    coreDumped   := wCoredump IN state;
  77.   *    ...
  78.   *  ELSE
  79.   *    retCode := VAL(INTEGER,CAST(SIGNEDWORD,state * wRetcode) DIV 256);
  80.   *    ...
  81.   *  END;
  82.   *)
  83.  
  84. TYPE
  85. #if reverse_set
  86.   WaitOptions = (
  87.     wait15, wait14, wait13, wait12, wait11, wait10, wait9,
  88.     wait8,  wait7,  wait6,  wait5,  wait4,  wait3,  wait2,
  89.     WUNTRACED, (* 0002H, auch gestoppte Unterprozesse beruecksichtigen *)
  90.     WNOHANG    (* 0001H, nicht auf Beendigung warten, sofort zurueck *)
  91.   );
  92. #else
  93.   WaitOptions = (
  94.     WNOHANG,   (* 0001H, nicht auf Beendigung warten, sofort zurueck *)
  95.     WUNTRACED, (* 0002H, auch gestoppte Unterprozesse beruecksichtigen *)
  96.     wait2, wait3,  wait4,  wait5,  wait6,  wait7,  wait8,
  97.     wait9, wait10, wait11, wait12, wait13, wait14, wait15
  98.   );
  99. #endif
  100.  
  101.   WaitOption = PACKEDSET OF WaitOptions;
  102.  
  103.  
  104. (*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
  105.  
  106.  PROCEDURE getpid ( ): pidT;
  107.  
  108.  PROCEDURE getppid ( ): pidT;
  109.  
  110. (*--------------------------------------------------------------------------
  111.  | Liefert die Kennung des eigenen bzw. des uebergeordneten Prozesses.      |
  112.  |                                                                          |
  113.  | "GEMDOS": Ohne MiNT wird aus der Adresse der BasePage ein eindeutiger    |
  114.  |           Wert berechnet.                                                |
  115.  |           ("MiNT"-Unterstuetzung.)                                       |
  116.   --------------------------------------------------------------------------*)
  117.  
  118.  
  119.  PROCEDURE getuid ( ): uidT;
  120.  
  121.  PROCEDURE getgid ( ): gidT;
  122.  
  123.  PROCEDURE geteuid ( ): uidT;
  124.  
  125.  PROCEDURE getegid ( ): gidT;
  126.  
  127.  PROCEDURE setuid ((* EIN/ -- *) uid : uidT ): INTEGER;
  128.  
  129.  PROCEDURE setgid ((* EIN/ -- *) gid : gidT ): INTEGER;
  130.  
  131. (*--------------------------------------------------------------------------
  132.  | Funktionen fuer das Abfragen und Setzen diverser Kennungen:              |
  133.  | "getuid/gid"  : liefern reale Benutzer- bzw. Gruppenkennung des aufrufen-|
  134.  |                 den Prozesses.                                           |
  135.  | "geteuid/gid" : liefern effektive Benutzer- bzw. Gruppenkennung des auf- |
  136.  |                 rufenden Prozesses.                                      |
  137.  | "setuid/gid"  : setzen reale und effektive Benutzer- bzw. Gruppenkennung |
  138.  |                 des aufrufenden Prozesses auf <uid> bzw. <gid>.          |
  139.  |                                                                          |
  140.  | Die realen Kennungen identifizieren den Benutzer bzw. die Gruppe.        |
  141.  |                                                                          |
  142.  | Der Zugriff auf Systemressourcen (z.B. Dateien) wird ueber die effektiven|
  143.  | Kennungen geregelt, die normalerweise gleich den realen Kennungen sind,  |
  144.  | es sei denn, es wird ein Programm ausgefuehrt, das die ``set user id''   |
  145.  | oder ``set group id'' Bits im Modusfeld gesetzt hat, wodurch der ausfueh-|
  146.  | rende Prozess als effektive Kennung die Kennung des Dateibesitzers und   |
  147.  | damit auch seine Zugriffsberechtigung bekommt. Die realen Kennungen      |
  148.  | werden hiedurch aber nicht beeinflusst.                                  |
  149.  |                                                                          |
  150.  | "GEMDOS": Ohne MiNT ziemlich sinnlos, aber wohl auch mit.                |
  151.  |           ("MiNT"-Unterstuetzung.)                                       |
  152.   --------------------------------------------------------------------------*)
  153.  
  154.  
  155.  PROCEDURE getpgrp ( ): pidT;
  156.  
  157.  PROCEDURE setpgid ((* EIN/ -- *) pid  : pidT;
  158.                     (* EIN/ -- *) pgid : pidT ): INTEGER;
  159.  
  160. (*--------------------------------------------------------------------------
  161.  | "getpgrp()": ermittelt die Prozessgruppe des aufrufenden Prozesses.      |
  162.  | "setpgid()": Setzt die Prozessgruppe des Prozesses <pid> auf den Wert    |
  163.  |              <pgid>. Wenn <pid> oder <pgid> Null sind, wird stattdessen  |
  164.  |              die Prozesskennung des aufrufenden Prozesses eingesetzt.    |
  165.  |                                                                          |
  166.  | "GEMDOS": Ohne MiNT ziemlich sinnlos, aber wohl auch mit.                |
  167.  |           ("MiNT"-Unterstuetzung.)                                       |
  168.   --------------------------------------------------------------------------*)
  169.  
  170.  
  171.  PROCEDURE fork ( ): pidT;
  172.  
  173. (*--------------------------------------------------------------------------
  174.  | Der aktuelle Prozess wird in zwei gleichartige Prozesse aufgeteilt, aber |
  175.  | mit getrenntem Speicherbereich und unterschiedlichen Prozesskennungen.   |
  176.  | Konnte der neue Prozess nicht erzeugt werden, wird dem aufrufenden Pro-  |
  177.  | zess ein Fehler gemeldet; sonst liefert die Funktion dem aufrufenden     |
  178.  | (= Parent) die (positive) Prozesskennung des neuen Prozesses (= Child)   |
  179.  | und dem neuen Prozess eine Null.                                         |
  180.  |                                                                          |
  181.  | "GEMDOS": Funktioniert nur unter MiNT, sonst wird ein Fehler gemeldet.   |
  182.  |           ("MiNT"-Unterstuetzung.)                                       |
  183.   --------------------------------------------------------------------------*)
  184.  
  185.  
  186.  PROCEDURE execve ((* EIN/ -- *) REF prg  : ARRAY OF CHAR;
  187.                    (* EIN/ -- *)     argv : StrArray;
  188.                    (* EIN/ -- *)     envp : StrArray      ): INTEGER;
  189.  
  190.  PROCEDURE execv ((* EIN/ -- *) REF prg  : ARRAY OF CHAR;
  191.                   (* EIN/ -- *)     argv : StrArray      ): INTEGER;
  192.  
  193.  PROCEDURE execvp ((* EIN/ -- *) REF prg  : ARRAY OF CHAR;
  194.                    (* EIN/ -- *)     argv : StrArray      ): INTEGER;
  195.  
  196. (*--------------------------------------------------------------------------
  197.  | Ersetzt den aufrufenden Prozess durch einen neuen, der aus dem Programm  |
  198.  | gebildet wird, dessen Dateiname <prg> ist. <args> und <env> sind Felder  |
  199.  | aus Zeigern auf Parameter und Environment-Variablen, sodass der neue     |
  200.  | Prozess diese als Elemente der Kommandozeile bzw. als Environment-Variab-|
  201.  | len holen kann.                                                          |
  202.  | Ist <envp> = NULL, wird das augenblickliche Environment vererbt.         |
  203.  | Falls ein Fehler auftritt, wird ein negativer Wert zurueckgeliefert,     |
  204.  | andernfalls kehrt die Funktion NICHT zum Aufrufer zurueck, da dieser     |
  205.  | durch das neue Programm ersetzt wurde.                                   |
  206.  | Mit der Kombination "fork()"&"execve()" koennen somit neue Prozesse      |
  207.  | gestartet werden.                                                        |
  208.  |                                                                          |
  209.  | Spezielle Versionen von "execve()":                                      |
  210.  |                                                                          |
  211.  | "execv()" : es wird das augenblickliche Environment vererbt.             |
  212.  | "execvp()": das augenblickliche Environment wird vererbt, und <prg> wird |
  213.  |             in allen in PATH angegebenen Verzeichnissen gesucht.         |
  214.  |                                                                          |
  215.  | "GEMDOS": Da "fork()" nur unter MiNT laeuft, ist die Funktion ohne MiNT  |
  216.  |           nicht sinnvoll.                                                |
  217.  |           Die Kommandozeilenparameter werden dem neuen Programm ueber die|
  218.  |           normale Kommandozeile in der BasePage und das ARGV-Verfahren   |
  219.  |           mitgeteilt.                                                    |
  220.  |           ("MiNT"-Unterstuetzung.)                                       |
  221.   --------------------------------------------------------------------------*)
  222.  
  223.  
  224.  
  225.  
  226.  PROCEDURE waitpid ((* EIN/ -- *)     pid     : pidT;
  227.                     (* -- /AUS *) VAR state   : WaitVal;
  228.                     (* EIN/ -- *)     options : WaitOption ): pidT;
  229.  
  230. (*--------------------------------------------------------------------------
  231.  | Wartet auf die Beendigung oder das Stoppen eines vom aufrufenden Prozess |
  232.  | gestarteten Unterprozesses. Als Funktionswert wird die 'pid' des ent-    |
  233.  | sprechenden Prozesses oder -1 bei einem Fehler (z.B. wenn keine Prozesse |
  234.  | gestartet wurden) zurueckgeliefert. In <state> steht kodiert die Ursache |
  235.  | der Beendigung oder des Stoppens (siehe Definition von 'WaitVal').       |
  236.  | Mit <options> wird das Verhalten der Prozedur festgelegt (siehe Def. von |
  237.  | 'WaitOptions').                                                          |
  238.  | Mit <pid> wird festgelegt, welche Unterprozesse beruecksichtigt werden   |
  239.  | sollen:                                                                  |
  240.  |                                                                          |
  241.  |   <pid> = -1: alle Unterprozesse                                         |
  242.  |   <pid> >  0: nur Unterprozess mit dieser Prozesskennung                 |
  243.  |   <pid> =  0: alle Unterprozesse mit der gleichen Prozessgruppenkennung  |
  244.  |               wie der aufrufende Prozess                                 |
  245.  |   <pid> < -1: alle Unterprozesse, die |<pid>| als Prozessgruppenkennung  |
  246.  |               haben                                                      |
  247.  |                                                                          |
  248.  | "GEMDOS": Funktioniert nur unter MiNT, sonst wird ein Fehler gemeldet.   |
  249.  |           ("MiNT"-Unterstuetzung.)                                       |
  250.   --------------------------------------------------------------------------*)
  251.  
  252.  PROCEDURE wait ((* -- /AUS *) VAR state : WaitVal ): pidT;
  253.  
  254. (*--------------------------------------------------------------------------
  255.  | Aequivalent zu "waitpid(-1, state, WaitOption{})", es werden also keine  |
  256.  | gestoppten Unterprozesse beruecksichtigt.                                |
  257.  |                                                                          |
  258.  | "GEMDOS": Funktioniert nur unter MiNT, sonst wird ein Fehler gemeldet.   |
  259.  |           ("MiNT"-Unterstuetzung.)                                       |
  260.   --------------------------------------------------------------------------*)
  261.  
  262.  
  263.  PROCEDURE WIFEXITED   ((* EIN/ -- *) state : WaitVal ): BOOLEAN;
  264.  PROCEDURE WEXITSTATUS ((* EIN/ -- *) state : WaitVal ): INTEGER;
  265.  
  266.  PROCEDURE WIFSIGNALED ((* EIN/ -- *) state : WaitVal ): BOOLEAN;
  267.  PROCEDURE WTERMSIG    ((* EIN/ -- *) state : WaitVal ): CARDINAL;
  268.  
  269.  PROCEDURE WIFSTOPPED ((* EIN/ -- *) state : WaitVal ): BOOLEAN;
  270.  PROCEDURE WSTOPSIG   ((* EIN/ -- *) state : WaitVal ): CARDINAL;
  271.  
  272. (*--------------------------------------------------------------------------
  273.  | Diese Funktionen sind bei POSIX als Makros definiert.                    |
  274.  |                                                                          |
  275.  | "WIFEXITED()"  : TRUE, genau dann, wenn der Unterprozess ``normal'' been-|
  276.  |                  det wurde, d.h. nicht durch ein Signal.                 |
  277.  | "WEXITSTATUS()": Falls "WIFEXITED()" = TRUE, wird der Returncode des     |
  278.  |                  Unterprozesses geliefert. Dabei werden aber nur die     |
  279.  |                  unteren 8 Bit des Returncodes benutzt und vorzeichen-   |
  280.  |                  richtig erweitert.                                      |
  281.  |                  Wenn "WIFEXITED()" = FALSE, ist der Funktionswert nicht |
  282.  |                  definiert !                                             |
  283.  | "WIFSIGNALED()": TRUE, genau dann, wenn der Unterprozess durch ein Signal|
  284.  |                  beendet wurde.                                          |
  285.  | "WTERMSIG()"   : Falls "WIFSIGNALED()" = TRUE, wird der Ordinalwert des  |
  286.  |                  beendenden Signals geliefert.                           |
  287.  |                  Wenn "WIFSIGNALED()" = FALSE,ist der Funktionswert nicht|
  288.  |                  definiert !                                             |
  289.  | "WIFSTOPPED()" : TRUE, genau dann, wenn der Unterprozess momentan ge-    |
  290.  |                  stoppt, aber nicht beendet ist (``Job Control'').       |
  291.  | "WSTOPSIG()"   : Falls "WIFSTOPPED()" = TRUE, wird der Ordinalwert des   |
  292.  |                  Signals, das den Prozess gestoppt hat, geliefert.       |
  293.  |                  Wenn "WIFSTOPPED()" = FALSE, ist der Funktionswert nicht|
  294.  |                  definiert !                                             |
  295.  |                                                                          |
  296.  | Es sollten ausschliesslich diese Funktionen benutzt werden, um einen     |
  297.  | Status vom Typ 'WaitVal' zu analysieren.                                 |
  298.   --------------------------------------------------------------------------*)
  299.  
  300.  
  301.  
  302.  
  303.  
  304.  PROCEDURE times ((* -- /AUS *) VAR buf : TmsRec ): clockT;
  305.  
  306. (*--------------------------------------------------------------------------
  307.  | Liefert Informationen ueber die vom Prozess und seine Unterprozesse ver- |
  308.  | brauchte Zeit (siehe Def. von 'TmsRec'); die Zeiten sind in der Einheit  |
  309.  | 'sys.CLKTCK's / Sekunde angegeben.                                       |
  310.  | Als Funktionswert wird die vergangene Zeit seit einem beliebigen, aber   |
  311.  | festen Zeitpunkt in der Vergangenheit zurueckgeliefert; durch mehrmaligen|
  312.  | Aufruf der Funktion koennen so Zeitdifferenzen gemessen werden. Auch hier|
  313.  | ist die Einheit 'sys.CLKTCK's / Sekunde.                                 |
  314.  |                                                                          |
  315.  | "GEMDOS": Die im System verbrachte Zeit kann nicht festgestellt werden.  |
  316.  |           ("MiNT"-Unterstuetzung.)                                       |
  317.   --------------------------------------------------------------------------*)
  318.  
  319.  
  320.  
  321.  PROCEDURE Exit ((* EIN/ -- *) retval : INTEGER );
  322.  
  323. (*--------------------------------------------------------------------------
  324.  | Der aufrufende Prozess wird mit dem Returncode <retval> beendet.         |
  325.  | <retVal> sollte im Bereich [-128..127] liegen, da im Typ 'WaitVal' nur   |
  326.  | 8 Bit des Returncodes untergebracht werden koennen.                      |
  327.  | Die Prozedur muesste eigentlich "_exit()" heissen!                       |
  328.   --------------------------------------------------------------------------*)
  329.  
  330.  
  331.  
  332.  
  333. (*===========================================================================*)
  334. (* Die folgenden Funktionen haben NICHTS mit POSIX zu tun, sind jedoch fuer  *)
  335. (* "PCDOS" und "GEMDOS" notwendig, um ein *IX-like Programmstarten zu        *)
  336. (* ermoeglichen. Fuer *IX sind die Funktionen immerhin bequem.               *)
  337. (*===========================================================================*)
  338.  
  339. TYPE
  340.   SpawnMode = (
  341.     pOVERLAY, (* Aufrufer wird durch neuen Prozess ersetzt (= exec)*)
  342.     pNOWAIT,  (* neuer Prozess laeuft parallel zum erzeugenden Prozess *)
  343.     pWAIT     (* Erzeugender Prozess wird unterbrochen *)
  344.   );
  345.  
  346. (*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
  347.  
  348.  PROCEDURE spawnve ((* EIN/ -- *)     mode : SpawnMode;
  349.                     (* EIN/ -- *) REF prg  : ARRAY OF CHAR;
  350.                     (* EIN/ -- *)     argv : StrArray;
  351.                     (* EIN/ -- *)     envp : StrArray      ): INTEGER;
  352.  
  353. (*--------------------------------------------------------------------------
  354.  | Diese Prozedur fasst die Prozeduren "fork()", "execve()" und "waitpid()" |
  355.  | auf unterschiedliche Weise zusammen.                                     |
  356.  |                                                                          |
  357.  | <mode> = pOVERLAY: "spawnve()" entspricht "execve()"                     |
  358.  | <mode> = pNOWAIT : es wird ein "fork()" ausgefuehrt, und dann <prg> mit  |
  359.  |                    "execve()" gestartet.                                 |
  360.  |                    Rueckgabewert ist entweder -1 und 'errno' wird gesetzt|
  361.  |                    falls beim Aufruf von "spawnve()" etwas schiefgeht,   |
  362.  |                    oder die positive 'pid' des erzeugten Prozesses.      |
  363.  | <mode> = pWAIT   : wie pNOWAIT, aber es wird mit "waitpid()" auf das Ende|
  364.  |                    des erzeugten Prozesses gewartet. Falls beim Aufruf   |
  365.  |                    von "spawnve()" etwas schiefgeht, ist der Rueckgabe-  |
  366.  |                    wert gleich -1 und 'errno' wird gesetzt, ansonsten    |
  367.  |                    wird 'errno' auf Null gesetzt(!), und die unteren 16  |
  368.  |                    Bit des Funktionswertes sind vom Typ 'WaitVal'. Da im |
  369.  |                    oberen Byte von 'WaitVal' der Returncode des aufgeru- |
  370.  |                    fenen Prozesses enthalten ist (falls der Prozess nicht|
  371.  |                    durch ein Signal gestoppt oder terminiert wurde) und  |
  372.  |                    dieser auch negativ sein kann, und 'WaitVal' fuer den |
  373.  |                    Funktionswert auch vorzeichenrichtig auf INTEGER-     |
  374.  |                    Groesse erweitert wird,muss ein Fehler von "spawnve()"|
  375.  |                    durch Inspizieren von 'errno' ermittelt werden:       |
  376.  |                                                                          |
  377.  |                      ret := spawnve(pWAIT,...);                          |
  378.  |                      IF errno <> 0 THEN                                  |
  379.  |                        (* "spawnve()"-Fehler *)                          |
  380.  |                      ...                                                 |
  381.  |                                                                          |
  382.  | "GEMDOS": Diese Prozedur laeuft fuer <mode> = 'pWAIT' oder 'pOVERLAY'    |
  383.  |           auch ohne MiNT.                                                |
  384.  |           ACHTUNG: Es wird wirklich nur das Programm ueber 'Pexec' ge-   |
  385.  |           startet, es wird weder der Bildschirm geloescht, die Maus aus- |
  386.  |           geschaltet, noch der Critical-Error-Handler umgesetzt! Ehe man |
  387.  |           jetzt aber selbst daran geht dies zu tun, sollte man daran den-|
  388.  |           ken, dass es zum Chaos fuehrt, falls Prozesse parallel laufen  |
  389.  |           (unter MiNT), da es nur einen Bildschirm, eine Maus und einen  |
  390.  |           Error-Handler (vor MiNT 0.95) gibt! Das Problem laesst sich nur|
  391.  |           loesen, wenn TOS-Programme ihre Ausgaben in GEM-Fenster schrei-|
  392.  |           ben, wie dies unter MultiTOS der Fall sein wird.               |
  393.  |           Wenn ein (Unter)Prozess keine Bidschirmausgaben macht, ist dies|
  394.  |           natuerlich kein Problem.                                       |
  395.  |           Ohne MiNT wird Pexec mit Modus 0 (pWAIT) gestartet, sonst      |
  396.  |           sind auch Modus 100 (pNOWAIT) und 200 (pOVERLAY) moeglich.     |
  397.  |           ("MiNT"-Unterstuetzung.)                                       |
  398.   --------------------------------------------------------------------------*)
  399.  
  400.  
  401.  
  402.  PROCEDURE spawnv ((* EIN/ -- *)     mode : SpawnMode;
  403.                    (* EIN/ -- *) REF prg  : ARRAY OF CHAR;
  404.                    (* EIN/ -- *)     argv : StrArray      ): INTEGER;
  405.  
  406.  PROCEDURE spawnvp ((* EIN/ -- *)     mode : SpawnMode;
  407.                     (* EIN/ -- *) REF prg  : ARRAY OF CHAR;
  408.                     (* EIN/ -- *)     argv : StrArray      ): INTEGER;
  409.  
  410. (*--------------------------------------------------------------------------
  411.  | Spezielle Versionen von "spawnve()":                                     |
  412.  |                                                                          |
  413.  | "spawnv()"  : es wird das augenblickliche Environment vererbt.           |
  414.  | "spawnvp()" : das augenblickliche Environment wird vererbt, und <prg>    |
  415.  |               wird in allen in PATH angegebenen Verzeichnissen gesucht.  |
  416.   --------------------------------------------------------------------------*)
  417.  
  418. END proc.
  419.