[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