home *** CD-ROM | disk | FTP | other *** search
Modula Implementation | 1993-10-23 | 21.3 KB | 895 lines |
- IMPLEMENTATION MODULE proc;
- (*__NO_CHECKS__*)
- (*****************************************************************************)
- (* Basiert auf der MiNTLIB von Eric R. Smith *)
- (* --------------------------------------------------------------------------*)
- (* STATUS: OK *)
- (* --------------------------------------------------------------------------*)
- (* 14-Feb-93, Holger Kleinschmidt *)
- (*****************************************************************************)
-
- VAL_INTRINSIC
- CAST_IMPORT
- OSCALL_IMPORT
-
- FROM SYSTEM IMPORT
- (* TYPE *) ADDRESS,
- (* PROC *) ADR;
-
- FROM pSTRING IMPORT
- (* CONST*) EOS,
- (* TYPE *) StrArray, StrPtr, StrRange, ArrayRange,
- (* PROC *) LenC, COPY, ASSIGN, TOKEN, SLEN, APPEND, APPENDCHR, RPOSCHR,
- RPOSCHRSET;
-
- FROM cmdline IMPORT
- (* VAR *) environ,
- (* PROC *) GetEnvVar;
-
- FROM types IMPORT
- (* CONST*) NULL, PATHMAX, SUFFIXSEP, DDIRSEP, XDIRSEP,
- (* TYPE *) SIGNEDWORD, UNSIGNEDWORD, SIGNEDLONG, UNSIGNEDLONG, FileName,
- WORDSET, PathName, uidT, gidT, pidT, clockT;
-
- FROM err IMPORT
- (* CONST*) eOK, eACCDN, EFAULT, EINVAL, ENOSYS, ENOMEM, ENOENT, ECHILD, E2BIG,
- EPERM,
- (* VAR *) errno;
-
- FROM DosFile IMPORT
- (* CONST*) EXECSUFFIX,
- (* PROC *) UnixToDos;
-
- FROM DosSystem IMPORT
- (* TYPE *) CmdLine, BasePtr, BasePage,
- (* VAR *) PID, PPID,
- (* PROC *) SysClock;
- #if MINT
- FROM DosSystem IMPORT MiNTVersion;
- #endif
-
- FROM file IMPORT
- (* CONST*) sIFMT, sIFREG,
- (* TYPE *) StatRec, modeT,
- (* PROC *) stat;
-
- #include "oscalls.m2h"
-
- (*==========================================================================*)
-
- CONST EOKL = LIC(0);
-
- VAR
- #if MINT
- MiNT : CARDINAL;
- #endif
- CHILDTIME : UNSIGNEDLONG;
-
- (*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
-
- PROCEDURE getpid ( ): pidT;
- (*T*)
- VAR base : BasePtr;
- #if MINT
- wres : UNSIGNEDWORD;
- #endif
- BEGIN
- #if MINT
- IF MiNT > 0 THEN
- Pgetpid(wres);
- RETURN(VAL(pidT,wres));
- ELSE
- #endif
- RETURN(VAL(pidT,PID));
- #if MINT
- END;
- #endif
- END getpid;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE getppid ( ): pidT;
- (*T*)
- VAR base : BasePtr;
- #if MINT
- wres : UNSIGNEDWORD;
- #endif
- BEGIN
- #if MINT
- IF MiNT > 0 THEN
- Pgetppid(wres);
- RETURN(VAL(pidT,wres));
- ELSE
- #endif
- RETURN(VAL(pidT,PPID));
- #if MINT
- END;
- #endif
- END getppid;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE getuid ( ): uidT;
- (*T*)
- #if MINT
- VAR wres : UNSIGNEDWORD;
- #endif
- BEGIN
- #if MINT
- IF MiNT > 0 THEN
- Pgetuid(wres);
- RETURN(VAL(uidT,wres));
- ELSE
- #endif
- RETURN(0);
- #if MINT
- END;
- #endif
- END getuid;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE getgid ( ): gidT;
- (*T*)
- #if MINT
- VAR wres : UNSIGNEDWORD;
- #endif
- BEGIN
- #if MINT
- IF MiNT > 0 THEN
- Pgetgid(wres);
- RETURN(VAL(gidT,wres));
- ELSE
- #endif
- RETURN(0);
- #if MINT
- END;
- #endif
- END getgid;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE geteuid ( ): uidT;
- (*T*)
- #if MINT
- VAR wres : UNSIGNEDWORD;
- #endif
- BEGIN
- #if MINT
- IF MiNT > 0 THEN
- IF MiNT >= 95 THEN
- Pgeteuid(wres);
- ELSE
- Pgetuid(wres);
- END;
- RETURN(VAL(uidT,wres));
- ELSE
- #endif
- RETURN(0);
- #if MINT
- END;
- #endif
- END geteuid;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE getegid ( ): gidT;
- (*T*)
- #if MINT
- VAR wres : UNSIGNEDWORD;
- #endif
- BEGIN
- #if MINT
- IF MiNT > 0 THEN
- IF MiNT >= 95 THEN
- Pgetegid(wres);
- ELSE
- Pgetgid(wres);
- END;
- RETURN(VAL(gidT,wres));
- ELSE
- #endif
- RETURN(0);
- #if MINT
- END;
- #endif
- END getegid;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE setuid ((* EIN/ -- *) uid : uidT ): INTEGER;
- (*T*)
- #if MINT
- VAR wres : SIGNEDWORD;
- #endif
- BEGIN
- #if MINT
- IF MiNT > 0 THEN
- Psetuid(VAL(UNSIGNEDWORD,uid), wres);
- IF wres < eOK THEN
- IF wres = eACCDN THEN
- errno := EPERM;
- ELSE
- errno := INT(wres);
- END;
- RETURN(-1);
- ELSE
- RETURN(0);
- END;
- ELSE
- #endif
- IF uid = 0 THEN
- RETURN(0);
- ELSE
- errno := EINVAL;
- RETURN(-1);
- END;
- #if MINT
- END;
- #endif
- END setuid;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE setgid ((* EIN/ -- *) gid : gidT ): INTEGER;
- (*T*)
- #if MINT
- VAR wres : SIGNEDWORD;
- #endif
- BEGIN
- #if MINT
- IF MiNT > 0 THEN
- Psetgid(VAL(UNSIGNEDWORD,gid), wres);
- IF wres < eOK THEN
- IF wres = eACCDN THEN
- errno := EPERM;
- ELSE
- errno := INT(wres);
- END;
- RETURN(-1);
- ELSE
- RETURN(0);
- END;
- ELSE
- #endif
- IF gid = 0 THEN
- RETURN(0);
- ELSE
- errno := EINVAL;
- RETURN(-1);
- END;
- #if MINT
- END;
- #endif
- END setgid;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE getpgrp ( ): pidT;
- (*T*)
- #if MINT
- VAR wres : UNSIGNEDWORD;
- #endif
- BEGIN
- #if MINT
- IF MiNT > 0 THEN
- Pgetpgrp(wres);
- RETURN(VAL(pidT,wres));
- ELSE
- #endif
- RETURN(VAL(pidT,PID));
- #if MINT
- END;
- #endif
- END getpgrp;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE setpgid ((* EIN/ -- *) pid : pidT;
- (* EIN/ -- *) pgid : pidT ): INTEGER;
- (**)
- #if MINT
- VAR wres : SIGNEDWORD;
- #endif
- BEGIN
- #if MINT
- IF MiNT > 0 THEN
- Psetpgrp(VAL(SIGNEDWORD,pid), VAL(SIGNEDWORD,pgid), wres);
- IF wres < eOK THEN
- IF wres = eACCDN THEN
- errno := EPERM;
- ELSE
- errno := INT(wres);
- END;
- RETURN(-1);
- ELSE
- RETURN(0);
- END;
- ELSE
- #endif
- IF ((pid = 0) OR (pid = VAL(pidT,PID)))
- AND ((pgid = 0) OR (pgid = VAL(pidT,PID)))
- THEN
- RETURN(0);
- ELSE
- errno := EINVAL;
- RETURN(-1);
- END;
- #if MINT
- END;
- #endif
- END setpgid;
-
- (*--------------------------------------------------------------------------*)
-
- PROCEDURE fork ( ): pidT;
- (*T*)
- VAR wres : SIGNEDWORD;
-
- BEGIN
- #if MINT
- IF MiNT > 0 THEN
- Pfork(wres);
- IF wres < eOK THEN
- errno := INT(wres);
- RETURN(-1);
- ELSE
- RETURN(VAL(pidT,wres));
- END;
- END;
- #endif
- errno := ENOSYS;
- RETURN(-1);
- END fork;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE MakeWaitCode ((* EIN/ -- *) retCode : SIGNEDWORD ): SIGNEDWORD;
- (*T*)
- CONST SIGINT = 2;
-
- VAR exit : UNSIGNEDWORD;
- sig : UNSIGNEDWORD;
- ret : WORDSET;
-
- BEGIN
- IF retCode = -32 THEN
- (* Programm wurde durch 'Ctrl-C' abgebrochen *)
- exit := 0;
- sig := SIGINT;
- ELSE
- ret := CAST(WORDSET,retCode);
- #if reverse_set
- exit := CAST(UNSIGNEDWORD,ret * WORDSET{8..15});
- sig := VAL(UNSIGNEDWORD,CAST(UNSIGNEDWORD,ret * WORDSET{1..7}) DIV 256);
- #else
- exit := CAST(UNSIGNEDWORD,ret * WORDSET{0..7});
- sig := VAL(UNSIGNEDWORD,CAST(UNSIGNEDWORD,ret * WORDSET{8..14}) DIV 256);
- #endif
- END;
- IF (sig <> 0) AND (exit <> 0) AND (exit <> 127) THEN
- (* normaler Returncode, kein Signal *)
- sig := 0;
- END;
- IF (exit = 127) AND (sig <> 0) THEN
- (* Prozess gestoppt *)
- RETURN(retCode); (* ist schon entsprechend kodiert *)
- ELSE
- (* Prozess terminiert, evtl. durch Signal *)
- RETURN(VAL(SIGNEDWORD,exit * 256 + sig));
- END;
- END MakeWaitCode;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE wait ((* -- /AUS *) VAR state : WaitVal ): pidT;
- (*T*)
- #if MINT
- VAR res : RECORD
- CASE TAG_COLON BOOLEAN OF
- FALSE: long : SIGNEDLONG;
- |TRUE : pid : UNSIGNEDWORD;
- term : SIGNEDWORD;
- END;
- END;
- #endif
- BEGIN
- state := WaitVal{};
- #if MINT
- IF MiNT = 0 THEN
- #endif
- errno := ECHILD;
- RETURN(-1);
- #if MINT
- ELSE
- Pwait3(0, LC(0), res.long);
- END;
- IF res.long < EOKL THEN
- errno := INT(res.long);
- RETURN(-1);
- END;
- state := CAST(WaitVal,MakeWaitCode(res.term));
- RETURN(VAL(pidT,res.pid));
- #endif
- END wait;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE waitpid ((* EIN/ -- *) pid : pidT;
- (* -- /AUS *) VAR state : WaitVal;
- (* EIN/ -- *) options : WaitOption ): pidT;
- (*T*)
- #if MINT
- VAR res : RECORD
- CASE TAG_COLON BOOLEAN OF
- FALSE: long : SIGNEDLONG;
- |TRUE : pid : UNSIGNEDWORD;
- term : SIGNEDWORD;
- END;
- END;
- #endif
- BEGIN
- state := WaitVal{};
- #if MINT
- IF MiNT = 0 THEN
- #endif
- errno := ECHILD;
- RETURN(-1);
- #if MINT
- ELSIF MiNT < 96 THEN
- IF (pid <> -1) AND (pid <> 0) THEN
- errno := EINVAL;
- RETURN(-1);
- END;
- Pwait3(CAST(UNSIGNEDWORD,options), LC(0), res.long);
- ELSE
- Pwaitpid(VAL(SIGNEDWORD,pid), CAST(UNSIGNEDWORD,options), LC(0), res.long);
- END;
- IF res.long < EOKL THEN
- errno := INT(res.long);
- RETURN(-1);
- END;
- state := CAST(WaitVal,MakeWaitCode(res.term));
- RETURN(VAL(pidT,res.pid));
- #endif
- END waitpid;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE WIFEXITED ((* EIN/ -- *) state : WaitVal ): BOOLEAN;
- BEGIN
- RETURN((state * wStopval <> WSTOPPED) AND (state * wTermsig = WaitVal{}));
- END WIFEXITED;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE WEXITSTATUS ((* EIN/ -- *) state : WaitVal ): INTEGER;
- BEGIN
- RETURN(INT(CAST(SIGNEDWORD,state * wRetcode) DIV 256));
- END WEXITSTATUS;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE WIFSIGNALED ((* EIN/ -- *) state : WaitVal ): BOOLEAN;
- BEGIN
- RETURN((state * wStopval <> WSTOPPED) AND (state * wTermsig <> WaitVal{}));
- END WIFSIGNALED;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE WTERMSIG ((* EIN/ -- *) state : WaitVal ): CARDINAL;
- BEGIN
- RETURN(VAL(CARDINAL,CAST(UNSIGNEDWORD,state * wTermsig)));
- END WTERMSIG;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE WIFSTOPPED ((* EIN/ -- *) state : WaitVal ): BOOLEAN;
- BEGIN
- RETURN(state * wStopval = WSTOPPED);
- END WIFSTOPPED;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE WSTOPSIG ((* EIN/ -- *) state : WaitVal ): CARDINAL;
- BEGIN
- RETURN(VAL(CARDINAL,CAST(UNSIGNEDWORD,state * wStopsig) DIV 256));
- END WSTOPSIG;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE Spawn ((* EIN/ -- *) mode : SpawnMode;
- #if has_REF
- (* EIN/ -- *) REF prg : ARRAY OF CHAR;
- #else
- (* EIN/ -- *) VAR prg : ARRAY OF CHAR;
- #endif
- (* EIN/ -- *) argv : StrArray;
- (* EIN/ -- *) envp : StrArray ): INTEGER;
- (*T*)
- VAR envLen : UNSIGNEDLONG;
- argPtr : StrPtr;
- envPtr : StrPtr;
- mem : ADDRESS;
- arg : ArrayRange;
- envIdx : StrRange;
- envCmd : StrRange;
- cmdIdx : StrRange;
- pexec : UNSIGNEDWORD;
- res : INTEGER;
- wres : SIGNEDWORD;
- lres : SIGNEDLONG;
- childStart : UNSIGNEDLONG;
- dot : BOOLEAN;
- done : BOOLEAN;
- ARGV : ARRAY [0..5] OF CHAR;
- cmdLine : CmdLine;
- path0 : PathName;
-
- PROCEDURE argcpy (arg : StrPtr);
- VAR i : StrRange;
- c : CHAR;
- BEGIN
- i := 0;
- REPEAT
- c := arg^[i];
- envPtr^[envIdx] := c;
- INC(i);
- INC(envIdx);
- UNTIL c = 0C;
- END argcpy;
-
- BEGIN
- errno := 0;
- pexec := 0;
- #if MINT
- IF MiNT > 0 THEN
- IF mode = pNOWAIT THEN
- pexec := 100;
- ELSIF mode = pOVERLAY THEN
- pexec := 200;
- END;
- ELSIF mode = pNOWAIT THEN
- #else
- IF mode = pNOWAIT THEN
- #endif
- errno := EINVAL;
- RETURN(-1);
- END;
-
- IF (argv = NULL) OR (argv^[0] = NULL) THEN
- errno := EFAULT;
- RETURN(-1);
- END;
- UnixToDos(prg, path0, dot, done);
- IF NOT done THEN
- RETURN(-1);
- END;
-
- IF envp = NULL THEN
- envp := environ;
- END;
-
- (* Laenge des benoetigten Environments berechnen.
- * Dazu gehoeren entweder das uebergebene oder das aktuelle
- * Environment und die Kommandozeilenargumente einschliesslich
- * des Programmnamens.
- *)
- envLen := 0;
- arg := 0;
- WHILE argv^[arg] <> NULL DO
- INC(envLen, VAL(UNSIGNEDLONG,LenC(argv^[arg])+1));
- (* + 1, wegen abschliessendem Nullbyte *)
- INC(arg);
- END;
-
- arg := 0;
- WHILE envp^[arg] <> NULL DO
- INC(envLen, VAL(UNSIGNEDLONG,LenC(envp^[arg])+1));
- INC(arg);
- END;
- INC(envLen, 20); (* Platz fuer "ARGV=" & sicherheitshalber etwas mehr *)
-
- (* Benoetigten Speicher anfordern.
- * Wenn nicht genuegend Speicher vorhanden ist, mit Fehlermeldung abbrechen.
- *)
- Malloc(envLen, mem);
- IF mem = NULL THEN
- errno := E2BIG;
- RETURN(-1);
- END;
- envPtr := CAST(StrPtr,mem);
- envIdx := 0;
-
- (* Das Environment mit den Variablen auffuellen *)
- arg := 0;
- WHILE envp^[arg] <> NULL DO
- argcpy(envp^[arg]);
- INC(arg);
- END;
-
- (* Kommandozeile mit ARGV-Verfahren ins Environment schreiben.
- * Beginn der eigentlichen Argumente (nach dem Programmnamen) merken,
- * fuer die Uebertragung in die Basepage-Kommandozeile.
- *)
- ARGV := "ARGV=";
- argcpy(CAST(StrPtr,ADR(ARGV)));
- argcpy(argv^[0]); (* Programmname *)
- envCmd := envIdx; (* Beginn der Argumente *)
- arg := 1;
- WHILE argv^[arg] <> NULL DO
- argcpy(argv^[arg]);
- INC(arg);
- END;
- envPtr^[envIdx] := 0C; (* Ende des Environments kennzeichnen *)
- envPtr^[envIdx+1] := 0C; (* Falls es keine Argumente gab *)
-
- (* Soviel der Argumente wie moeglich in die Basepage-Kommandozeile
- * uebertragen. ARGV-Verfahren durch den sonst ungueltigen
- * Kommandozeilenlaengenwert 127 signalisieren.
- *)
- cmdLine[0] := CHR(127);
- cmdIdx := 1;
- WHILE cmdIdx <= 124 DO
- IF envPtr^[envCmd] <> 0C THEN
- cmdLine[cmdIdx] := envPtr^[envCmd];
- ELSIF envPtr^[envCmd+1] <> 0C THEN
- cmdLine[cmdIdx] := ' ';
- ELSE
- cmdLine[cmdIdx] := 0C;
- cmdIdx := 125;
- END;
- INC(cmdIdx);
- INC(envCmd);
- END;
- cmdLine[125] := 0C;
-
- childStart := SysClock();
- Pexec(pexec,ADR(path0),ADR(cmdLine),envPtr,lres);
- INC(CHILDTIME, SysClock() - childStart);
-
- Mfree(envPtr, wres);
- res := INT(lres);
- wres := VAL(SIGNEDWORD,res);
- IF lres < EOKL THEN
- (* Wenn "Pexec" selbst fehlschlaegt, gibts einen
- * negativen 32-Bit-Wert.
- *)
- errno := res;
- RETURN(-1);
- ELSIF mode = pOVERLAY THEN
- (* Ohne MiNT muss selbst fuer die Beendigung des laufenden
- * Prozesses gesorgt werden. Mit MiNT kehrt der ``Pexec''-Aufruf
- * erst gar nicht zurueck!
- *)
- Pterm(wres);
- ELSIF mode = pWAIT THEN
- RETURN(INT(MakeWaitCode(wres)));
- ELSE
- (* Bei pNOWAIT wird die (positive) Prozess-ID zurueckgegeben *)
- RETURN(res);
- END;
- END Spawn;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE spawnv ((* EIN/ -- *) mode : SpawnMode;
- (* EIN/ -- *) REF prg : ARRAY OF CHAR;
- (* EIN/ -- *) argv : StrArray ): INTEGER;
- (*T*)
- BEGIN
- RETURN(Spawn(mode, prg, argv, environ));
- END spawnv;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE spawnve ((* EIN/ -- *) mode : SpawnMode;
- (* EIN/ -- *) REF prg : ARRAY OF CHAR;
- (* EIN/ -- *) argv : StrArray;
- (* EIN/ -- *) envp : StrArray ): INTEGER;
- (*T*)
- BEGIN
- RETURN(Spawn(mode, prg, argv, envp));
- END spawnve;
-
- (*---------------------------------------------------------------------------*)
- #if has_REF
- PROCEDURE FindExec ((* EIN/ -- *) REF file : ARRAY OF CHAR;
- #else
- PROCEDURE FindExec ((* EIN/ -- *) VAR file : ARRAY OF CHAR;
- #endif
- (* -- /AUS *) VAR path : ARRAY OF CHAR ): BOOLEAN;
- (*T*)
- CONST
- DEFAULTPATH = ".";
- #if no_MIN_MAX
- MAXCARD = CAST(CARDINAL,-1);
- #else
- MAXCARD = MAX(CARDINAL);
- #endif
-
- VAR sIdx,dIdx : INTEGER;
- dtIdx : CARDINAL;
- stIdx : CARDINAL;
- fLen : CARDINAL;
- pLen : CARDINAL;
- l11, l12 : CARDINAL;
- l21, l22 : CARDINAL;
- st : StatRec;
- ext : FileName;
- suffices : PathName;
- dirs : PathName;
-
- BEGIN
- sIdx := RPOSCHR(0, SUFFIXSEP, file);
- dIdx := RPOSCHRSET(0, "\/", file);
-
- IF dIdx >= 0 THEN
- (* <file> enthaelt einen Pfad -> nur dort suchen.
- * Der Pfad wird aus <file> entfernt.
- *)
- COPY(0, dIdx, file, dirs);
- COPY(dIdx+1, MAXCARD, file, file);
- ELSIF NOT GetEnvVar("PATH", dirs) THEN
- (* <file> hat keinen Pfad und "PATH" existiert nicht.
- * -> nur in 'DEFAULTPATH' suchen.
- *)
- dirs := DEFAULTPATH;
- END;
-
- IF sIdx > dIdx THEN
- (* <file> hat eine Extension -> nur diese probieren.
- * Die Extension wird aus <file> entfernt.
- *)
- COPY(sIdx+1, MAXCARD, file, suffices);
- COPY(0, sIdx, file, file);
- ELSIF NOT GetEnvVar("SUFFIX", suffices) THEN
- (* <file> hat keine Extension und "SUFFIX" existiert nicht.
- * -> Extensionen aus 'EXECSUFFIX' probieren.
- *)
- ASSIGN(EXECSUFFIX, suffices);
- END;
-
- (* Jetzt enthaelt 'dirs' alle zu durchsuchenden Verzeichnisse,
- * 'suffices' alle auszuprobierenden Extensionen und 'file'
- * den ``nackten'' Dateinamen ohne Pfad und Extension.
- *)
- APPENDCHR(".", file); (* Punkt fuer Extension *)
-
- dtIdx := 0; l11 := 0;
-
- (* Jedes Verzeichnis mit allen Extensionen durchprobieren *)
- WHILE TOKEN(dirs, ";,", dtIdx, l11, l12, path) DO
- pLen := SLEN(path);
- IF (pLen > 0) AND (pLen < PATHMAX-1)
- AND (path[pLen-1] <> DDIRSEP) AND (path[pLen-1] <> XDIRSEP)
- THEN
- path[pLen] := DDIRSEP;
- INC(pLen);
- path[pLen] := EOS;
- END;
- APPEND(file, path); (* 'path': Pfad + Dateiname + Punkt *)
- pLen := SLEN(path);
-
- stIdx := 0; l21 := 0;
- WHILE TOKEN(suffices, ";,", stIdx, l21, l22, ext) DO
- (* Jetzt wird probiert, ob eine Datei mit einer der angegebenen
- * Extensionen im Verzeichnis existiert. Das 'x-Bit' wird nicht
- * beruecksichtigt.
- *)
- IF ext[0] = EOS THEN
- (* Auch ohne Extension versuchen *)
- path[pLen-1] := EOS; (* Ohne Punkt *)
- ELSE
- APPEND(ext, path); (* Extension anhaengen *)
- END;
- IF (stat(path, st) = 0) AND (st.stMode * sIFMT = sIFREG) THEN
- RETURN(TRUE);
- END;
- path[pLen-1] := '.'; (* Punkt fuer Extension wieder an seinen Platz *)
- path[pLen] := EOS; (* Extension wieder entfernen *)
- END;
- END;
- RETURN(FALSE);
- END FindExec;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE spawnvp ((* EIN/ -- *) mode : SpawnMode;
- (* EIN/ -- *) REF prg : ARRAY OF CHAR;
- (* EIN/ -- *) argv : StrArray ): INTEGER;
- (*T*)
- VAR path0 : PathName;
- BEGIN
- IF FindExec(prg, path0) THEN
- RETURN(Spawn(mode, path0, argv, environ));
- ELSE
- errno := ENOENT;
- RETURN(-1);
- END;
- END spawnvp;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE execve ((* EIN/ -- *) REF prg : ARRAY OF CHAR;
- (* EIN/ -- *) argv : StrArray;
- (* EIN/ -- *) envp : StrArray ): INTEGER;
- (*T*)
- BEGIN
- RETURN(Spawn(pOVERLAY, prg, argv, envp));
- END execve;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE execv ((* EIN/ -- *) REF prg : ARRAY OF CHAR;
- (* EIN/ -- *) argv : StrArray ): INTEGER;
- (*T*)
- BEGIN
- RETURN(Spawn(pOVERLAY, prg, argv, environ));
- END execv;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE execvp ((* EIN/ -- *) REF prg : ARRAY OF CHAR;
- (* EIN/ -- *) argv : StrArray ): INTEGER;
- (*T*)
- VAR path0 : PathName;
- BEGIN
- IF FindExec(prg, path0) THEN
- RETURN(Spawn(pOVERLAY, path0, argv, environ));
- ELSE
- errno := ENOENT;
- RETURN(-1);
- END;
- END execvp;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE Exit ((* EIN/ -- *) retval : INTEGER );
- (*T*)
- BEGIN
- Pterm(VAL(SIGNEDWORD,retval));
- END Exit;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE times ((* -- /AUS *) VAR buf : TmsRec ): clockT;
- (**)
- VAR clock : UNSIGNEDLONG;
- #if MINT
- usage : ARRAY [0..7] OF UNSIGNEDLONG;
- #endif
- BEGIN
- clock := SysClock();
- #if MINT
- IF MiNT > 0 THEN
- Prusage(ADR(usage));
- WITH buf DO
- tmsUtime := usage[1] DIV LC(5);
- tmsStime := usage[0] DIV LC(5);
- tmsCUtime := usage[3] DIV LC(5);
- tmsCStime := usage[2] DIV LC(5);
- END;
- ELSE
- #endif
- WITH buf DO
- tmsUtime := VAL(clockT,clock - CHILDTIME);
- tmsStime := 0; (* nicht feststellbar *)
- tmsCUtime := VAL(clockT,CHILDTIME);
- tmsCStime := 0; (* nicht feststellbar *)
- END;
- #if MINT
- END;
- #endif
- RETURN(VAL(clockT,clock));
- END times;
-
- (*===========================================================================*)
-
- BEGIN
- #if MINT
- MiNT := MiNTVersion();
- #endif
- CHILDTIME := 0;
- END proc.
-