135c4bbdfSmrg/* Copyright (c) 2008-2012 Apple Inc. 24642e01fSmrg * 34642e01fSmrg * Permission is hereby granted, free of charge, to any person 44642e01fSmrg * obtaining a copy of this software and associated documentation files 54642e01fSmrg * (the "Software"), to deal in the Software without restriction, 64642e01fSmrg * including without limitation the rights to use, copy, modify, merge, 74642e01fSmrg * publish, distribute, sublicense, and/or sell copies of the Software, 84642e01fSmrg * and to permit persons to whom the Software is furnished to do so, 94642e01fSmrg * subject to the following conditions: 104642e01fSmrg * 114642e01fSmrg * The above copyright notice and this permission notice shall be 124642e01fSmrg * included in all copies or substantial portions of the Software. 134642e01fSmrg * 144642e01fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 154642e01fSmrg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 164642e01fSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 174642e01fSmrg * NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT 184642e01fSmrg * HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 194642e01fSmrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 204642e01fSmrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 214642e01fSmrg * DEALINGS IN THE SOFTWARE. 224642e01fSmrg * 234642e01fSmrg * Except as contained in this notice, the name(s) of the above 244642e01fSmrg * copyright holders shall not be used in advertising or otherwise to 254642e01fSmrg * promote the sale, use or other dealings in this Software without 264642e01fSmrg * prior written authorization. 274642e01fSmrg */ 284642e01fSmrg 296747b715Smrg#ifdef HAVE_DIX_CONFIG_H 306747b715Smrg#include <dix-config.h> 316747b715Smrg#endif 326747b715Smrg 334642e01fSmrg#include <launch.h> 3435c4bbdfSmrg#include <asl.h> 354642e01fSmrg#include <errno.h> 364642e01fSmrg 374642e01fSmrg#include "launchd_fd.h" 384642e01fSmrg 3935c4bbdfSmrgextern aslclient aslc; 4035c4bbdfSmrg 4135c4bbdfSmrgint 4235c4bbdfSmrglaunchd_display_fd(void) 4335c4bbdfSmrg{ 444642e01fSmrg launch_data_t sockets_dict, checkin_request, checkin_response; 454642e01fSmrg launch_data_t listening_fd_array, listening_fd; 464642e01fSmrg 474642e01fSmrg /* Get launchd fd */ 4835c4bbdfSmrg if ((checkin_request = launch_data_new_string(LAUNCH_KEY_CHECKIN)) == 4935c4bbdfSmrg NULL) { 5035c4bbdfSmrg asl_log( 5135c4bbdfSmrg aslc, NULL, ASL_LEVEL_ERR, 5235c4bbdfSmrg "launch_data_new_string(\"" LAUNCH_KEY_CHECKIN 5335c4bbdfSmrg "\") Unable to create string.\n"); 544642e01fSmrg return ERROR_FD; 554642e01fSmrg } 5635c4bbdfSmrg 574642e01fSmrg if ((checkin_response = launch_msg(checkin_request)) == NULL) { 5835c4bbdfSmrg asl_log(aslc, NULL, ASL_LEVEL_WARNING, 5935c4bbdfSmrg "launch_msg(\"" LAUNCH_KEY_CHECKIN "\") IPC failure: %s\n", 6035c4bbdfSmrg strerror( 6135c4bbdfSmrg errno)); 624642e01fSmrg return ERROR_FD; 634642e01fSmrg } 6435c4bbdfSmrg 654642e01fSmrg if (LAUNCH_DATA_ERRNO == launch_data_get_type(checkin_response)) { 664642e01fSmrg // ignore EACCES, which is common if we weren't started by launchd 674642e01fSmrg if (launch_data_get_errno(checkin_response) != EACCES) 6835c4bbdfSmrg asl_log(aslc, NULL, ASL_LEVEL_ERR, 6935c4bbdfSmrg "launchd check-in failed: %s\n", 7035c4bbdfSmrg strerror(launch_data_get_errno( 7135c4bbdfSmrg checkin_response))); 724642e01fSmrg return ERROR_FD; 7335c4bbdfSmrg } 7435c4bbdfSmrg 7535c4bbdfSmrg sockets_dict = launch_data_dict_lookup(checkin_response, 7635c4bbdfSmrg LAUNCH_JOBKEY_SOCKETS); 774642e01fSmrg if (NULL == sockets_dict) { 7835c4bbdfSmrg asl_log(aslc, NULL, ASL_LEVEL_ERR, 7935c4bbdfSmrg "launchd check-in: no sockets found to answer requests on!\n"); 804642e01fSmrg return ERROR_FD; 814642e01fSmrg } 8235c4bbdfSmrg 834642e01fSmrg if (launch_data_dict_get_count(sockets_dict) > 1) { 8435c4bbdfSmrg asl_log(aslc, NULL, ASL_LEVEL_ERR, 8535c4bbdfSmrg "launchd check-in: some sockets will be ignored!\n"); 864642e01fSmrg return ERROR_FD; 874642e01fSmrg } 8835c4bbdfSmrg 8935c4bbdfSmrg listening_fd_array = launch_data_dict_lookup(sockets_dict, 9035c4bbdfSmrg BUNDLE_ID_PREFIX ":0"); 914642e01fSmrg if (NULL == listening_fd_array) { 926747b715Smrg listening_fd_array = launch_data_dict_lookup(sockets_dict, ":0"); 936747b715Smrg if (NULL == listening_fd_array) { 9435c4bbdfSmrg asl_log( 9535c4bbdfSmrg aslc, NULL, ASL_LEVEL_ERR, 9635c4bbdfSmrg "launchd check-in: No known sockets found to answer requests on! \"%s:0\" and \":0\" failed.\n", 9735c4bbdfSmrg BUNDLE_ID_PREFIX); 986747b715Smrg return ERROR_FD; 996747b715Smrg } 1004642e01fSmrg } 10135c4bbdfSmrg 10235c4bbdfSmrg if (launch_data_array_get_count(listening_fd_array) != 1) { 10335c4bbdfSmrg asl_log(aslc, NULL, ASL_LEVEL_ERR, 10435c4bbdfSmrg "launchd check-in: Expected 1 socket from launchd, got %u)\n", 10535c4bbdfSmrg (unsigned)launch_data_array_get_count( 10635c4bbdfSmrg listening_fd_array)); 1074642e01fSmrg return ERROR_FD; 1084642e01fSmrg } 10935c4bbdfSmrg 11035c4bbdfSmrg listening_fd = launch_data_array_get_index(listening_fd_array, 0); 1114642e01fSmrg return launch_data_get_fd(listening_fd); 1124642e01fSmrg} 113