{"id":245,"date":"2006-12-30T12:58:18","date_gmt":"2006-12-30T19:58:18","guid":{"rendered":"http:\/\/www.red-sweater.com\/blog\/245\/taming-launchd"},"modified":"2006-12-30T13:13:56","modified_gmt":"2006-12-30T20:13:56","slug":"taming-launchd","status":"publish","type":"post","link":"https:\/\/redsweater.com\/blog\/245\/taming-launchd","title":{"rendered":"Taming Launchd"},"content":{"rendered":"<p>Developers, and some power users who are reading this have probably heard of <a href=\"http:\/\/developer.apple.com\/macosx\/launchd.html\">launchd<\/a>. It&#8217;s Apple&#8217;s &#8220;mama process,&#8221; responsible for launching other processes at startup, login, at regular intervals, or on demand. If you open the Activity Monitor application, and view &#8220;All Processes, Hierarchically,&#8221; you&#8217;ll see that there are only two top-level processes: kernel_task, and launchd. The kernel sits there and does its thing, while launchd spawns all the other processes that make up your Macintosh computing experience.<\/p>\n<p>\nOne big benefit of launchd to end-users is that <em>most<\/em> of what gets launched can be easily examined by perusing the configuration files. Launchd looks in five well-defined locations for launchable items:\n<\/p>\n<p>\n\/System\/Library\/LaunchDaemons<br \/>\n\/System\/Library\/LaunchAgents<br \/>\n\/Library\/LaunchDaemons<br \/>\n\/Library\/LaunchAgents<br \/>\n~\/Library\/LaunchAgents\n<\/p>\n<p>\nSo all you have to do to get a feel for (most of) what launchd is up to is start poking around in those directories. For each independent &#8220;launch&#8221; that launchd controls, you&#8217;ll find a corresponding configuration property list file. For instance, you&#8217;re guaranteed to find a bunch of examples in \/System\/Library\/LaunchDaemons, and depending on which third-party packages you&#8217;ve installed, you might find things in other places, as well.\n<\/p>\n<p><h3>Launchd In Context: FTP<\/h3>\n<p>Take a quick look at <a href=\"file:\/\/localhost\/System\/Library\/LaunchDaemons\/ftp.plist\">ftp.plist<\/a>, one of the system launch daemons. Depending on how you&#8217;ve configured your system, you&#8217;ll either see that a &#8220;Disabled&#8221; key is present and set to &#8220;true,&#8221; or it is absent. This corresponds directly to the &#8220;FTP Access&#8221; item in the System Preference&#8217;s &#8220;Sharing&#8221; panel. Go ahead and toggle the setting in your preferences, and observe that the ftp.plist file is immediately updated to reflect the new setting. This tells launchd that it should no longer consider launching the ftp daemon when an incoming ftp connection is attempted.\n<\/p>\n<p>\nWhat constitutes an incoming ftp connection? Look further down the ftp.plist and you&#8217;ll find an entry with key name &#8220;SockServiceName&#8221; and a value of &#8220;ftp&#8221;. Launchd uses this name to lookup the socket port\/protocol information for the named service from \/etc\/services. In this case, when an incoming connection is attempted on port 21, launchd will, if this item is not disabled, launch the daemon at \/usr\/libexec\/ftpd, in order to handle the incoming connection. Groovy, huh? <a href=\"http:\/\/developer.apple.com\/documentation\/MacOSX\/Conceptual\/BPSystemStartup\/Articles\/LaunchOnDemandDaemons.html\">Read more<\/a> about network handlers and other on-demand daemons.\n<\/p>\n<p><h3>Boot-Time King<\/h3>\n<\/p>\n<p>\nI said above that these configuration files reveal &#8220;most of&#8221; what launchd is up to with regard to running things on your system. Because launchd can&#8217;t handle all types of configurations, and because its introduction has been sort of gently staged, it&#8217;s responsible for running a lot of the older mechanisms like \/etc\/rc, StartupItems, etc. This means that launchd is basically responsible for everything from when the kernel gets loaded on. That includes booting your Mac!\n<\/p>\n<p>\nThings have been in such flux over the past few years that it&#8217;s hard to keep a straight answer when it comes to exactly what takes place at boot time. Excellent overviews such as <a href=\"http:\/\/www.kernelthread.com\/mac\/osx\/arch_startup.html\">Mac OS X System Startup<\/a> by Amit Singh, or <a href=\"http:\/\/developer.apple.com\/documentation\/MacOSX\/Conceptual\/BPSystemStartup\/index.html\">The Boot Process<\/a> by Apple, are liable to become outdated as launchd continues to evolve.\n<\/p>\n<p>\nFortunately, the entire process is transparently observable, because launchd is <a href=\"http:\/\/launchd.macosforge.org\/\">open source<\/a>. If you&#8217;re ever in doubt about any nuance of the startup process, just look at the <a href=\"https:\/\/svn.macosforge.org\/projects\/launchd\/browser\/trunk\">source code<\/a>. The repository even contains the boot-time configuration file &#8220;\/etc\/rc&#8221;, and the source for antiques like SystemStarter. You can even check out how the boot process is going to look in <a href=\"https:\/\/svn.macosforge.org\/projects\/launchd\/browser\/branches\/Leopard\">Leopard<\/a>. (Note: free registration on macosforge.com required). I couldn&#8217;t figure out how to check out those repository URLs from the command-line, but I discovered an <a href=\"http:\/\/svn.macosforge.org\/repository\/launchd\/trunk\/\">alternate URL<\/a> that works, and doesn&#8217;t seem to require registration.\n<\/p>\n<p><h3>Editing Launchd Configuration Files<\/h3>\n<\/p>\n<p>\nIt won&#8217;t take you long to discover that the launchd configuration files, while elegant and modular, are a bit of a pain to read, let alone edit. Fortunately, a couple of third-party solutions exist to ease this task.\n<\/p>\n<p>\n<a href=\"https:\/\/sourceforge.net\/projects\/lingon\/\">Lingon<\/a>, by Peter Borg, is a very powerful editor which also serves as a sort of browser for all the existing configuration files on your Mac. You can selectively start or stop any existing configuration, and it takes care of asking you to authenticate for editing those system-owned files (after warning you profusely not to do so!). It even sports a &#8220;wizard&#8221; interface that asks in relatively plain English what it is you&#8217;re trying to accomplish, and guides you through the creation of <em>new<\/em>, custom launchd configurations.\n<\/p>\n<p>\nWhile Lingon is essentially easy to use, it has some rough edges which scream for refinement. I&#8217;d really like to see the application receive a UI overhaul. Lots of little awkward UI elements and poorly phrased dialog make it slightly less than a 100% success. But it sure beats editing in vi, or even Property List Editor.\n<\/p>\n<p>\nOne of Lingon&#8217;s nicest features is its &#8220;Expert&#8221; pane, which allows you to examine and edit the raw XML of a configuration at any time. This is so useful that I&#8217;d like to see if featured as a full-time view, perhaps in a hideable split view pane. It would be fun to be able to watch the changes live in the XML source while tweaking details in the UI. But Lingon is, in the spirit of launchd itself, open source. So any shortcomings that ultimately get me down can be remedied to my own (or your own) liking.\n<\/p>\n<p>\nApparently I wasn&#8217;t the only person to object slightly to the UI of Lingon. <a href=\"http:\/\/www.codepoetry.net\/products\/launchdeditor\">Launchd Editor<\/a> is a $5, closed-source alternative that bites off a much smaller feature set, while trying to improve on the UI of Lingon. It&#8217;s clear by observing some of the configuration panes that Launchd Editor was inspired by Lingon (or vice-versa, I&#8217;m not positive which came first, but I&#8217;d guess Lingon did). Some of the control layout is almost identical to Lingon, but touched up a bit in alignment and wording, mostly for the better.\n<\/p>\n<p>\nLaunchd Editor is limited by its adoption of a document-centric model, such that the user has to specifically locate and open a configuration file. It also lacks the start\/stop\/load features of Lingon. Overall I&#8217;d say it&#8217;s worth using Lingon in spite of its rough UI, but minimalists might prefer Launchd Editor.<\/p>\n<h3>Launchd For Developers<\/h3>\n<p>So far I&#8217;ve talked about how the system uses launchd for its services, and sort of alluded to the fact that you might come up with your own configurations to suit your personal needs. But developers should also take heed of launchd as a mechanism for automating tasks on behalf of users. One example of this is Noodlesoft&#8217;s <a href=\"http:\/\/www.noodlesoft.com\/hazel.html\">Hazel<\/a>, which uses launchd configuration rules to periodically check the status of &#8220;watched folders&#8221; and perform housekeeping tasks on them. By saving configurations to the user&#8217;s LaunchAgents folder, and then loading them with the <a href=\"file:\/\/localhost\/bin\/launchctl\">launchctl<\/a> command-line tool, it pushes off timing responsibility to launchd. Nifty!<\/p>\n<h3>Summary<\/h3>\n<p>Launchd is a super addition to Mac OS X, and a stellar example of Apple&#8217;s commitment to improving Unix for both end-user and architectural benefit. Hopefully if you hadn&#8217;t gotten a chance to take a close look at it before, you&#8217;ll be encouraged to do so after reading this article.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Developers, and some power users who are reading this have probably heard of launchd. It&#8217;s Apple&#8217;s &#8220;mama process,&#8221; responsible for launching other processes at startup, login, at regular intervals, or on demand. If you open the Activity Monitor application, and view &#8220;All Processes, Hierarchically,&#8221; you&#8217;ll see that there are only two top-level processes: kernel_task, and [&hellip;]<\/p>\n","protected":false},"author":10,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[14,21,20,15,23],"tags":[],"class_list":["post-245","post","type-post","status-publish","format-standard","hentry","category-apple","category-darwin","category-hacking","category-programming","category-software-reviews"],"_links":{"self":[{"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/posts\/245","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/users\/10"}],"replies":[{"embeddable":true,"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/comments?post=245"}],"version-history":[{"count":0,"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/posts\/245\/revisions"}],"wp:attachment":[{"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/media?parent=245"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/categories?post=245"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/tags?post=245"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}