DEADSOFTWARE

DswHostProcs: hack-fix for cpfront
[cpc.git] / src / posix / generic / Dsw / Mod / HostProcs.cp
index efe84737b230ce44a7bb1002943768e77c208231..8516697aa512bd6390d32152d1b2a802e5ea5519 100644 (file)
@@ -1,8 +1,8 @@
 MODULE DswHostProcs;
 
-  IMPORT SYSTEM, Log, DswProcs, HostLang, unistd := PosixCunistd, stdlib := PosixCstdlib,
+  IMPORT SYSTEM, DswProcs, HostLang, unistd := PosixCunistd, stdlib := PosixCstdlib,
     signal := PosixCsignal, sys_wait := PosixCsys_wait, macro := PosixCmacro,
-    errno := PosixCerrno;
+    errno := PosixCerrno, sys_stat := PosixCsys_stat;
 
   TYPE
     Directory = POINTER TO RECORD (DswProcs.Directory) END;
@@ -16,13 +16,6 @@ MODULE DswHostProcs;
       code: unistd.int;
     END;
 
-  PROCEDURE (d: Directory) New* (): Process;
-    VAR p: Process;
-  BEGIN
-    NEW(p); p.argv := NIL; p.pid := -1; p.code := 0;
-    RETURN p
-  END New;
-
   PROCEDURE ToHost (IN s: ARRAY OF CHAR): String;
     VAR ss: String; res: INTEGER;
   BEGIN
@@ -33,6 +26,56 @@ MODULE DswHostProcs;
     RETURN ss
   END ToHost;
 
+  PROCEDURE IsRegular (mode: sys_stat.mode_t): BOOLEAN;
+  BEGIN
+    RETURN BITS(mode) * BITS(sys_stat.S_IFMT) = BITS(sys_stat.S_IFREG)
+  END IsRegular;
+
+  PROCEDURE (d: Directory) New* (): Process;
+    VAR p: Process;
+  BEGIN
+    NEW(p); p.argv := NIL; p.pid := -1; p.code := 0;
+    RETURN p
+  END New;
+
+  PROCEDURE (d: Directory) GetPath (IN name: ARRAY OF CHAR): DswProcs.String;
+    VAR
+      ch: CHAR;
+      v: POINTER [untagged] TO ARRAY [untagged] OF SHORTCHAR;
+      s, e, ret: POINTER TO ARRAY OF CHAR;
+      w: String;
+      cres: sys_stat.int;
+      i, j, k, len, res: INTEGER;
+      buf: sys_stat.struct_stat;
+      found: BOOLEAN;
+  BEGIN
+    v := stdlib.getenv("PATH");
+    IF v # NIL THEN
+      NEW(s, LEN(v$) * 3 + 1);
+      HostLang.HostToString(v$, s, HostLang.pep383x, res);
+      ASSERT(res = 0, 100);
+      len := LEN(name$);
+      NEW(e, LEN(s$) + len + 2);
+      i := 0;
+      REPEAT
+        j := -1; found := FALSE;
+        REPEAT ch := s[i]; INC(i); INC(j); e[j] := ch UNTIL (ch = ":") OR (ch = 0X);
+        IF e[0] = "/" THEN
+          e[j] := "/"; INC(j);
+          FOR k := 0 TO len DO
+            e[j + k] := name[k]
+          END;
+          e[j + k] := 0X;
+          w := ToHost(e);
+          cres := macro.stat(w, buf);
+          found := (cres = 0) & IsRegular(buf.st_mode) & (unistd.access(w, unistd.X_OK) = 0)
+        END
+      UNTIL found OR (ch = 0X);
+      IF ~found THEN e := NIL END
+    END;
+    RETURN e
+  END GetPath;
+
   PROCEDURE (p: Process) Program* (IN exe: ARRAY OF CHAR);
     VAR argv: SString;
   BEGIN
@@ -57,16 +100,17 @@ MODULE DswHostProcs;
   PROCEDURE (p: Process) Execute* (OUT ok: BOOLEAN);
     TYPE
       UString = POINTER [untagged] TO ARRAY [untagged] OF SHORTCHAR;
-      SUString = POINTER TO ARRAY OF UString;
+      SUString = POINTER [untagged] TO ARRAY [untagged] OF UString;
     VAR
-      i, j: INTEGER; pid: unistd.pid_t; res: unistd.int; argv: SUString;
+      i, j, adr: INTEGER; pid: unistd.pid_t; res: unistd.int; argv: SUString;
   BEGIN
     ASSERT(p.pid = -1, 20);
     ASSERT(p.argv # NIL, 21);
-    NEW(argv, LEN(p.argv) + 1);
+    argv := SYSTEM.VAL(SUString, stdlib.malloc((LEN(p.argv) + 1)) * SIZE(UString));
     FOR i := 0 TO LEN(p.argv) - 1 DO
       argv[i] := SYSTEM.VAL(UString, SYSTEM.ADR(p.argv[i, 0]))
     END;
+    argv[i] := NIL;
     pid := unistd.fork();
     IF pid = 0 THEN
       res := unistd.execv(argv[0], argv);
@@ -78,7 +122,8 @@ MODULE DswHostProcs;
       p.argv := NIL; (* or save it for debugging and reuse? *)
       p.pid := pid;
       ok := TRUE
-    END
+    END;
+    stdlib.free(SYSTEM.ADR(argv[0]))
   END Execute;
 
   PROCEDURE (p: Process) Terminate* (OUT ok: BOOLEAN);