2

I am looking for a way to execute a Linux executable from a separate Linux Executable that was compiled from C or C++. However, I have looked at numerous Stack Overflow posts which all direct the user asking to use the system() function or a wrapper of the system function and I do not want a program that relies on the shell, because it could easily fall apart if it was transferred to a different operating system with a different shell.

In the post How do I execute an external program within C in Linux with arguments, the second answer states that execve() is a wrapper for the system() function, and this makes me wary of the other functions in the exec() family.

I have also looked at the following articles:

All help is appreciated!

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
ShortsKing
  • 47
  • 1
  • 8
  • 9
    "*execve() is a wrapper for the system function*". It's not the case. It's the other way around - `system` is a wrapper for `execve`. The [system manaul](https://man7.org/linux/man-pages/man3/system.3.html) gives that info: "*The system() library function uses fork(2) to create a child process that executes the shell command specified in command using execl(3)*". So using the `exec` functions might actually be what you need? – kaylum Mar 02 '22 at 00:31
  • `system` is really, really dumb. Many consider it to be a security hole because of how stupid it is. – user4581301 Mar 02 '22 at 00:34
  • 3
    The second answer doesn't say that `execve()` is a wrapper for the `system` function. It says `system` uses `exec*` functions. – David Schwartz Mar 02 '22 at 00:40
  • 1
    If you're worried about portability, then `system()` is the portable way to do the job; it is required by the Standard C library so, for most practical purposes, it will be available anywhere C is available. However, there are some security risks associated with it, and it doesn't necessarily handle all the scenarios you want. In that case, you almost invariably end up using `fork()` and the `exec()` family of functions, possibly with `pipe()` and `dup2()`, or maybe some more esoteric functions for handling pseudo-terminals (aka pseudo-ttys or ptys). – Jonathan Leffler Mar 02 '22 at 01:28
  • 4
    On POSIX systems, an alternative to the `fork()` and `exec*()` functions is the [`posix_spawn()`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_spawn.html) function and its relatives (findable from https://pubs.opengroup.org/onlinepubs/9699919799/toc.htm). – Jonathan Leffler Mar 02 '22 at 01:34

1 Answers1

3

execve() is not a wrapper for system(); it is a wrapper for the execve syscall itself.

execve() replaces the current process, so you’ll probably need to fork() and then execute execve() in the child process, thereby emulating the behaviour of system().

tjcaul
  • 383
  • 1
  • 9
  • when the current process is replaced, and the program executed by `execve()` finishes, is control return to the previous process, or is the process eliminated entirely? – ShortsKing Mar 02 '22 at 01:51
  • 2
    @ShortsKing, on success, `execve()` does not return. The binary executing in the calling process is completely replaced by the one designated by `execve()`'s arguments. Note also that it is more common to use one of the various other [exec-family functions](https://man7.org/linux/man-pages/man3/exec.3.html) than to use `execve()` directly. – John Bollinger Mar 02 '22 at 01:57
  • 1
    System call numbers are only meaningful for a specific OS _and architecture_ and the only time you should have to worry about the actual numbers is when you're adding new system calls to the kernel. Saying (#11) just confuses people. Please edit that out. – zwol Mar 02 '22 at 02:30
  • @zwol You're right; of course they're unhelpful. Thanks for pointing that out. I've been writing a lot of assembly recently, so the first thing I thought of when I saw `execve()` was "11". – tjcaul Mar 02 '22 at 02:44
  • 2
    Even in assembly you ought to be able to use the `SYS_*` constants from `sys/syscall.h`, can't you? – zwol Mar 02 '22 at 02:49
  • @zwol Yes, I can. I'm just learning, though, so it helps me to know the numbers so I can better understand the assembled binary. – tjcaul Mar 02 '22 at 02:50