I don't want to use system() in my C program, because system(3) blocks and this is not what I want. What is the optimal way to do it?
I think that a quick and dirty action is to call sytem(command &). the & will spawn the new process.
Use fork() to create a new process and then use system() (or any exec function) in it. The original process will then be able to continue executing.
The answer depends on what your real goal is. You don't say what platform you're on, and I know very little about Windows, so this only covers your options on linux/unix.
You just want to spawn another program, and don't need to interact with it. In this case, call fork(), and then in the child process run execve() (or related function).
You want to interact with another program. In this case, use popen().
You want part of your program to run as a subprocess. In this case, use fork(), and call whatever functions you need to run in the child.
You need to interact with part of your program running as a subprocess. Call pipe() so you have a file descriptor to communicate through, then call fork() and use the file descriptor pair to communicate. Alternatively, you could communicate through a socket, message queue, shared memory, etc.
You might want to use popen. It creates new processes and allows you to redirect the process output to your own process.
If in windows, use the ShellExecute() function from the Windows API.
If in Unix, go for fork() then system() as mentioned.
Related
Is there a way to start a child process without fork(), using execvp() exclusively?
The pedantic answer to your question is no. The only system call that creates a new process is fork. The system call underlying execvp (called execve) loads a new program into an existing process, which is a different thing.
Some species of Unix have additional system calls besides fork (e.g. vfork, rfork, clone) that create a new process, but they are only small variations on fork itself, and none of them are part of the POSIX standard that specifies the functionality you can count on on anything that calls itself a Unix.
The slightly more helpful answer is that you might be looking for posix_spawn, which is a library routine wrapping fork and exec into a single operation, but I find it more troublesome to use that correctly than to write my own fork+exec subroutine. YMMV.
posix_spawn is the only posix compliant way to create a child process without calling fork directly. I say 'directly' because historically posix_spawn would itself just call fork, or vfork. However, that is no longer the case in GNU/linux. posix_spawn itself may be more efficient than fork, in addition to perhaps being a stronger fit conceptually when code is attempting to run a different executable.
If you aren't worried about portability, you can abandon posix and couple yourself directly to the kernel you are targeting. On linux the system call to create a child process is clone. At the time of this answer the manual page provides documentation for three variants, including the relatively new clone3.
I believe you can take the example from the manual page and add an execvp call to childFunc. I have not tried it yet, though!
Unlike Windows systems, where creating a new process and executing a new process image happen in a single step, Linux and other UNIX-like systems do them as two distinct steps.
The fork function makes an exact duplicate of the calling process and actually returns twice, once to the parent process and once to the child process. The execvp function (and other functions in the exec family) executes a new process image in the same process, overwriting the existing process image.
You can call execvp without calling fork first. If so, that just means the currently running program goes away and is replaced with the given program. However, fork is the way to create a new process.
As user zwol has already explained, execve() does not fork a new process. Rather, it replaces the address space and CPU state of current process,
loads the new address space from the executable filename and starts it from
main() with argument list argv and environment variable list envp.
It keeps pid and open files.
int execve(const char *filename,char *const argv [],char *const envp[]);
filename: name of executable file to run
argv: Command line arguments
envp: environment variable settings (e.g., $PATH, $HOME, etc.)
posix_spawn. But it ignores failures of execvp() -- potentially because implementing this was regarded as too complicated.
I would like to know if there is any good way to execute an external command in Linux environment using C language without using system(), popen(), fork(), exec()?
The reason I cannot use these functions is that my main application has used up most of the system resources (i.e memory) in my embedded board. If I do a fork, the board won't be able to create a duplicate of my main application. From I read in a book, both system() and popen() actually using fork() underneath, so I cannot use them either.
The only idea I currently have is create a process before I run my main application and use IPC(pipe or socket) to let the new process know what external commands it needs to run with system() or popen() and return the results back to my application when it is done.
You cannot do this. Linux create new process by sequential call to fork() and exec(). No other way of process creation exists.
But fork() itself is quite efficient. It uses Copy-on-Write for child process, so fork() not copy memory until it is really needed. So, if you call exec() right after fork() your system won't eat too much memory.
UPD. I lie to you saying about process creation. In fact, there is clone() call which fork() uses internally. This call provides more control over process creation, but it can be complicated to use. Read man 2 fork and man 2 clone for more information.
I am using a system() to call an executable program(A server) . Now after a certain time I want to terminate this program from my c program itself. Does anyone know how to do this?
OS running:(http://rcn-ee.net/deb/rootfs/precise/ubuntu-12.04-r4-minimal-armhf-2012-07-16.tar.xz)
The best way to do this is to use a function that gives you more control over the resulting process than system() does. However, this would be platform specific.
For Windows, use CreateProcess() which returns a HANDLE which you can use later in TerminateProcess() to kill the process.
For Unix, use fork() and exec() which gives you the pid of the child process, which you can use later in kill() to kill the process.
Just wondering how if it's possible to execute another program in a thread and send information to/get information from it. Essentially the same concept as with a child process and using pipes to communicate - however I don't want to use fork.
I can't seem to find whether it's possible to do this, any help would be appreciated.
Thanks
You cannot use the exec family of functions to load another executable file within a thread; the exec functions replace the entire process with the process started from the executable. Thus fork() is necessary if you want your original process to keep running.
In theory you could replicate most of the behaviour of the exec system call in userspace, and run an executable within a thread - but as the thread would share the open file table, signal handlers and so on with the rest of the process, it would likely destructively interfere with the main process. It would also be a lot of work.
If you're not using fork (directly or indirectly), then it's not really another process. Of course, you can communicate between threads within a process. That's essential to most multithreading.
CreateProcess() came up a few times searching google....
Is it OK to assume this is the safest and most efficient method?
If so, I would like to use the output of the called process.
How do I know it has completed before continuing on in the C program?
Thanks.
ShellExecute Can be used to create a process, its a more convenient way to pass arguments.
But if you want to use the output of the process then CreateProcess is probably your best bet
With CreateProcess you can pass a STARTUPINFO structure that can be used to pass a file pipe handle to Standard Out of the process.
CreateProcess will return a PROCESS_INFORMATION structure containing a HANDLE to the created process. That handle will become signalled when the process exits.
So You can WaitForSingleObject on the process handle to wait for the output to be complete.
Don't forget to CloseHandle on the process handle and thread handle when you are done.
Depends on how you measure efficiency. system() is programmer efficient.
Also see exec() and its many brothers.
CreateProcess() is a fairly low-level function for spawning subprocesses and may not be the most convenient option. For a C program where you need to read the output, consider popen() (note that the MS CRT places an underscore before its name):
FILE *f = _popen("dir", "r");
char buf[1000];
while (fgets(buf, sizeof(buf), f)) {
// .. process output using stdio functions
}
_pclose(f);
The classic source for how to execute a Windows program and catch its output is this article on MSDN - it's actually not as complicated as it looks.
If you need full control (change std in/out etc), CreateProcess is your best option. If you are executing something specified by the user, you really need to use ShellExecute[Ex] since CreateProcess will fail for applications that require UAC elevation (ShellExecuteEx is also able to give you a handle to the child process when you start applications)