YA daemon problem -- what was the idea?

  • While trying to get a daemon working (a tool that launches at startup
    and survives login/logout), we seem to have encountered the same
    problem as everyone else, in that our CFMessagePorts don't connect when
    launched at startup.

    Mike Vannorsdel posted that he "did some reimplementing  and have found
    a better solution," but since mamasam doesn't preserve email addresses,
    I'm forced to post here.

    What are some workarounds for communicating from a daemon process to
    other processes, especially ones launched by the user?

    Also, as an aside: Should I be calling daemon() in my main()?

    --
    Mel Walker <mwalker...>
  • On Tuesday, July 15, 2003, at 09:12, Mel Walker wrote:

    > While trying to get a daemon working (a tool that launches at startup
    > and survives login/logout), we seem to have encountered the same
    > problem as everyone else, in that our CFMessagePorts don't connect
    > when launched at startup.
    > [...]
    >
    > What are some workarounds for communicating from a daemon process to
    > other processes, especially ones launched by the user?

    The solution is quite simple, but so many people seem to have a mental
    block about it: the daemon should not be making connections to other
    processes (at least, non-boot proceses).  A daemon should sit quietly
    waiting for other processes to contact it.  These login-session
    processes should be making the connection to the daemon.

    > Also, as an aside: Should I be calling daemon() in my main()?

    Not if you want to use CoreFoundation or other higher-level frameworks.
      Only BSD/POSIX-only processes should be using daemon().

    Chris Kane
    CoreFoundation, Apple
  • On Tuesday, July 15, 2003, at 06:52  pm, Chris Kane wrote:

    > On Tuesday, July 15, 2003, at 09:12, Mel Walker wrote:
    >
    >> Also, as an aside: Should I be calling daemon() in my main()?
    >
    > Not if you want to use CoreFoundation or other higher-level
    > frameworks.  Only BSD/POSIX-only processes should be using daemon().

    Why shouldn't a process call daemon() if it's using the higher-level
    frameworks?  It seems like an odd restriction.  Does this also apply to
    processes that do similar things to the daemon() function (e.g. detach
    themselves from the terminal and fork() into the background)?

    Kind regards,

    Alastair.
  • On Tuesday, July 15, 2003, at 13:18, Alastair J.Houghton wrote:
    > On Tuesday, July 15, 2003, at 06:52  pm, Chris Kane wrote:
    >> On Tuesday, July 15, 2003, at 09:12, Mel Walker wrote:
    >>
    >>> Also, as an aside: Should I be calling daemon() in my main()?
    >>
    >> Not if you want to use CoreFoundation or other higher-level
    >> frameworks.  Only BSD/POSIX-only processes should be using daemon().
    >
    > Why shouldn't a process call daemon() if it's using the higher-level
    > frameworks?  It seems like an odd restriction.  Does this also apply
    > to processes that do similar things to the daemon() function (e.g.
    > detach themselves from the terminal and fork() into the background)?

    The restriction applies to any use of fork() which is not soon followed
    by an exec*(), not just daemon()'s use of fork().  You cannot reliably
    use higher-level API after a fork(), before the exec*() either.

    The issue stems from the fact that fork() does not replicate all a
    parent's state (such as some kernel resources) into the child, but it
    does replicate the memory and some resources.  Thus (1) libraries in
    the new process have not gone through their ordinary initialization
    steps in the new process, and (2) libraries' cached state or opened
    resources have now gone silently invalid underneath them, due to the
    fork() (for those things not replicated by fork()).  For example, calls
    to library functions may produce errors now where they weren't before
    the fork(), or crash, or silently misbehave, or whatever.

    I believe there is a Tech Note on this.  You need to exec*() after a
    fork() if you want to use APIs above the BSD/POSIX layer.  And POSIX
    itself, I believe I've been told, specifies only a small list of things
    that are guaranteed safe after fork().  [But in practice...]

    Chris Kane
    CoreFoundation, Apple