launchd_fd.c (4211B)
1 /* Copyright (c) 2008-2012 Apple Inc. 2 * 3 * Permission is hereby granted, free of charge, to any person 4 * obtaining a copy of this software and associated documentation files 5 * (the "Software"), to deal in the Software without restriction, 6 * including without limitation the rights to use, copy, modify, merge, 7 * publish, distribute, sublicense, and/or sell copies of the Software, 8 * and to permit persons to whom the Software is furnished to do so, 9 * subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be 12 * included in all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 * NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT 18 * HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 19 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 * 23 * Except as contained in this notice, the name(s) of the above 24 * copyright holders shall not be used in advertising or otherwise to 25 * promote the sale, use or other dealings in this Software without 26 * prior written authorization. 27 */ 28 29 #ifdef HAVE_DIX_CONFIG_H 30 #include <dix-config.h> 31 #endif 32 33 #include <launch.h> 34 #include <asl.h> 35 #include <errno.h> 36 37 #include "launchd_fd.h" 38 39 extern aslclient aslc; 40 41 int 42 launchd_display_fd(void) 43 { 44 launch_data_t sockets_dict, checkin_request, checkin_response; 45 launch_data_t listening_fd_array, listening_fd; 46 47 /* Get launchd fd */ 48 if ((checkin_request = launch_data_new_string(LAUNCH_KEY_CHECKIN)) == 49 NULL) { 50 asl_log( 51 aslc, NULL, ASL_LEVEL_ERR, 52 "launch_data_new_string(\"" LAUNCH_KEY_CHECKIN 53 "\") Unable to create string.\n"); 54 return ERROR_FD; 55 } 56 57 if ((checkin_response = launch_msg(checkin_request)) == NULL) { 58 asl_log(aslc, NULL, ASL_LEVEL_WARNING, 59 "launch_msg(\"" LAUNCH_KEY_CHECKIN "\") IPC failure: %s\n", 60 strerror( 61 errno)); 62 return ERROR_FD; 63 } 64 65 if (LAUNCH_DATA_ERRNO == launch_data_get_type(checkin_response)) { 66 // ignore EACCES, which is common if we weren't started by launchd 67 if (launch_data_get_errno(checkin_response) != EACCES) 68 asl_log(aslc, NULL, ASL_LEVEL_ERR, 69 "launchd check-in failed: %s\n", 70 strerror(launch_data_get_errno( 71 checkin_response))); 72 return ERROR_FD; 73 } 74 75 sockets_dict = launch_data_dict_lookup(checkin_response, 76 LAUNCH_JOBKEY_SOCKETS); 77 if (NULL == sockets_dict) { 78 asl_log(aslc, NULL, ASL_LEVEL_ERR, 79 "launchd check-in: no sockets found to answer requests on!\n"); 80 return ERROR_FD; 81 } 82 83 if (launch_data_dict_get_count(sockets_dict) > 1) { 84 asl_log(aslc, NULL, ASL_LEVEL_ERR, 85 "launchd check-in: some sockets will be ignored!\n"); 86 return ERROR_FD; 87 } 88 89 listening_fd_array = launch_data_dict_lookup(sockets_dict, 90 BUNDLE_ID_PREFIX ":0"); 91 if (NULL == listening_fd_array) { 92 listening_fd_array = launch_data_dict_lookup(sockets_dict, ":0"); 93 if (NULL == listening_fd_array) { 94 asl_log( 95 aslc, NULL, ASL_LEVEL_ERR, 96 "launchd check-in: No known sockets found to answer requests on! \"%s:0\" and \":0\" failed.\n", 97 BUNDLE_ID_PREFIX); 98 return ERROR_FD; 99 } 100 } 101 102 if (launch_data_array_get_count(listening_fd_array) != 1) { 103 asl_log(aslc, NULL, ASL_LEVEL_ERR, 104 "launchd check-in: Expected 1 socket from launchd, got %u)\n", 105 (unsigned)launch_data_array_get_count( 106 listening_fd_array)); 107 return ERROR_FD; 108 } 109 110 listening_fd = launch_data_array_get_index(listening_fd_array, 0); 111 return launch_data_get_fd(listening_fd); 112 }