[launchd-dev] Setting environment variables under Snow Leopard advice.
Benjamin Donnachie
benjamin at py-soft.co.uk
Sun Oct 25 04:26:34 PDT 2009
I currently use a patched version of gpg-agent under launchd control,
which previously set the necessary environment variables so that they
were accessible system-wide using IPC and SetUserEnvironment. The
plist looks like this:
<?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>KeepAlive</key>
<true/>
<key>Label</key>
<string>com.sourceforge.macgpg2.gpg-agent</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/gpg-agent</string>
<string>--launchd</string>
<string>--use-standard-socket</string>
<string>--write-env-file</string>
</array>
<key>LimitLoadToSessionType</key>
<string>Aqua</string>
<key>ServiceIPC</key>
<true/>
</dict>
</plist>
This worked fine under Leopard but under Snow Leopard the environment
variables are not being set. I have had a look through the launchd
source, and ServiceIPC and SetUserEnvironment are still present and
the developer docs do not seem to cover this case. As gpg-agent
caches passphrases it is not suitable for running on demand. I could
modify the patch to accept paths from launchd but I would prefer to
leave gpg-agent with its default behaviour and just pass the necessary
environment variables back to Snow Leopard.
Consequently, I should be grateful for any advice regarding the
correct implementation under 10.6. Below is an extract of Stéphane
Corthésy's gpg-agent launchd patch showing the IPC behaviour.
Many thanks,
Ben
Extract from the gpg-agent launchd patch:
// Pass environment variables back to launchd.
launch_data_t resp, tmp, tmpv, msg;
msg = launch_data_alloc(LAUNCH_DATA_DICTIONARY);
tmp = launch_data_alloc(LAUNCH_DATA_DICTIONARY);
tmpv = launch_data_new_string(strchr(infostr, '=') + 1); //
Skip variable name and equal sign
launch_data_dict_insert(tmp, tmpv, "GPG_AGENT_INFO");
launch_data_dict_insert(msg, tmp, "SetUserEnvironment");
resp = launch_msg(msg);
launch_data_free(msg); // Do NOT launch_data_free() on tmp, nor tmpv
if (resp)
{
launch_data_free(resp);
}
else
{
log_error ("failed to pass environment variable
GPG_AGENT_INFO to launchd: %s\n", strerror (errno));
kill (pid, SIGTERM);
exit (1);
}
if (opt.ssh_support)
{
msg = launch_data_alloc(LAUNCH_DATA_DICTIONARY);
tmp = launch_data_alloc(LAUNCH_DATA_DICTIONARY);
tmpv = launch_data_new_string(strchr(infostr_ssh_sock,
'=') + 1); // Skip variable name and equal sign
launch_data_dict_insert(tmp, tmpv, "SSH_AUTH_SOCK");
launch_data_dict_insert(msg, tmp, "SetUserEnvironment");
resp = launch_msg(msg);
launch_data_free(msg); // Do NOT launch_data_free() on
tmp, nor tmpv
if (resp)
{
launch_data_free(resp);
}
else
{
log_error ("failed to pass environment variable
SSH_AUTH_SOCK to launchd: %s\n", strerror (errno));
kill (pid, SIGTERM);
exit (1);
}
More information about the launchd-dev
mailing list