15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/mac/launchd.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/mac/scoped_launch_data.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base { 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace mac { 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// MessageForJob sends a single message to launchd with a simple dictionary 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// mapping |operation| to |job_label|, and returns the result of calling 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// launch_msg to send that message. On failure, returns NULL. The caller 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// assumes ownership of the returned launch_data_t object. 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)launch_data_t MessageForJob(const std::string& job_label, 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* operation) { 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // launch_data_alloc returns something that needs to be freed. 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedLaunchData message(launch_data_alloc(LAUNCH_DATA_DICTIONARY)); 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!message) { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "launch_data_alloc"; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // launch_data_new_string returns something that needs to be freed, but 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the dictionary will assume ownership when launch_data_dict_insert is 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // called, so put it in a scoper and .release() it when given to the 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // dictionary. 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedLaunchData job_label_launchd(launch_data_new_string(job_label.c_str())); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!job_label_launchd) { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "launch_data_new_string"; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!launch_data_dict_insert(message, 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) job_label_launchd.release(), 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operation)) { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return launch_msg(message); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)pid_t PIDForJob(const std::string& job_label) { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedLaunchData response(MessageForJob(job_label, LAUNCH_KEY_GETJOB)); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!response) { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) launch_data_type_t response_type = launch_data_get_type(response); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (response_type != LAUNCH_DATA_DICTIONARY) { 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (response_type == LAUNCH_DATA_ERRNO) { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "PIDForJob: error " << launch_data_get_errno(response); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "PIDForJob: expected dictionary, got " << response_type; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) launch_data_t pid_data = launch_data_dict_lookup(response, 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LAUNCH_JOBKEY_PID); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pid_data) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (launch_data_get_type(pid_data) != LAUNCH_DATA_INTEGER) { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "PIDForJob: expected integer"; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return launch_data_get_integer(pid_data); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace mac 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace base 76