1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "sandbox/mac/os_compatibility.h"
7 #include <servers/bootstrap.h>
10 #include "base/mac/mac_util.h"
16 // Verified from launchd-329.3.3 (10.6.8).
17 struct look_up2_request_10_6
{
18 mach_msg_header_t Head
;
25 struct look_up2_reply_10_6
{
26 mach_msg_header_t Head
;
27 mach_msg_body_t msgh_body
;
28 mach_msg_port_descriptor_t service_port
;
32 // launchd-392.39 (10.7.5)
33 // launchd-442.26.2 (10.8.5)
34 // launchd-842.1.4 (10.9.0)
35 struct look_up2_request_10_7
{
36 mach_msg_header_t Head
;
44 // look_up2_reply_10_7 is the same as the 10_6 version.
47 // launchd-329.3.3 (10.6.8)
48 // launchd-392.39 (10.7.5)
49 // launchd-442.26.2 (10.8.5)
50 // launchd-842.1.4 (10.9.0)
51 typedef int vproc_gsk_t
; // Defined as an enum in liblaunch/vproc_priv.h.
52 struct swap_integer_request_10_6
{
53 mach_msg_header_t Head
;
60 // TODO(rsesek): Libc provides strnlen() starting in 10.7.
61 size_t strnlen(const char* str
, size_t maxlen
) {
63 for (; len
< maxlen
; ++len
, ++str
) {
71 std::string
LaunchdLookUp2GetRequestName(const mach_msg_header_t
* header
) {
72 DCHECK_EQ(sizeof(R
), header
->msgh_size
);
73 const R
* request
= reinterpret_cast<const R
*>(header
);
74 // Make sure the name is properly NUL-terminated.
75 const size_t name_length
=
76 strnlen(request
->servicename
, BOOTSTRAP_MAX_NAME_LEN
);
77 std::string name
= std::string(request
->servicename
, name_length
);
82 void LaunchdLookUp2FillReply(mach_msg_header_t
* header
, mach_port_t port
) {
83 R
* reply
= reinterpret_cast<R
*>(header
);
84 reply
->Head
.msgh_size
= sizeof(R
);
85 reply
->Head
.msgh_bits
=
86 MACH_MSGH_BITS_REMOTE(MACH_MSG_TYPE_MOVE_SEND_ONCE
) |
87 MACH_MSGH_BITS_COMPLEX
;
88 reply
->msgh_body
.msgh_descriptor_count
= 1;
89 reply
->service_port
.name
= port
;
90 reply
->service_port
.disposition
= MACH_MSG_TYPE_COPY_SEND
;
91 reply
->service_port
.type
= MACH_MSG_PORT_DESCRIPTOR
;
95 bool LaunchdSwapIntegerIsGetOnly(const mach_msg_header_t
* header
) {
96 const R
* request
= reinterpret_cast<const R
*>(header
);
97 return request
->inkey
== 0 && request
->inval
== 0 && request
->outkey
!= 0;
102 const LaunchdCompatibilityShim
GetLaunchdCompatibilityShim() {
103 LaunchdCompatibilityShim shim
= {
104 .msg_id_look_up2
= 404,
105 .msg_id_swap_integer
= 416,
106 .look_up2_fill_reply
= &LaunchdLookUp2FillReply
<look_up2_reply_10_6
>,
107 .swap_integer_is_get_only
=
108 &LaunchdSwapIntegerIsGetOnly
<swap_integer_request_10_6
>,
111 if (base::mac::IsOSSnowLeopard()) {
112 shim
.look_up2_get_request_name
=
113 &LaunchdLookUp2GetRequestName
<look_up2_request_10_6
>;
114 } else if (base::mac::IsOSLionOrLater() &&
115 !base::mac::IsOSLaterThanMavericks_DontCallThis()) {
116 shim
.look_up2_get_request_name
=
117 &LaunchdLookUp2GetRequestName
<look_up2_request_10_7
>;
119 DLOG(ERROR
) << "Unknown OS, using launchd compatibility shim from 10.7.";
120 shim
.look_up2_get_request_name
=
121 &LaunchdLookUp2GetRequestName
<look_up2_request_10_7
>;
127 } // namespace sandbox