I would like to have a small \"application loader\" program that receives other binary application files over TCP from an external server and runs them.
I could do
Short answer: no.
Long answer: It's possible but rather tricky to do this without writing it out to disk. You can theoretically write your own elf loader that reads the binary, maps some memory, handles the dynamic linking as required, and then transfers control but that's an awful lot of work, that's hardly ever going to be worth the effort.
The next best solution is to write it to disk and call unlink ASAP. The disk doesn't even have to be "real" disk, it can be tmpfs or similar.
The alternative I've been using recently is to not pass complete compiled binaries around, but to pass LLVM bytecode instead, which can then be JIT'd/interpreted/saved as fit. This also has the advantage of making your application work in heterogeneous environments.
It may be tempting to try a combination of fmemopen
, fileno
and fexecve
, but this won't work for two reasons:
From fexecve()
manpage:
"The file descriptor fd must be opened read-only, and the caller must have permission to execute the file that it refers to"
I.e. it needs to be a fd that refers to a file.
From fmemopen()
manpage:
"There is no file descriptor associated with the file stream returned by these functions (i.e.,
fileno(3)
will return an error if called on the returned stream)"
You might want to look at and reuse UPX, which decompresses the executable to memory, and then transfers control to ld-linux
to start it.
Much easier than doing it is C would just to set up a tmpfs file system. You'd have all the advantages of the interface of a harddisk, from your program / server / whatever you could just do an exec
. These types of virtual filesystems are quite efficient nowadays, there would be really just one copy of the executable in the page cache.
As Andy points out, for such scheme to be efficient you'd have to ensure that you don't use buffered writes to the file but that you "write" (in a broader sense) directly in place.
ftruncate
mmap
to obtain the addr of a bufferrecv
call to write the data in placemunmap
the fileexec
with the filerm
the file. can be done even when the executable is still running