Greetings, I'm having a number of issues with launchd, particularly under Leopard. (Most, if not all, of this works just fine under Tiger.) My current, and most pressing issue, is trying to replace a daemon when the user upgrades their software. Here's what I've got running - A daemon is installed in /Library/LaunchDaemons/QRecallScheduler501.plist. I install the file by writing the plist then executing 'launchctl load /path-to-plist' as root. The .plist file has the UserName property set to an individual user. This has been working (mostly) until I need to upgrade the user's software. I've tried various techniques, but the one I'm using now which I think should work doesn't. Setup (if this makes any difference): The path to the daemon is a symbolic link to the actual binary in my application bundle. When the application is upgraded (via Sparkle), the application bundle is replaced with the new application bundle containing an updated daemon. Step #1: Run 'launchctl unload -w /path-to-plist' as root. I wait for launchctl to return and then wait for the daemon to terminate. Step #2: Delete the .plist at /Library/LaunchDaemons/QRecallScheduler501.plist. Step #3: Write a new .plist at /Library/LaunchDaemons/QRecallScheduler501.plist Step #4: Run 'launchctl load /path-to-plist' as root. Wait for launchctl to finish. Here's what happens: In step #1, launchctl returns with a status of 0. The daemon receives a SIGTERM and shuts down (2-3 seconds). IMMEDIATELY, launchd starts the new deamon. I can only assume because the location of the updated binary is the same as the old one that was just terminated. Steps #2 and #3 delete and rewrite the .plist. Step #4 runs 'launchctl load' which returns with a status of 0. What I get in the console log is 11/28/07 4:09:44 PM [0x0-0x1e01e].com.qrecall.client[145] launchctl: Error unloading: com.qrecall.scheduler 11/28/07 4:09:56 PM com.apple.launchd[62] (com.qrecall.scheduler.501) Ignored this key: UserName Contrary to the second error, the daemon is run with a UID of 501 (which is correct -- the daemon will terminate if it's started as root). The new daemon is then repeatedly restarted. (The daemon checks for a duplicate running instance of itself and terminates immediately if it's already running.) 11/28/07 4:09:57 PM com.apple.launchd[62] (com.qrecall.scheduler.501) Throttling respawn: Will start in 10 seconds 11/28/07 4:10:07 PM com.apple.launchd[62] (com.qrecall.scheduler.501) Throttling respawn: Will start in 10 seconds 11/28/07 4:10:17 PM com.apple.launchd[62] (com.qrecall.scheduler.501) Throttling respawn: Will start in 10 seconds 11/28/07 4:10:27 PM com.apple.launchd[62] (com.qrecall.scheduler.501) Throttling respawn: Will start in 10 seconds The really bad part is the instance of the daemon that is running does not seem to be running in the correct environment/namespace. When it launches a sub-process it attempts to connect with it using Mach ports; The connection fails. Restarting the OS doesn't fix the problem. I think the problem is that (in Leopard) there seems to be two instances of launchd running: One as root and one as user 501. But I'm getting very confused as to which one I should be trying to deal with. I changed the code to call launchctl while running as user 501. That sometimes works and sometimes doesn't. If I can get the daemon to stop and issue 'launchctl load /...' as user 501, the daemon starts working: specifically, it can communication with the sub-processes that it starts. Once started using 'launchctl' as user 501 it can be stopped again using launchctl as 501. But after a restart, it's running in the wrong namespace again and I have to perform a 'sudo launchctl unload' to get it to stop. So after an entire day, I'm really confused as to what launchctl commands I should be issuing to replace a running deamon, in what order, and using what UID. James -- James Bucanek