Any caveats to using fork in a Foundation/CoreFoundation tool?

  • I have the need to launch a tool from my GUI application that needs
    to be in its own process group (i.e. the parent process should not be
    the GUI app which launched it, since it needs to outlive the parent
    process.)

    It will use CFMessagePort to communicate with the parent app.

    I seem to recall that using fork not followed immediately by exec was
    a bad idea for Foundation/CoreFoundation tools or applications, but
    at the moment I can't find those references in the archives.

    Is using fork (or daemon, as the case may be) at the top of main
    going to cause me grief when I want to later use Foundation or
    CoreFoundation services?

    Any other recommended approaches?

    Jim
  • Hi Jim,

    On Oct 25, 2007, at 9:45 AM, Jim Correia wrote:

    > I have the need to launch a tool from my GUI application that needs
    > to be in its own process group (i.e. the parent process should not
    > be the GUI app which launched it, since it needs to outlive the
    > parent process.)
    >
    > It will use CFMessagePort to communicate with the parent app.
    >
    > I seem to recall that using fork not followed immediately by exec
    > was a bad idea for Foundation/CoreFoundation tools or applications,
    > but at the moment I can't find those references in the archives.

    Perhaps these messages will be easier to find.

    > Is using fork (or daemon, as the case may be) at the top of main
    > going to cause me grief when I want to later use Foundation or
    > CoreFoundation services?

    Yes. :)

    > Any other recommended approaches?

    Using launchd or LaunchServices is really the way to go here; go ahead
    and use CFMessagePort for your IPC, but either use a launchd plist to
    start your non-GUI process on-demand, or have your GUI process use
    LaunchServices to fire it up.

    In order for all the CF/Foundation internals to be initialized
    properly, an exec() has to happen otherwise things won't work, or
    won't work the way you expect (especially Mach-based things, like
    CFMessagePort).

    The "Agents and Daemons" technote talks about using launchd:

    http://developer.apple.com/technotes/tn2005/tn2083.html

    Having LaunchServices is a way of asking someone else to do the launch
    for you.

    Either way, the non-GUI bits will wind up not being in the parent's
    process group.

    .chris

    --
    Chris Parker
    Cocoa Frameworks
    Apple Inc.
  • The forked app no longer has valid Mach ports to the Window Server and
    other various services (like, say, the pasteboard), so if you try to
    utilize any of these services, you'll fail right away and it's not
    likely to be graceful :) Basically, if you fork, you have to behave as
    if you're a command line app and stop using any high level services.

    Jim Correia wrote:
    > I have the need to launch a tool from my GUI application that needs to
    > be in its own process group (i.e. the parent process should not be the
    > GUI app which launched it, since it needs to outlive the parent process.)
    >
    > It will use CFMessagePort to communicate with the parent app.
    >
    > I seem to recall that using fork not followed immediately by exec was
    > a bad idea for Foundation/CoreFoundation tools or applications, but at
    > the moment I can't find those references in the archives.
    >
    > Is using fork (or daemon, as the case may be) at the top of main going
    > to cause me grief when I want to later use Foundation or
    > CoreFoundation services?
    >
    > Any other recommended approaches?
    >
    > Jim
  • On Oct 25, 2007, at 11:45 AM, Jim Correia wrote:

    > I have the need to launch a tool from my GUI application that needs
    > to be in its own process group (i.e. the parent process should not
    > be the GUI app which launched it, since it needs to outlive the
    > parent process.)
    >
    > It will use CFMessagePort to communicate with the parent app.
    >
    > I seem to recall that using fork not followed immediately by exec
    > was a bad idea for Foundation/CoreFoundation tools or applications,
    > but at the moment I can't find those references in the archives.
    >
    > Is using fork (or daemon, as the case may be) at the top of main
    > going to cause me grief when I want to later use Foundation or
    > CoreFoundation services?

    Yes, it will cause problems - basically, after a fork, you not
    suppose use anything above libSystem - according to POSIX, you're not
    even suppose to use anything except those that are listed as async
    signal handler safe (according to one web page "In the child, do not
    call any library functions after calling fork() and before calling
    exec(). One of the library functions might use a lock that was held
    in the parent at the time of the fork(). The child process may
    execute only Async-Signal-Safe operations until one of the exec()
    handlers is called").  So even malloc could be bad...

    So basically all of CoreFoundation is bad (check out the source for
    CFMachPort.c in the current CF source to see where it tries to
    gracefully handle this problem - with graceful meaning "print a
    meaningful message and exit" rather than "hang").

    >
    > Any other recommended approaches?

    I'd add a "magic flag" to the argv list - your tool will check that,
    and if missing, will fork and exec itself with that flag added (and
    then quit).  If it is present, then you are good to go...

    Glenn Andreas                      <gandreas...>
      <http://www.gandreas.com/> wicked fun!
    quadrium2 | build, mutate, evolve, animate  | images, textures,
    fractals, art
  • On Oct 25, 2007, at 1:12 PM, Chris Parker wrote:

    >> Any other recommended approaches?
    >
    > Using launchd or LaunchServices is really the way to go here; go
    > ahead and use CFMessagePort for your IPC, but either use a launchd
    > plist to start your non-GUI process on-demand, or have your GUI
    > process use LaunchServices to fire it up.

    I don't think launchd is the solution I want, since I really want to
    directly spawn the process, but then have it detach from the parent.
    (I seem to recall there being issues with per user agents on 10.4 as
    well.)

    Can I use LaunchServices to fire up the process if it is a non-GUI
    CoreServices type tool?

    When I tried that, LS returned -10822 - kLSServerCommunicationErr.

    Am I missing something?

    Thanks,
    Jim
previous month october 2007 next month
MTWTFSS
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
Go to today