Advertisement

Executing remote programs using C

Started by January 05, 2005 06:03 PM
13 comments, last by Winograd 19 years, 10 months ago
I made a level editor for my game but it's a seperate program from my game. I have a menu option in my game to choose the level editor but I don't know how I can execute it from my game.
Try eighter the ANSI C system() or Unix exec() family of functions, depending on your needs. Perhaps coupled with a fork() call to keep the original process running.
There's a few other things you might need to take care of too. Like SIGHUP handling if you want the child to outlive the parent, and catching SIGCHLD to avoid leaving zombie processes.
The Unix programming FAQ should cover any remaining details on how to do this properly.
Advertisement
The thing is I want the original process to exit. As I'm looking at the man page for exec and it seems to be describing what I wan't. This bring up new questions, first, what would be the equivalent of exec in windows? and secons, how can I tell if my program is running of a windows maching or *nix machine?
Quote: Original post by subflood
The thing is I want the original process to exit. As I'm looking at the man page for exec and it seems to be describing what I wan't. This bring up new questions, first, what would be the equivalent of exec in windows? and secons, how can I tell if my program is running of a windows maching or *nix machine?

Exiting the original process is easy - just don't fork() before exec() and the original process will be taken over by the new one. Make sure you don't leave any open files (or any other inheritable resources) hanging around though.
In Win32 you'd use CreateProcess() instead. And provide a preprocessor define at compile time to detect which environment you're in (WIN32 seems to be automatically defined on most compilers).

#ifdef WIN32 /* windows? */CreateProcess(..);#else /* posix? */execve(..);#endif 
Thank you.
doynax: Are you sure that using exec causes the original program to exit?

I doubt that.. say your program has opened few windows and you use exec to launch a child process. Your original program just stops responding if it does not use threads or you have not forked a new process. Windows don't disappear.. of course you could close them first, but bottom line is that the original process does not exit. Is that even possible?

Shouldn't child process belong to a parent process? Is it so that exiting parent process without handling the child process causes the child to turn to a zombie process or does this happen only when child exits and parent does not handle the signal? Perhaps exiting parent process transfers the "parenthood" to the parent of the killed process.. I might be wrong though..
Advertisement
Quote: Original post by Winograd
doynax: Are you sure that using exec causes the original program to exit?

I doubt that.. say your program has opened few windows and you use exec to launch a child process. Your original program just stops responding if it does not use threads or you have not forked a new process. Windows don't disappear.. of course you could close them first, but bottom line is that the original process does not exit. Is that even possible?

There's no need to fork() off a new process since subflood wanted to original process to disappear.
And, no, exec() doesn't make the original process disappear. It does something better instead - it replaces the original process.
As I said earlier, you still have to close any remaining resources. But that's mostly files really, since just about everything is a file in Unix. For example you interface with X-Windows through TCP which is a socket which is a file.
Not that I advocate the "loop through all possible file descriptors and close them" approach, let your program exit normally instead. Bad things would happen whenever you encounter an alternative interface, like svgalib (I think later versions have some kind of workaround for this, but that's not the point).

Quote: Original post by Winograd
Shouldn't child process belong to a parent process? Is it so that exiting parent process without handling the child process causes the child to turn to a zombie process or does this happen only when child exits and parent does not handle the signal? Perhaps exiting parent process transfers the "parenthood" to the parent of the killed process.. I might be wrong though..

The default action of a child process when a parent disappears is to exit, but this is sane thing to do in most cases. However if a parent doesn't read a child's exit code (through wait()) the child process will remain in the system as a zombie. None of this is a problem if you want to replace the original process though.

Overall I find the Unix process system to be one of the beautiful APIs designed to date. It's primary power lies in allowing you to use independent processes where other systems would need threads.

[Edited by - doynax on January 6, 2005 8:06:00 AM]
With Win32 you will need to exit the current process, after you have created the new process, which you can do with ExitProcess, which will shutdown all your windows and threads created automatically. However, this is messy, so do a proper shutdown first.

eg.

MyShutdownFunc();
CreateProcess( ... );
ExitProcess(0);
Quote: Original post by doynax
And, no, exec() doesn't make the original process disappear. It does something better instead - it replaces the original process.


Ah.. I see (it would have been smart to read the man pages carefully first :)).. rating up if I can..
This is a bit of topic, but because you (doynax) seem to have pretty good knowledge on the exec area, tell me..
When the process image is replaced by a new one, does the new process inherit the file descriptors? Probably not...

and another one..
Is the new process and it's data and bss sections allocated to the same pages than the old process? I mean that if the old process had written something to address x and the new process has not overwritten it yet, then can it be recovered by the new process? This is probably highly dependant on the implementation of the exec family functions (and/or kernel)... but let's say we are on gnu/linux 2.6, an we have sufficiently new glibc (>=2.3)..
Quote: Original post by Winograd
Ah.. I see (it would have been smart to read the man pages carefully first :)).. rating up if I can..
This is a bit of topic, but because you (doynax) seem to have pretty good knowledge on the exec area, tell me..
When the process image is replaced by a new one, does the new process inherit the file descriptors? Probably not...
It does, this is actually a popular method of communication with child processes.
Before you fork() you can create a pipe() and afterwards replace a known file descriptor (probably 0, 1, 2 - stdin/out/err respectively) for the child process.

Here's a short example without error or zombie handling.
int spawn(const char *cmd) {	int fds[2];	pipe(fds);	if(!fork()) { /* child? */		/* replace stdin with the input end of the pipe */		dup2(fds[0], 0);		close(fds[0]);		close(fds[1]);		execl(cmd, cmd);	}	/* parent? */	close(fds[0]);	/* return a file descriptor for sending data to the child process */	return fds[1];}

Neat, eh? =)
Quote: Original post by Winograd
Is the new process and it's data and bss sections allocated to the same pages than the old process? I mean that if the old process had written something to address x and the new process has not overwritten it yet, then can it be recovered by the new process? This is probably highly dependant on the implementation of the exec family functions (and/or kernel)... but let's say we are on gnu/linux 2.6, an we have sufficiently new glibc (>=2.3)..
No, you normally don't get to keep the memory contents. However you can flag a memory area as inheritable when allocating it (specify MAP_INHERIT to mmap() calls).

This topic is closed to new replies.

Advertisement