What is ProcessBuilder of Java's counterpart in C++? - java

There is a python program which is not installed in system's default path. How do I call a program in C++ similar to ProcessBuilder's functionality in Java.
What is the equivalent of the below in C++
ProcessBuilder pb = new ProcessBuilder("python3","software","param");
pb.inheritIO();
Process ps = pb.start();
if(ps.exitValue()==0) {
System.out.println("Process executed successfully");
}

https://en.cppreference.com/w/cpp/utility/program/system
int wstatus = std::system("python3 software param");
The return value is an implementation-defined value. On Posix systems it contains a lot of information that can be extracted using the following macros:
WIFEXITED(wstatus)
returns true if the child terminated normally, that is, by calling exit(3) or
_exit(2), or by returning from main().
WEXITSTATUS(wstatus)
returns the exit status of the child. This consists of the least significant 8
bits of the status argument that the child specified in a call to exit(3) or
_exit(2) or as the argument for a return statement in main(). This macro should
be employed only if WIFEXITED returned true.
WIFSIGNALED(wstatus)
returns true if the child process was terminated by a signal.
WTERMSIG(wstatus)
returns the number of the signal that caused the child process to terminate.
This macro should be employed only if WIFSIGNALED returned true.
WCOREDUMP(wstatus)
returns true if the child produced a core dump. This macro should be employed
only if WIFSIGNALED returned true.
This macro is not specified in POSIX.1-2001 and is not available on some UNIX
implementations (e.g., AIX, SunOS). Therefore, enclose its use inside #ifdef
WCOREDUMP ... #endif.
WIFSTOPPED(wstatus)
returns true if the child process was stopped by delivery of a signal; this is
possible only if the call was done using WUNTRACED or when the child is being
traced (see ptrace(2)).
WSTOPSIG(wstatus)
returns the number of the signal which caused the child to stop. This macro
should be employed only if WIFSTOPPED returned true.
WIFCONTINUED(wstatus)
(since Linux 2.6.10) returns true if the child process was resumed by delivery of
SIGCONT.

Related

How to execute a linux terminal command from LUAJ?

I want to simply execute a linux terminal command like ls from LuaJ and the result that it will return or anything that returns i want to receive it and will show the names in the Java Gui. I searched but found this but not one with LuaJ.
Is there any function to execute the terminal command from LuaJ ??
There are multiple ways to do this, for one, you can implement it yourself in Java then link it to LuaJ.
LuaFunction command = new OneArgFunction()
{
public LuaValue call(LuaValue cmd)
{
Process p = Runtime.getRuntime().exec("/bin/sh", "-c", cmd.checkstring());
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
int returnCode = p.waitFor();
return LuaValue.valueOf(returnCode);
}
}
globals.set("command", command);
Then in Lua:
local code = command("ls");
The problem with actually getting the output of a command is that you can't just have a fixall solution. For all the system knows you could be calling a program which runs for 2 hours generating constant output, which could be an issue, not to mention if the program requires input. If you know you're only going to use certain functions you can make a dirty version of above function to capture the output from the stream and return it all instead of the exit code, just don't use it on other processes that don't return quickly. The other alternative is to create a class that wraps the input and output streams from the process and return a coerced version of that class, and manage the input and output from lua.
Lua does have a function that's part of the OsLib called execute(), if execute doesn't exist in your current environment then in Java call:
globals.load(new OsLib());
Before loading the lua code. the os.execute() function returns the status code, and doesn't return the streams, so no way to get the output there. To get around this you can modify the command to pipe the output to a temp file and open it with the io library (new IoLib() if doesn't exist in current environment).
The other option is to use io.openProcess, which also executes the command and returns a file to read the output from.
Resources:
http://luaj.org/luaj/3.0/api/org/luaj/vm2/lib/OsLib.html
http://luaj.org/luaj/3.0/api/org/luaj/vm2/lib/IoLib.html

Java Processbuilder - Catching the exitvalue of another Script?

I try to run a python script in my java programm. What I want to do is to catch the exitValue of the python programm and write it via System.out.println out.
Here is the Python code:
import sys
import subprocess
print "hallo"
i = sys.argv[0]
path = "R:\\xxx\\xxx\\xxx\\read"
resultlist = []
if i == 0:
result = True
else:
result = False
resultlist.append(result)
resultlist.append(path)
sys.exit(resultlist)
The Processbuilder methods .waitFor() and .exitValue() just gives a 0 or a 1 out. So I cant use it.
Is there any possible way to catch the value/string of sys.exit(resultlist) from the python script in my java programm?
man 2 exit:
The function _exit() terminates the calling process "immediately". Any open file descriptors belonging to the process are closed; any children of the process
are inherited by process 1, init, and the process's parent is sent a SIGCHLD signal.
**The value status is returned to the parent process as the process's exit status, and can be collected using one of the wait(2) family of calls.**
You cannot return "complex values" with exit(2) (the syscall) to begin with. If python does that then fine, but it's a "trick". Don't rely on it.
What you want to do is print the output of your program to stdout and capture stdout. For this, use the Process's .getInputStream() and swallow it in, for instance, a ByteArrayOutputStream.
Since you use a ProcessBuilder, you can also use its .redirectOutput() method before executing the process. Since Java 7, it has quite a few options available.

Handling delayed execution of a program in java

I am running an .exe file from my program and it is taking certain time for the same.The output from this command is used in the following statements for further processing. The output is a boolean variable. But the program is returning false immediately, but in fact the command is still in execution and is taking certain time. Because of the false value the subsequent statements is throwing an error. How do i handle this situation.
The return_var = exec(pagecmd) is the executing statement.
boolean return_var = false;
if("true".equals(getConfig("splitmode", ""))){
System.out.println("Inside splitmode if**********************");
String pagecmd = command.replace("%", page);
pagecmd = pagecmd + " -p " + page;
File f = new File(swfFilePath);
System.out.println("The swffile inside splitmode block exists is -----"+f.exists());
System.out.println("The pagecmd is -----"+pagecmd);
if(!f.exists()){
return_var = exec(pagecmd);
System.out.println("The return_var inside splitmode is----"+return_var);
if(return_var) {
strResult=doc;
}else{
strResult = "Error converting document, make sure the conversion tool is installed and that correct user permissions are applied to the SWF Path directory" +
getDocUrl();
}
In conjuction with waitFor() suggested by Andreas, you may also need to use getInputStream of Process object returned by exec() to retrieve the data written by the program you are executing.
Assumed that you are finally using Runtime.exec() inside your exec() method, you can use the waitFor() method of the Process object which is returned from Runtime.exec() to wait until the execution has finished:
...
Process p = Runtime.getRuntime().exec(pagecmd);
int result = p.waitFor();
...
The return value from waitFor() is the exit code of the sub process.
If you actually need to read output from the sub process which the sub process is writing to its stderr or stdout channel, you need to use Process.getInputStream() (Note: not getOutputStream()) and Process.getErrorStream() and read the sub processes output from these streams. Then, check the return values from the stream's read() methods to check if the sub process has terminated (or at least closed its output streams) instead of using waitFor().
Also, for these kind of problems, you should consider using the Apache commons exec library.
Alternatively, you might want to check the ProcessBuilder class.

Lua / Java / LuaJ - Handling or Interrupting Infinite Loops and Threads

I'm using LuaJ to run user-created Lua scripts in Java. However, running a Lua script that never returns causes the Java thread to freeze. This also renders the thread uninterruptible. I run the Lua script with:
JsePlatform.standardGlobals().loadFile("badscript.lua").call();
badscript.lua contains while true do end.
I'd like to be able to automatically terminate scripts which are stuck in unyielding loops and also allow users to manually terminate their Lua scripts while they are running. I've read about debug.sethook and pcall, though I'm not sure how I'd properly use them for my purposes. I've also heard that sandboxing is a better alternative, though that's a bit out of my reach.
This question might also be extended to Java threads alone. I've not found any definitive information on interrupting Java threads stuck in a while (true);.
The online Lua demo was very promising, but it seems the detection and termination of "bad" scripts is done in the CGI script and not Lua. Would I be able to use Java to call a CGI script which in turn calls the Lua script? I'm not sure that would allow users to manually terminate their scripts, though. I lost the link for the Lua demo source code but I have it on hand. This is the magic line:
tee -a $LOG | (ulimit -t 1 ; $LUA demo.lua 2>&1 | head -c 8k)
Can someone point me in the right direction?
Some sources:
Embedded Lua - timing out rogue scripts (e.g. infinite loop) - an example anyone?
Prevent Lua infinite loop
Embedded Lua - timing out rogue scripts (e.g. infinite loop) - an example anyone?
How to interrupt the Thread when it is inside some loop doing long task?
Killing thread after some specified time limit in Java
I struggled with the same issue and after some digging through the debug library's implementation, I created a solution similar to the one proposed by David Lewis, but did so by providing my own DebugLibrary:
package org.luaj.vm2.lib;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Varargs;
public class CustomDebugLib extends DebugLib {
public boolean interrupted = false;
#Override
public void onInstruction(int pc, Varargs v, int top) {
if (interrupted) {
throw new ScriptInterruptException();
}
super.onInstruction(pc, v, top);
}
public static class ScriptInterruptException extends RuntimeException {}
}
Just execute your script from inside a new thread and set interrupted to true to stop the execution. The exception will be encapsulated as the cause of a LuaError when thrown.
There are problems, but this goes a long way towards answering your question.
The following proof-of-concept demonstrates a basic level of sandboxing and throttling of arbitrary user code. It runs ~250 instructions of poorly crafted 'user input' and then discards the coroutine. You could use a mechanism like the one in this answer to query Java and conditionally yield inside a hook function, instead of yielding every time.
SandboxTest.java:
public static void main(String[] args) {
Globals globals = JsePlatform.debugGlobals();
LuaValue chunk = globals.loadfile("res/test.lua");
chunk.call();
}
res/test.lua:
function sandbox(fn)
-- read script and set the environment
f = loadfile(fn, "t")
debug.setupvalue(f, 1, {print = print})
-- create a coroutine and have it yield every 50 instructions
local co = coroutine.create(f)
debug.sethook(co, coroutine.yield, "", 50)
-- demonstrate stepped execution, 5 'ticks'
for i = 1, 5 do
print("tick")
coroutine.resume(co)
end
end
sandbox("res/badfile.lua")
res/badfile.lua:
while 1 do
print("", "badfile")
end
Unfortunately, while the control flow works as intended, something in the way the 'abandoned' coroutine should get garbage collected is not working correctly. The corresponding LuaThread in Java hangs around forever in a wait loop, keeping the process alive. Details here:
How can I abandon a LuaJ coroutine LuaThread?
I've never used Luaj before, but could you not put your one line
JsePlatform.standardGlobals().loadFile("badscript.lua").call();
Into a new thread of its own, which you can then terminate from the main thread?
This would require you to make some sort of a supervisor thread (class) and pass any started scripts to it to supervise and eventually terminate if they don't terminate on their own.
EDIT: I've not found any way to safely terminate LuaJ's threads without modifying LuaJ itself. The following was what I came up with, though it doesn't work with LuaJ. However, it can be easily modified to do its job in pure Lua. I may be switching to a Python binding for Java since LuaJ threading is so problematic.
--- I came up with the following, but it doesn't work with LuaJ ---
Here is a possible solution. I register a hook with debug.sethook that gets triggered on "count" events (these events occur even in a while true do end). I also pass a custom "ScriptState" Java object I created which contains a boolean flag indicating whether the script should terminate or not. The Java object is queried in the Lua hook which will throw an error to close the script if the flag is set (edit: throwing an error doesn't actually terminate the script). The terminate flag may also be set from inside the Lua script.
If you wish to automatically terminate unyielding infinite loops, it's straightforward enough to implement a timer system which records the last time a call was made to the ScriptState, then automatically terminate the script if sufficient time passes without an API call (edit: this only works if the thread can be interrupted). If you want to kill infinite loops but not interrupt certain blocking operations, you can adjust the ScriptState object to include other state information that allows you to temporarily pause auto-termination, etc.
Here is my interpreter.lua which can be used to call another script and interrupt it if/when necessary. It makes calls to Java methods so it will not run without LuaJ (or some other Lua-Java library) unless it's modified (edit: again, it can be easily modified to work in pure Lua).
function hook_line(e)
if jthread:getDone() then
-- I saw someone else use error(), but an infinite loop still seems to evade it.
-- os.exit() seems to take care of it well.
os.exit()
end
end
function inithook()
-- the hook will run every 100 million instructions.
-- the time it takes for 100 million instructions to occur
-- is based on computer speed and the calling environment
debug.sethook(hook_line, "", 1e8)
local ret = dofile(jLuaScript)
debug.sethook()
return ret
end
args = { ... }
if jthread == nil then
error("jthread object is nil. Please set it in the Java environment.",2)
elseif jLuaScript == nil then
error("jLuaScript not set. Please set it in the Java environment.",2)
else
local x,y = xpcall(inithook, debug.traceback)
end
Here's the ScriptState class that stores the flag and a main() to demonstrate:
public class ScriptState {
private AtomicBoolean isDone = new AtomicBoolean(true);
public boolean getDone() { return isDone.get(); }
public void setDone(boolean v) { isDone.set(v); }
public static void main(String[] args) {
Thread t = new Thread() {
public void run() {
System.out.println("J: Lua script started.");
ScriptState s = new ScriptState();
Globals g = JsePlatform.debugGlobals();
g.set("jLuaScript", "res/main.lua");
g.set("jthread", CoerceJavaToLua.coerce(s));
try {
g.loadFile("res/_interpreter.lua").call();
} catch (Exception e) {
System.err.println("There was a Lua error!");
e.printStackTrace();
}
}
};
t.start();
try { t.join(); } catch (Exception e) { System.err.println("Error waiting for thread"); }
System.out.println("J: End main");
}
}
res/main.lua contains the target Lua code to be run. Use environment variables or parameters to pass additional information to the script as usual. Remember to use JsePlatform.debugGlobals() instead of JsePlatform.standardGlobals() if you want to use the debug library in Lua.
EDIT: I just noticed that os.exit() not only terminates the Lua script but also the calling process. It seems to be the equivalent of System.exit(). error() will throw an error but will not cause the Lua script to terminate. I'm trying to find a solution for this now.
Thanks to #Seldon for suggesting the use of custom DebugLib. I implemented a simplified version of that by just checking before every instruction if a predefined amount of time is elapsed. This is of course not super accurate because there is some time between class creation and script execution. Requires no separate threads.
class DebugLibWithTimeout(
timeout: Duration,
) : DebugLib() {
private val timeoutOn = Instant.now() + timeout
override fun onInstruction(pc: Int, v: Varargs, top: Int) {
val timeoutElapsed = Instant.now() > timeoutOn
if (timeoutElapsed)
throw Exception("Timeout")
super.onInstruction(pc, v, top)
}
}
Important note: if you sandbox an untrusted script calling load function on Lua-code and passing a separate environment to it, this will not work. onInstruction() seems to be called only if the function environment is a reference to _G. I dealt with that by stripping everything from _G and then adding whitelisted items back.
-- whitelisted items
local sandbox_globals = {
print = print
}
local original_globals = {}
for key, value in pairs(_G) do
original_globals[key] = value
end
local sandbox_env = _G
-- Remove everything from _G
for key, _ in pairs(sandbox_env) do
sandbox_env[key] = nil
end
-- Add whitelisted items back.
-- Global pairs-function cannot be used now.
for key, value in original_globals.pairs(sandbox_globals) do
sandbox_env[key] = value
end
local function run_user_script(script)
local script_function, message = original_globals.load(script, nil, 't', sandbox_env)
if not script_function then
return false, message
end
return pcall(script_function)
end

Return value from a Java code

There is a Java class which creates a POST request and sends it to a servlet.
The main method of the class file (test) looks something like this:
public static void main(String[] args) throws IOException {
// Code logic goes here...
// No return Statement
}
This is called from a KornShell (ksh) script something like this:
retcode=`$CLK_JAVA_PATH -cp $CLASSPATH test ${PASSWORD} ${HOSTNAME} ${TOOLSET}`
if [ $? != "0" ];then
echo "ERROR:
echo "${retcode}"
else
echo "${SCRIPT} Success"
fi
retcode always has the value "2" independent of if the code fails or succeeds.
My question is since the return type of my main method is "void" why is the code returning some value?
The return value of a Java application is not the return value of it's main method, because a Java application doesn't necessarily end when it's main method has finished execution.
Instead the JVM ends when no more non-daemon threads are running or when System.exit() is called.
And System.exit() is also the only way to specify the return value: the argument passed to System.exit() will be used as the return value of the JVM process on most OS.
So ending your main() method with this:
System.exit(0);
will ensure two things:
that your Java application really exits when the end of main is reached and
that the return value of the JVM process is 0
Java programs do not return an exit code back to the operating system by returning a value from main, as is done in C and C++. You can exit the program and specify the exit code by calling System.exit(code);, for example:
// Returns exit code 2 to the operating system
System.exit(2);
System.exit(0);
This returns error code 0 (everything went fine).
System.exit Doc
Use
System.exit( someNumber );
this will give your app control over the return value seen by the OS.
Your program always returns a return code after exiting. In normal programs, if you do not specify a return code, it will return zero (this includes setting the return type to void).
Java, however, likes to be special! Java won't return the return code you return at the Main method, but it'll return some return code when the JVM exits (this accounts for multithreaded programs), and will return what a System.Exit(returnCode); call specifies.
You're not getting the exit status, that's what $? contains. You're getting standard out, whatever is written to System.out.

Categories