Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a process on Mac OS using fork() and exec()

I am working on a relatively simple, independent "process starter" that I would like to get to work on Windows (XP, Vista, 7), Linux (Ubuntu 10.10) and especially Mac OS X (10.6). Linux and Windows basically work, but I'm having some trouble with the Mac version. I was hoping fork() and exec() functions would work the same way under Mac OS as they work in Linux. So my first question is:

  1. Should I use these to create a process on the Mac or are there any platform specific functions to be used?

My current code (which worked fine under Linux) to debug this looks something like this:

pid_t processId = 0;
if (processId = fork()) == 0)
{
    const char * tmpApplication = "/Path/to/TestApplication";

    int argc = 1;
    char * argv[argc + 1];

    argv[0] = tmpApplication;
    argv[1] = NULL;

    execv(tmpApplication, argv);
}else
{
    //[...]
}

Any idea if this could work under Mac OS X as well, because my child process is simply not being launched, while there are no errors that would come up.

Thank you!

like image 523
Chris Avatar asked Dec 01 '10 16:12

Chris


People also ask

Does fork () work on Mac?

Fork - a fast and friendly git client for Mac and Windows.

What does fork () and exec () functions do?

fork starts a new process which is a copy of the one that calls it, while exec replaces the current process image with another (different) one. Both parent and child processes are executed simultaneously in case of fork() while Control never returns to the original program unless there is an exec() error.

Does exec create a new process?

exec does not create a new process; it just changes the program file that an existing process is running. exec first wipes out the memory state of the calling process. It then goes to the filesystem to find the program file requested.

Why do we need separate fork () and exec () system calls instead of one combined system call that does both?

The main reason is likely that the separation of the fork() and exec() steps allows arbitrary setup of the child environment to be done using other system calls.


2 Answers

The following program, adapted from your code, works just fine for me under OS X:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>

int main (void) {
    pid_t processId;
    if ((processId = fork()) == 0) {
        char app[] = "/bin/echo";
        char * const argv[] = { app, "success", NULL };
        if (execv(app, argv) < 0) {
            perror("execv error");
        }
    } else if (processId < 0) {
        perror("fork error");
    } else {
        return EXIT_SUCCESS;
    }
    return EXIT_FAILURE;
}

I suggest you start with this simple fragment, and if it works keep adding things until you find what makes it break.

like image 198
Arkku Avatar answered Sep 27 '22 18:09

Arkku


Is TestApplication an actual executable, or an application bundle (.app)? You can only launch actual executables using functions like execv(). Usually the executable inside an application bundle can be found at ApplicationName.app/Contents/MacOS/ApplicationName.

like image 41
Justin Spahr-Summers Avatar answered Sep 27 '22 17:09

Justin Spahr-Summers