Reputation: 509
On Windows in C#, I can launch an external program from within my code by calling Process.Start()
, which starts the process and returns its ID. This is important because I am not forking my own process, and I might have to kill the process later.
I have looked at exec()
, fork()
and many other things under Linux in C++ but none of those do quite the same thing. For example, system()
blocks while the program runs, and fork()
duplicates my whole process just so I can run another task.
Can someone tell me what the equivalent is?
Upvotes: 0
Views: 1162
Reputation: 31447
The way to start a new process on Linux is by using fork
and exec
. This you can wrap in your own System
class that holds the PID and provides methods to kill the process etc. An example of such a class is QProcess
from the Qt library.
Note: there's also the posix_spawn() and (Linux specific) clone() functions.
Upvotes: 1
Reputation: 509
Thanks to @user4581301 for the comment above. posix_spawn()
was what I was looking for.
Here is the code I ended up using though.
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
class ProcessCancelHelper {
private:
pid_t process_id_;
public:
ProcessCancelHelper()
: process_id_(0) {}
int StartProcess(const char* command_buffer) {
const char* command_argv[4];
command_argv[0] = "sh";
command_argv[1] = "-c";
command_argv[2] = command_buffer;
command_argv[3] = nullptr;
process_id_ = fork();
if (process_id_ == -1) return -1;
if (process_id_ == 0) {
execvp(command_argv[0], const_cast<char* const*>(command_argv));
assert(false && "execvp did not work");
exit(-1);
}
int wait_status;
if (waitpid(process_id_, &wait_status, 0))
{
process_id_ = 0;
if (WIFEXITED(wait_status)) return (WEXITSTATUS(wait_status));
return -1;
}
process_id_ = 0;
return -1;
}
bool CancelProcess() {
return (process_id_ != 0 && kill(process_id_, SIGKILL) == 0);
}
}
This works and I have not yet tried switching to using posix_spawn
instead, but as discussed that is just a wrapper.
Upvotes: 0
Reputation: 3551
There is no equivalent. This is difference between Windows and Linux (and any other Unix-like system). In Unix-like system, new process is always started using fork() + exec()
. Higher level C library APIs like system()
use fork() + exec()
system calls under the hood, because there is absolutely no other way. But Windows always creates new process from scratch. But you should not be discouraged by the fact that fork()
creates copy of the current process. In fact it does it in a very specific way, so that actually almost nothing copied until write to memory occurs. And even in this case, only modified memory page is copied. Otherwise, creating new processes on Unix/Linux would be over-expensive (for example, assume a process which consumes 4GB of memory wants to execute some shell command). And in fact, exec()
does the job which CreateProcess()
does on Windows - assigns new executable image to process, re-initializes heap and stack.
Upvotes: 1