Search code examples
rascal

How to execute a program that is not on PATH using Rascal


I'm trying to execute a program on Ubuntu using the exec or createProcess function, but whenever I do so I get an error that I cannot explain. E.g.:

rascal>import util::ShellExec;
ok
rascal>import IO;
ok
rascal>exists(|home:///Desktop/testProgram|);
bool: true
rascal>exec("./testProgram", workingDir=|home:///Desktop|);
|std:///util/ShellExec.rsc|(417,856,<16,0>,<32,124>): Java(
  "IOException",
  "Cannot run program \"./testProgram\": error=2, No such file or directory",
  Java("IOException","error=2, No such file or directory"))
        at java.lang.ProcessBuilder.start(|unknown:///ProcessBuilder.java|(0,0,<1128,0>,<1128,0>))
        at java.lang.ProcessBuilder.start(|unknown:///ProcessBuilder.java|(0,0,<1071,0>,<1071,0>))
        at org.rascalmpl.library.util.ShellExec.createProcessInternal(|unknown:///ShellExec.java|(0,0,<128,0>,<128,0>))
        at org.rascalmpl.library.util.ShellExec.createProcess(|unknown:///ShellExec.java|(0,0,<48,0>,<48,0>))
        at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(|unknown:///NativeMethodAccessorImpl.java|(0,0,<0,0>,<0,0>))
        at *** somewhere ***(|std:///util/ShellExec.rsc|(417,856,<16,0>,<32,124>))
        at createProcess(|std:///util/ShellExec.rsc|(1557,3,<40,81>,<40,84>))
        at $root$(|prompt:///|(0,52,<1,0>,<1,52>)ok

The mentioned testProgram is simply the following compiled C program:

#include <stdio.h>

int main() {
    printf("test program\n");
    return 0;
}

Executing programs that are on PATH works just fine. E.g.:

rascal>exec("echo", args=["test"]);
str: "test\n"

Especially odd to me is the fact that at createProcess(|std:///util/ShellExec.rsc|(1557,3,<40,81>,<40,84>)) points to the identifier env on the second line in this code block (the createProcess call):

public str exec(str processCommand, loc workingDir=|cwd:///|, list[str] args = [], map[str,str] env = ()) {
   pid = createProcess(processCommand, workingDir=workingDir, args=args, envVars=env);
   result = readEntireStream(pid);
   killProcess(pid);
   return result;
}

I can't figure out how this argument connects to the command that I am trying to execute or to a file or directory not existing.

What is going wrong here? Is it not possible to execute files that are not on PATH or am I doing something wrong?


Solution

  • It seems that createProcess and exec are not ready to understand all the abstract schemes (like home:///) I changed your example to file:///Users/myname/Desktop, and then it worked.