How to ensure that my job is launched through launchd and not directly?
I have a program and I want to ensure that it has been launched only by launchd (as a daemon) & it should terminate if the user launches it directly (double-click on Finder, terminal). Is there a nifty way of accomplishing this?
16 apr 2015 kl. 13:25 skrev Raunak Poddar <raunak.poddar@gmail.com>:
I have a program and I want to ensure that it has been launched only by launchd (as a daemon) & it should terminate if the user launches it directly (double-click on Finder, terminal). Is there a nifty way of accomplishing this?
A quick and dirty check would be to use getppid() and ensure that it's launchd. A better way is probably to check in with launchd (see SampleD.c), but I'm not actually sure what happens if you run that manually. -- Per Olofsson, IT-service, University of Gothenburg
There are a couple strategies you can use. In your launchd.plist(5), you can define a certain environment variable, like LAUNCHED_BY_LAUNCHD or something. If you check for that variable with getenv(3) and it is not present, you know that you weren't launched properly. Alternatively, as of Yosemite, launchd sets an environment variable called XPC_SERVICE_NAME whose value is the label you've given your job. You can check that too. Do not do a getppid(3) check against 1. It will fail on older OSes if you're an agent, and the kernel may reparent processes to PID 1 under certain conditions, so having a parent PID of 1 is not necessarily indicative of being managed by launchd. -damien On 16 Apr, 2015, at 04:25, Raunak Poddar <raunak.poddar@gmail.com> wrote:
I have a program and I want to ensure that it has been launched only by launchd (as a daemon) & it should terminate if the user launches it directly (double-click on Finder, terminal). Is there a nifty way of accomplishing this? _______________________________________________ launchd-dev mailing list launchd-dev@lists.macosforge.org https://lists.macosforge.org/mailman/listinfo/launchd-dev
16 apr 2015 kl. 21:20 skrev Damien Sorresso <dsorresso@apple.com>:
There are a couple strategies you can use.
In your launchd.plist(5), you can define a certain environment variable, like LAUNCHED_BY_LAUNCHD or something. If you check for that variable with getenv(3) and it is not present, you know that you weren't launched properly.
Alternatively, as of Yosemite, launchd sets an environment variable called XPC_SERVICE_NAME whose value is the label you've given your job. You can check that too.
Any thoughts on checking in with launchd and getting the job label? launch_data_dict_lookup(checkin_response, LAUNCH_JOBKEY_LABEL) predictably fails when run on the commandline, and succeeds when started as a daemon by launchd.
Do not do a getppid(3) check against 1. It will fail on older OSes if you're an agent, and the kernel may reparent processes to PID 1 under certain conditions, so having a parent PID of 1 is not necessarily indicative of being managed by launchd.
I suspected as much, good to know :) -- Per Olofsson, IT-service, University of Gothenburg
On 17 Apr, 2015, at 00:45, Per Olofsson <per.olofsson@gu.se> wrote:
16 apr 2015 kl. 21:20 skrev Damien Sorresso <dsorresso@apple.com>:
There are a couple strategies you can use.
In your launchd.plist(5), you can define a certain environment variable, like LAUNCHED_BY_LAUNCHD or something. If you check for that variable with getenv(3) and it is not present, you know that you weren't launched properly.
Alternatively, as of Yosemite, launchd sets an environment variable called XPC_SERVICE_NAME whose value is the label you've given your job. You can check that too.
Any thoughts on checking in with launchd and getting the job label? launch_data_dict_lookup(checkin_response, LAUNCH_JOBKEY_LABEL) predictably fails when run on the commandline, and succeeds when started as a daemon by launchd.
For various reasons, that is probably not as reliable as you'd think across OS versions, especially crossing from Mavericks to Yosemite. The environment variable is a fairly authoritative indication that launchd spawned you. Of course, anyone can set it if they spawn your binary by hand, so just don't make security decisions based on its presence or absence. Also those APIs are incredibly awkward and have been deprecated in Yosemite. -damien
Do not do a getppid(3) check against 1. It will fail on older OSes if you're an agent, and the kernel may reparent processes to PID 1 under certain conditions, so having a parent PID of 1 is not necessarily indicative of being managed by launchd.
I suspected as much, good to know :)
-- Per Olofsson, IT-service, University of Gothenburg
_______________________________________________ launchd-dev mailing list launchd-dev@lists.macosforge.org https://lists.macosforge.org/mailman/listinfo/launchd-dev
17 apr 2015 kl. 18:10 skrev Damien Sorresso <dsorresso@apple.com>:
For various reasons, that is probably not as reliable as you'd think across OS versions, especially crossing from Mavericks to Yosemite. The environment variable is a fairly authoritative indication that launchd spawned you. Of course, anyone can set it if they spawn your binary by hand, so just don't make security decisions based on its presence or absence.
Also those APIs are incredibly awkward and have been deprecated in Yosemite.
Agreed, the new API in launch(3) is a heck of a lot cleaner, but I haven't had a chance to rewrite anything yet. Thanks for the info! -- Per Olofsson, IT-service, University of Gothenburg
participants (3)
-
Damien Sorresso
-
Per Olofsson
-
Raunak Poddar