[launchd-dev] Can a launchd job get any access to its invoking plist?

Norman Gray norman at astro.gla.ac.uk
Wed Dec 4 15:41:25 PST 2013


Damien, hello.

Thanks for your thoughtful remarks here.

On 2013 Dec 4, at 21:51, Damien Sorresso <dsorresso at apple.com> wrote:

>> @Graham: thanks.  launch_data_dict_lookup looks like it would do the job, and demonstrates that Apple feel that the information is legitimately available in at least some circumstances. But the fact that it's not documented _anywhere_ I can find (other than being implicitly documented as part of Apple example code), makes me nervous of using it.
>> 
>> All the best,
> 
> Those interfaces are really only so that jobs can check in with launchd to obtain listening sockets. They were way too general at the outset.

Righto.  I'll take that as a clear indication that I should avoid the launch_data_dict_lookup API.  Or were you referring to the ServiceManagement.h API as well?

[The following is thinking aloud; feel free, all, to ignore me]

Thinking of the broader question....

> On 4 Dec, 2013, at 12:58, Norman Gray <norman at astro.gla.ac.uk> wrote:
>> 
[...]
>> Sure, and I'm storing the actual state in preferences, using NSUserDefaults.  All I really want to know is "Have I been invoked from A.plist or B.plist?"
>> 
>> [...]
>> So I'm not thinking of the job parameters as _state_, quite, but as part of the program launch environment.  Rather than (argc, argv, environ), it's effectively (argc, argv, environ, plist).  That's not traditional unix, of course, but then launchd isn't traditional unix either.
> 
> It seems like you're basing a ton of behaviors simply on the job's label.

Well, not really.  The program can be invoked in a couple of different contexts, and it wants to respect that, and behave slightly differently in those two contexts, in ways which are related to its own internal bookkeeping, and nothing that the author of the plist should have to care about.  The only real difference between those two contexts is that they're different plists, and it seems slightly perverse that in order to find that out, I've got to 'fake' it by copying (or requiring the plist's author to copy) the Label or some other unique identifier into an EnvironmentVariables entry.

> Why do they have to be based on that? That said, I think it's reasonable to export the job's label in an environment variable or something. But plist is not there as part of the program's environment. It *defines* the program's environment.

Yeeeees, but I'm not sure this distinction makes much difference.  The more I think about this, the _less_ I feel able to identify a secure distinction between the program's environment as a char**, and the plist dictionary which, as you say, defines that environment.

The best I can do is say that certain elements within the launchd.plist dictionary are describing the actions which launchd is to take, and that these are formally distinct from the environment that launchd subsequently constructs for the program.  I could potentially -- just -- see why it might be desirable for a program to be kept ignorant of this information (*mumble*... security/privacy... *mumble*), but since the above APIs exist, that's clearly not the case in fact, and this smells of post hoc rationalisation on my part.

Another possibility is that the structure of the launchd.plist dictionary isn't necessarily stable long-term, so a program can't rely on  it.  True: but that doesn't matter, since programs already have cope with the fact that the content of the char** environment isn't completely guaranteed either.

So I'm left without identifiable clear blue water between the char** environment and the broader plist environment, other than that the char** environment is The Unix Way.  I'm a sturdy defender of The Unix Way, but since the very existence of launchd is a smack in the face of The Unix Way (garhhhh... cron, at and batch were good enough for me when I were a young 'un), why stop here?

Indeed, if there were (say) a <key>CFEnvironment</key> within the plist, that could take as value any plist type and which could be easily retrieved within the job, that would potentially provide a much more natural way of providing ready-Cocoad-up context to sit along side the char* -> char* dictionary of the unix environment.

The overview of the Service Management framework says that it "...provides support for loading and unloading launchd jobs and reading and manipulating job dictionaries from within an application."  That seems an eminently sensible goal and, based on the second half of that sentence, the fact that there isn't a function SMJobGetLabel(void), for example, looks like an omission rather than a design decision.

That's probably enough of that!

Best wishes,

Norman


-- 
Norman Gray  :  http://nxg.me.uk
SUPA School of Physics and Astronomy, University of Glasgow, UK



More information about the launchd-dev mailing list