1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "base/mac/launchd.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include "base/logging.h"
8*6777b538SAndroid Build Coastguard Worker #include "base/mac/scoped_launch_data.h"
9*6777b538SAndroid Build Coastguard Worker #include "base/numerics/safe_conversions.h"
10*6777b538SAndroid Build Coastguard Worker
11*6777b538SAndroid Build Coastguard Worker // This file is written in terms of launch_data_t, which is deprecated but has
12*6777b538SAndroid Build Coastguard Worker // no replacement. Ignore the deprecation warnings for now.
13*6777b538SAndroid Build Coastguard Worker #pragma clang diagnostic push
14*6777b538SAndroid Build Coastguard Worker #pragma clang diagnostic ignored "-Wdeprecated-declarations"
15*6777b538SAndroid Build Coastguard Worker
16*6777b538SAndroid Build Coastguard Worker namespace base::mac {
17*6777b538SAndroid Build Coastguard Worker
18*6777b538SAndroid Build Coastguard Worker // MessageForJob sends a single message to launchd with a simple dictionary
19*6777b538SAndroid Build Coastguard Worker // mapping |operation| to |job_label|, and returns the result of calling
20*6777b538SAndroid Build Coastguard Worker // launch_msg to send that message. On failure, returns NULL. The caller
21*6777b538SAndroid Build Coastguard Worker // assumes ownership of the returned launch_data_t object.
MessageForJob(const std::string & job_label,const char * operation)22*6777b538SAndroid Build Coastguard Worker launch_data_t MessageForJob(const std::string& job_label,
23*6777b538SAndroid Build Coastguard Worker const char* operation) {
24*6777b538SAndroid Build Coastguard Worker // launch_data_alloc returns something that needs to be freed.
25*6777b538SAndroid Build Coastguard Worker ScopedLaunchData message(launch_data_alloc(LAUNCH_DATA_DICTIONARY));
26*6777b538SAndroid Build Coastguard Worker if (!message.is_valid()) {
27*6777b538SAndroid Build Coastguard Worker LOG(ERROR) << "launch_data_alloc";
28*6777b538SAndroid Build Coastguard Worker return NULL;
29*6777b538SAndroid Build Coastguard Worker }
30*6777b538SAndroid Build Coastguard Worker
31*6777b538SAndroid Build Coastguard Worker // launch_data_new_string returns something that needs to be freed, but
32*6777b538SAndroid Build Coastguard Worker // the dictionary will assume ownership when launch_data_dict_insert is
33*6777b538SAndroid Build Coastguard Worker // called, so put it in a scoper and .release() it when given to the
34*6777b538SAndroid Build Coastguard Worker // dictionary.
35*6777b538SAndroid Build Coastguard Worker ScopedLaunchData job_label_launchd(launch_data_new_string(job_label.c_str()));
36*6777b538SAndroid Build Coastguard Worker if (!job_label_launchd.is_valid()) {
37*6777b538SAndroid Build Coastguard Worker LOG(ERROR) << "launch_data_new_string";
38*6777b538SAndroid Build Coastguard Worker return NULL;
39*6777b538SAndroid Build Coastguard Worker }
40*6777b538SAndroid Build Coastguard Worker
41*6777b538SAndroid Build Coastguard Worker if (!launch_data_dict_insert(message.get(), job_label_launchd.release(),
42*6777b538SAndroid Build Coastguard Worker operation)) {
43*6777b538SAndroid Build Coastguard Worker return NULL;
44*6777b538SAndroid Build Coastguard Worker }
45*6777b538SAndroid Build Coastguard Worker
46*6777b538SAndroid Build Coastguard Worker return launch_msg(message.get());
47*6777b538SAndroid Build Coastguard Worker }
48*6777b538SAndroid Build Coastguard Worker
PIDForJob(const std::string & job_label)49*6777b538SAndroid Build Coastguard Worker pid_t PIDForJob(const std::string& job_label) {
50*6777b538SAndroid Build Coastguard Worker ScopedLaunchData response(MessageForJob(job_label, LAUNCH_KEY_GETJOB));
51*6777b538SAndroid Build Coastguard Worker if (!response.is_valid()) {
52*6777b538SAndroid Build Coastguard Worker return -1;
53*6777b538SAndroid Build Coastguard Worker }
54*6777b538SAndroid Build Coastguard Worker
55*6777b538SAndroid Build Coastguard Worker launch_data_type_t response_type = launch_data_get_type(response.get());
56*6777b538SAndroid Build Coastguard Worker if (response_type != LAUNCH_DATA_DICTIONARY) {
57*6777b538SAndroid Build Coastguard Worker if (response_type == LAUNCH_DATA_ERRNO) {
58*6777b538SAndroid Build Coastguard Worker LOG(ERROR) << "PIDForJob: error "
59*6777b538SAndroid Build Coastguard Worker << launch_data_get_errno(response.get());
60*6777b538SAndroid Build Coastguard Worker } else {
61*6777b538SAndroid Build Coastguard Worker LOG(ERROR) << "PIDForJob: expected dictionary, got " << response_type;
62*6777b538SAndroid Build Coastguard Worker }
63*6777b538SAndroid Build Coastguard Worker return -1;
64*6777b538SAndroid Build Coastguard Worker }
65*6777b538SAndroid Build Coastguard Worker
66*6777b538SAndroid Build Coastguard Worker launch_data_t pid_data =
67*6777b538SAndroid Build Coastguard Worker launch_data_dict_lookup(response.get(), LAUNCH_JOBKEY_PID);
68*6777b538SAndroid Build Coastguard Worker if (!pid_data)
69*6777b538SAndroid Build Coastguard Worker return 0;
70*6777b538SAndroid Build Coastguard Worker
71*6777b538SAndroid Build Coastguard Worker if (launch_data_get_type(pid_data) != LAUNCH_DATA_INTEGER) {
72*6777b538SAndroid Build Coastguard Worker LOG(ERROR) << "PIDForJob: expected integer";
73*6777b538SAndroid Build Coastguard Worker return -1;
74*6777b538SAndroid Build Coastguard Worker }
75*6777b538SAndroid Build Coastguard Worker
76*6777b538SAndroid Build Coastguard Worker return checked_cast<pid_t>(launch_data_get_integer(pid_data));
77*6777b538SAndroid Build Coastguard Worker }
78*6777b538SAndroid Build Coastguard Worker
79*6777b538SAndroid Build Coastguard Worker } // namespace base::mac
80*6777b538SAndroid Build Coastguard Worker
81*6777b538SAndroid Build Coastguard Worker #pragma clang diagnostic pop
82