The solution uses the functionality of launchctl, combined with a Launch Agent to mimic the login hooks of old. For other solutions using the store of launchd, see this comparison.
The launch agent used here is located in /Library/LaunchAgents/:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>user.conf.launchd</string>
<key>Program</key>
<string>/Users/Shared/conflaunchd.sh</string>
<key>ProgramArguments</key>
<array>
<string>~/.conf.launchd</string>
</array>
<key>EnableGlobbing</key>
<true/>
<key>RunAtLoad</key>
<true/>
<key>LimitLoadToSessionType</key>
<array>
<string>Aqua</string>
<string>StandardIO</string>
</array>
</dict>
</plist>
One important thing is the RunAtLoad key so that the launch agent is executed at the earliest time possible.
The real work is done in the shell script /Users/Shared/conflaunchd.sh, which reads ~/.conf.launchd and feeds it to launchctl:
#! /bin/bash
#filename="$1"
filename="$HOME/.conf.launchd"
if [ ! -r "$filename" ]; then
exit
fi
eval $(/usr/libexec/path_helper -s)
while read line; do
# skip lines that only contain whitespace or a comment
if [ ! -n "$line" -o `expr "$line" : '#'` -gt 0 ]; then continue; fi
eval launchctl $line
done <"$filename"
exit 0
Notice the call of path_helper to get PATH set up right. Finally, ~/.conf.launchd looks like that
setenv PATH ~/Applications:"${PATH}"
setenv TEXINPUTS .:~/Documents/texmf//:
setenv BIBINPUTS .:~/Documents/texmf/bibtex//:
setenv BSTINPUTS .:~/Documents/texmf/bibtex//:
# Locale
setenv LANG en_US.UTF-8
These are launchctl commands, see its manpage for further information. Works fine for me (I should mention that I'm still a Snow Leopard guy), GUI applications such as texstudio and TeXShop can see my own tex tree. Things that can be improved:
The shell script has a #filename="$1" in it. This is not accidental, as the file name should be feeded to the script by the launch agent as an argument, but that doesn't work.
As mentioned here (German and behind a paywall!), it is possible to put the script in the launch agent itsself.
I am not sure how secure this solution is, as it uses eval with user provided strings.
I think to remember that the definition of MANPATH using this method didn't work well, but I'm not sure.
It should be mentioned that Apple intended a somewhat similar approach by putting stuff in ∼/launchd.conf, but it is currently unsupported as to this date and OS (see the manpage of launchd.conf). I guess that things like globbing would not work as they do in this proposal. And of course one can put these files anywhere else, except the launch agent which must reside in /Library/LaunchAgents/ or ~/Library/LaunchAgents/.
Finally, I should mention the sources I used as information on Launch Agents:
1, 2, 3, 4.
Update: This does not work in version 10.8 at the moment. Workarounds on a per application basis are described here and here.