Solved jexec: Return values?

In the jexec man page I cannot find any information about what gets returned by jexec.

Can one depend on that jexec will pass the return value from the jailed process it spawns?
And, what will jexec return, if, for example, there is another error (like file not found, jail not running etc?) that prevents jexec from spawning the process?

This question is important for me because I (respective my script) need to reliably know what the programs I call via jexec return.
 
Can one depend on that jexec will pass the return value from the jailed process it spawns?
After jail_attach(2) jexec just does an execve(2), so I'm going to claim: Yes, you can.

And, what will jexec return, if, for example, there is another error (like file not found, jail not running etc?) that prevents jexec from spawning the process?
When that fails it'll exit with a status of 1.

jexec is a tiny program and its sources are very readable: https://github.com/freebsd/freebsd/blob/master/usr.sbin/jexec/jexec.c
 
Thank you, tobik@.

I asked because I thought that it should be part of man page what to expect as return value.
So I looked at the code (thanks for the link), and found this:

Code:
/* Run the specified command, or the shell */
if (argc > 1) {
  if (execvp(argv[1], argv + 1) < 0)
    err(1, "execvp: %s", argv[1]);
} else {
  if (!(shell = getenv("SHELL")))
    shell = _PATH_BSHELL;
  if (execlp(shell, shell, "-i", NULL) < 0)
    err(1, "execlp: %s", shell);
}
exit(0);
If return value <0 I get 1.
If any error happened on the side of jexec, I get 1 also.
Otherwise I get 0.

This means I could tell only that the exec actually happened and returned non-negative, if the return value is zero.
If it is nonzero (i.e. 1), I could not even be sure whether the exec actually happened.

I would have to devise some workaround to find out whether the process actually has been run, and if so, why it failed.
I am not so sure whether this is a good way to do error "communication".

So my idea:
In jexec.c there are exactly 12 error conditions that get passed (not counted the two ones regarding the spawn code).
All these are passed to the err() function with some clear-text message, but currently all return 1 instead of individual error codes.
Wouldn't it be better to use some contiguous error numbers like
Code:
#define ERR_ERRORDESCRIPTION -31311
#define ERR_OTHERERRORDESCRIPTION -31312
etc?

Then the return value of the child could be passed to the caller.
In case of an error the caller can check whether the error numbers indicate it was a jexec error or an error of the child.

(The chance that error codes are not unique between jexec and the child is quite small, so the risk of confusional problems is limited imho.)

What do you think?
 
If return value <0 I get 1.
If any error happened on the side of jexec, I get 1 also.
Otherwise I get 0.

This means I could tell only that the exec actually happened and returned non-negative, if the return value is zero.
If it is nonzero (i.e. 1), I could not even be sure whether the exec actually happened.
I don't think that exit(0) can ever be reached. If execvp succeeds than the other process is already running (execvp replaces jexec, the return value of execvp is not the exit status of the process it runs). If not then err(1, ...) is called and jexec immediately exits.
 
Hm you are right, I overlooked that detail from the execv manpage...
RETURN VALUES
As the execve() system call overlays the current process image with a new
process image the successful call has no process to return to.
Then this means that there is actually no return value?!?
respective that the return value is undefined?
 
When execve() succeeds it never returns because the currently running process has been replaced by another one. The next process's code then runs and eventually calls _exit() at some point in its execution and thus determines the exit status of the whole thing.
 
Ahh thats good!
Then I just need to take care that my scripts do not return 1 to make sure it was not jexec who returned.
Fine, problem solved.
 
Back
Top