mirror of
https://github.com/darlinghq/darling-libxpc.git
synced 2024-11-23 03:39:40 +00:00
Fix os_transaction and make bools and nulls into globals
XPC bools and nulls were made into global to match their behavior in Apple's libxpc; users are allowed to compare XPC object pointers with the global XPC_BOOL_{TRUE,FALSE} constants, which are pointers to global variables, so this now allows that to work as expected.
This commit is contained in:
parent
33b6bf1ce8
commit
8df31b5db6
@ -32,7 +32,7 @@ set(xpc_sources
|
||||
subr_sbuf.c
|
||||
xpc_pipe.c
|
||||
reboot3.c
|
||||
transaction_private.c
|
||||
transaction.m
|
||||
)
|
||||
|
||||
set(DYLIB_INSTALL_NAME "/usr/lib/system/libxpc.dylib")
|
||||
@ -49,6 +49,12 @@ add_circular(xpc FAT
|
||||
launch
|
||||
system_info
|
||||
system_dyld
|
||||
UPWARD
|
||||
# break an upward dependency on libobjc
|
||||
# ---
|
||||
# note that we don't actually need to intialize it ourselves by calling `objc_init`;
|
||||
# libSystem guarantees that we'll be initialized after libdispatch, and libdispatch already initializes libobjc
|
||||
objc
|
||||
)
|
||||
#target_link_libraries(xpc system)
|
||||
install(TARGETS xpc DESTINATION libexec/darling/usr/lib/system)
|
||||
|
@ -4,17 +4,11 @@
|
||||
struct os_transaction_s;
|
||||
struct os_transaction_extra_vtable_s {};
|
||||
struct os_transaction_vtable_s {
|
||||
void (*_os_obj_xref_dispose)(_os_object_t);
|
||||
void (*_os_obj_dispose)(_os_object_t);
|
||||
_OS_OBJECT_CLASS_HEADER();
|
||||
struct os_transaction_extra_vtable_s _os_obj_vtable;
|
||||
};
|
||||
extern const struct os_transaction_vtable_s OS_OBJECT_CLASS_SYMBOL(os_transaction) __asm__(OS_OBJC_CLASS_RAW_SYMBOL_NAME(OS_OBJECT_CLASS(os_transaction)));
|
||||
|
||||
const struct os_transaction_vtable_s OS_OBJECT_CLASS_SYMBOL(os_transaction) = {
|
||||
._os_obj_xref_dispose = NULL,
|
||||
._os_obj_dispose = NULL,
|
||||
._os_obj_vtable = {},
|
||||
};
|
||||
extern const struct os_transaction_vtable_s OS_OBJECT_CLASS_SYMBOL(os_transaction) __asm__(OS_OBJC_CLASS_RAW_SYMBOL_NAME(OS_OBJECT_CLASS(os_transaction)));
|
||||
|
||||
#define OS_TRANSACTION_CLASS (&OS_OBJECT_CLASS_SYMBOL(os_transaction))
|
||||
|
||||
@ -29,3 +23,9 @@ struct os_transaction_s {
|
||||
os_transaction_t os_transaction_create(const char* transaction_name) {
|
||||
return (os_transaction_t)_os_object_alloc_realized(OS_TRANSACTION_CLASS, sizeof(struct os_transaction_s));
|
||||
};
|
||||
|
||||
OS_OBJECT_NONLAZY_CLASS
|
||||
@implementation OS_OBJECT_CLASS(os_transaction)
|
||||
OS_OBJECT_NONLAZY_CLASS_LOAD
|
||||
|
||||
@end
|
@ -120,6 +120,8 @@ typedef union {
|
||||
} xpc_u;
|
||||
|
||||
|
||||
// indicates that the object should never be released
|
||||
#define _XPC_KEEP_ALIVE UINT32_MAX
|
||||
#define _XPC_FROM_WIRE 0x1
|
||||
struct xpc_object {
|
||||
uint8_t xo_xpc_type;
|
||||
@ -164,6 +166,18 @@ struct xpc_service {
|
||||
#define xo_activity xo_u.activity
|
||||
#define xo_connection xo_u.connection
|
||||
|
||||
#define _XPC_GLOBAL_OBJECT_INITIALIZER(type, extra_size, union_value) { \
|
||||
.xo_xpc_type = type, \
|
||||
.xo_flags = 0, \
|
||||
.xo_refcnt = _XPC_KEEP_ALIVE, \
|
||||
.xo_size = extra_size, \
|
||||
.xo_u = { \
|
||||
union_value, \
|
||||
}, \
|
||||
.xo_audit_token = NULL, \
|
||||
.xo_link = NULL, \
|
||||
}
|
||||
|
||||
__private_extern__ struct xpc_object *_xpc_prim_create(int type, xpc_u value,
|
||||
size_t size);
|
||||
__private_extern__ struct xpc_object *_xpc_prim_create_flags(int type,
|
||||
|
26
xpc_misc.c
26
xpc_misc.c
@ -568,6 +568,9 @@ XPC_INLINE struct xpc_object* xpc_unpack(const void* buf, size_t size, size_t* p
|
||||
void
|
||||
xpc_object_destroy(struct xpc_object *xo)
|
||||
{
|
||||
if (xo->xo_refcnt == _XPC_KEEP_ALIVE)
|
||||
return;
|
||||
|
||||
if (xo->xo_xpc_type == _XPC_TYPE_DICTIONARY)
|
||||
xpc_dictionary_destroy(xo);
|
||||
|
||||
@ -589,9 +592,10 @@ xpc_object_destroy(struct xpc_object *xo)
|
||||
xpc_object_t
|
||||
xpc_retain(xpc_object_t obj)
|
||||
{
|
||||
struct xpc_object *xo;
|
||||
struct xpc_object *xo = obj;
|
||||
if (xo->xo_refcnt == _XPC_KEEP_ALIVE)
|
||||
return obj;
|
||||
|
||||
xo = obj;
|
||||
OSAtomicIncrement32(&xo->xo_refcnt);
|
||||
return (obj);
|
||||
}
|
||||
@ -599,9 +603,10 @@ xpc_retain(xpc_object_t obj)
|
||||
void
|
||||
xpc_release(xpc_object_t obj)
|
||||
{
|
||||
struct xpc_object *xo;
|
||||
struct xpc_object *xo = obj;
|
||||
if (xo->xo_refcnt == _XPC_KEEP_ALIVE)
|
||||
return;
|
||||
|
||||
xo = obj;
|
||||
if (OSAtomicDecrement32(&xo->xo_refcnt) > 0)
|
||||
return;
|
||||
|
||||
@ -787,8 +792,7 @@ ld2xpc(launch_data_t ld)
|
||||
memcpy(__DECONST(void *, val.str), ld->string, ld->string_len);
|
||||
xo = _xpc_prim_create(ld_to_xpc_type[ld->type], val, ld->string_len);
|
||||
} else if (ld->type == LAUNCH_DATA_BOOL) {
|
||||
val.b = (bool)ld->boolean;
|
||||
xo = _xpc_prim_create(ld_to_xpc_type[ld->type], val, 0);
|
||||
xo = xpc_bool_create((bool)ld->boolean);
|
||||
} else if (ld->type == LAUNCH_DATA_ARRAY) {
|
||||
xo = xpc_array_create(NULL, 0);
|
||||
for (uint64_t i = 0; i < ld->_array_cnt; i++)
|
||||
@ -803,19 +807,13 @@ ld2xpc(launch_data_t ld)
|
||||
xpc_object_t
|
||||
xpc_copy_entitlement_for_token(const char *key __unused, audit_token_t *token __unused)
|
||||
{
|
||||
xpc_u val;
|
||||
|
||||
val.b = true;
|
||||
return (_xpc_prim_create(_XPC_TYPE_BOOL, val,0));
|
||||
return xpc_bool_create(true);
|
||||
}
|
||||
|
||||
xpc_object_t
|
||||
xpc_copy_entitlements_for_pid(pid_t pid)
|
||||
{
|
||||
xpc_u val;
|
||||
|
||||
val.b = true;
|
||||
return (_xpc_prim_create(_XPC_TYPE_BOOL, val,0));
|
||||
return xpc_bool_create(true);
|
||||
}
|
||||
|
||||
|
||||
|
32
xpc_type.c
32
xpc_type.c
@ -54,14 +54,19 @@ xt _xpc_type_uuid;
|
||||
xt _xpc_type_double;
|
||||
xt _xpc_type_pointer;
|
||||
|
||||
|
||||
struct _xpc_bool_s {
|
||||
// we have to wrap it in `_xpc_bool_s` because the header defines the variable with that type
|
||||
struct xpc_object xo;
|
||||
};
|
||||
|
||||
typedef const struct _xpc_bool_s xb;
|
||||
const struct _xpc_bool_s _xpc_bool_true = {
|
||||
.xo = _XPC_GLOBAL_OBJECT_INITIALIZER(_XPC_TYPE_BOOL, 0, .b = true),
|
||||
};
|
||||
const struct _xpc_bool_s _xpc_bool_false = {
|
||||
.xo = _XPC_GLOBAL_OBJECT_INITIALIZER(_XPC_TYPE_BOOL, 0, .b = false),
|
||||
};
|
||||
|
||||
xb _xpc_bool_true;
|
||||
xb _xpc_bool_false;
|
||||
const struct xpc_object _xpc_null = _XPC_GLOBAL_OBJECT_INITIALIZER(_XPC_TYPE_NULL, 0, .b = false); // requires a union value, so just set the boolean
|
||||
|
||||
static size_t xpc_data_hash(const uint8_t *data, size_t length);
|
||||
|
||||
@ -146,32 +151,19 @@ _xpc_prim_create_flags(int type, xpc_u value, size_t size, uint16_t flags)
|
||||
xpc_object_t
|
||||
xpc_null_create(void)
|
||||
{
|
||||
xpc_u val = {0};
|
||||
return _xpc_prim_create(_XPC_TYPE_NULL, val, 0);
|
||||
return &_xpc_null;
|
||||
}
|
||||
|
||||
xpc_object_t
|
||||
xpc_bool_create(bool value)
|
||||
{
|
||||
xpc_u val;
|
||||
|
||||
val.b = value;
|
||||
return _xpc_prim_create(_XPC_TYPE_BOOL, val, 1);
|
||||
return value ? XPC_BOOL_TRUE : XPC_BOOL_FALSE;
|
||||
}
|
||||
|
||||
bool
|
||||
xpc_bool_get_value(xpc_object_t xbool)
|
||||
{
|
||||
struct xpc_object *xo;
|
||||
|
||||
xo = xbool;
|
||||
if (xo == NULL)
|
||||
return (0);
|
||||
|
||||
if (xo->xo_xpc_type == _XPC_TYPE_BOOL)
|
||||
return (xo->xo_bool);
|
||||
|
||||
return (false);
|
||||
return xbool == XPC_BOOL_FALSE ? false : true;
|
||||
}
|
||||
|
||||
xpc_object_t
|
||||
|
Loading…
Reference in New Issue
Block a user