As Vasily Starynkevich answered , this is impossible.
However, a very simple and common solution is used for this, which does not depend on Linux behavior or control of excessive memory load: use an early forked subordinate process, do fork and exec.
Ask the large parent process to create a Unix domain socket and fork the slave process as early as possible by closing all other descriptors in the slave (reopening STDIN_FILENO , STDOUT_FILENO and STDERR_FILENO in /dev/null ). I prefer the datagram socket for its simplicity and guarantee, although the stream socket will also work.
In some rare cases, it is useful for the slave process to execute a separate, dedicated, small helper program. In most cases, this is not necessary and greatly simplifies security design. (On Linux, you can enable SCM_CREDENTIALS helper messages when transferring data through a Unix domain socket and use the process ID in it to verify the identity / executable file that uses the peer /proc/PID/exe pseudo- /proc/PID/exe /proc/PID/exe .)
In any case, the slave process will block reading from the socket. When the other end closes the socket, read / receive will return 0, and the slave process will end.
Each datagram that a subordinate process receives describes a command to execute. (Using a datagram allows you to use C strings separated by NUL characters without escaping, etc.; to use a Unix streaming socket, you usually need to delimit the βcommandβ somehow, which in turn means escaping the delimiters in the strings of the command components.)
The slave process creates one or more channels and branches the child process. This child process closes the original Unix socket, replaces the standard threads with the corresponding ends of the channel (closing the other ends), and executes the required command. I personally prefer to use the optional close-on-exec socket on Linux to detect successful execution; in the event of an error, the errno code is written to the socket, so that the subordinate parent can reliably detect the failure and the exact cause. If successful, the subordinate parent closes the unnecessary ends of the channel, responds to the original process on successful completion, and the other end of the channel is SCM_RIGHTS auxiliary data. After sending a message, it closes the rest of the channel and waits for a new message.
On the side of the original process, the above process is sequential; only one thread can start an external process at a time. (You simply serialize access using the mutex.) Several may work simultaneously; this is just a request and response from a helper assistant that is serialized.
If this is a problem - it should not be in typical cases - you can, for example, multiplex connections by adding an ID prefix to each message (assigned by the parent process, monotonically increasing). In this case, you are likely to use a dedicated stream at the parent end to control communication with the slave, because you certainly cannot have multiple threads reading from the same socket at the same time and expect deterministic results.
Further circuit enhancements include things like using a dedicated process group for running processes, setting limits for them (by setting limits for a slave process), and executing commands as dedicated users and groups using a privileged slave.
In the case of a privileged slave, it is most useful for the parent node to perform a separate auxiliary process for it. On Linux, both parties can use SCM_CREDENTIALS helper messages via Unix domain sockets to verify the identity (PID and ID, executable file) of the peer, which makes it fairly simple to implement reliable security. (But note that /proc/PID/exe needs to be checked more than once to track attacks when a message is sent by a malicious program that quickly executes the corresponding program, but with command line arguments that lead to its quick completion, from time to time making it similar to the correct executable file that made the request, while a copy of the descriptor - and therefore the entire communication channel - was under the control of an unreliable user.)
Thus, the original problem can be solved, although the answer to the question is no. If executions are security sensitive, such as changing privileges (user accounts) or features (on Linux), then the project should be carefully thought out. considered, but in normal cases, the implementation is quite simple.
I would be happy to develop if necessary.