mirror of
https://github.com/darlinghq/darling-Libnotify.git
synced 2024-11-23 04:09:49 +00:00
251 lines
8.2 KiB
C
251 lines
8.2 KiB
C
/*
|
|
* Copyright (c) 2003-2012 Apple Inc. All rights reserved.
|
|
*
|
|
* @APPLE_LICENSE_HEADER_START@
|
|
*
|
|
* This file contains Original Code and/or Modifications of Original Code
|
|
* as defined in and that are subject to the Apple Public Source License
|
|
* Version 2.0 (the 'License'). You may not use this file except in
|
|
* compliance with the License. Please obtain a copy of the License at
|
|
* http://www.opensource.apple.com/apsl/ and read it before using this
|
|
* file.
|
|
*
|
|
* The Original Code and all software distributed under the License are
|
|
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
|
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
|
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
|
* Please see the License for the specific language governing rights and
|
|
* limitations under the License.
|
|
*
|
|
* @APPLE_LICENSE_HEADER_END@
|
|
*/
|
|
|
|
#ifndef _LIBNOTIFY_H_
|
|
#define _LIBNOTIFY_H_
|
|
|
|
#include <os/lock.h>
|
|
#include <sys/queue.h>
|
|
#include <pthread.h>
|
|
#include <mach/mach.h>
|
|
#include <dispatch/dispatch.h>
|
|
#include <xpc/private.h>
|
|
#include "table.h"
|
|
|
|
#include <TargetConditionals.h>
|
|
|
|
extern const char *_notify_shm_id(void);
|
|
#define SHM_ID _notify_shm_id()
|
|
|
|
#define NOTIFY_IPC_VERSION_NAME "com.apple.system.notify.ipc_version"
|
|
#define NOTIFY_IPC_VERSION_NAME_LEN 35
|
|
#define NOTIFY_SERVICE_NAME "com.apple.system.notification_center"
|
|
#define NOTIFY_SERVICE_NAME_LEN 36
|
|
#define NOTIFY_IPC_VERSION_MIN_SUPPORTED 3
|
|
#define NOTIFY_IPC_VERSION 3
|
|
|
|
/* extra internal flags to notify_register_mach_port */
|
|
/* Make sure this doesn't conflict with any flags in notify.h or notify_private.h */
|
|
#define _NOTIFY_COMMON_PORT 0x40000000
|
|
|
|
/* Notification types */
|
|
#define NOTIFY_TYPE_NONE 0x00000000
|
|
#define NOTIFY_TYPE_MEMORY 0x00000001
|
|
#define NOTIFY_TYPE_PLAIN 0x00000002
|
|
#define NOTIFY_TYPE_PORT 0x00000003
|
|
#define NOTIFY_TYPE_FILE 0x00000004
|
|
#define NOTIFY_TYPE_SIGNAL 0x00000005
|
|
#define NOTIFY_TYPE_XPC_EVENT 0x00000006
|
|
#define NOTIFY_TYPE_COMMON_PORT 0x00000007
|
|
|
|
#define NOTIFY_TYPE_MASK 0x0000000f // If this is changed, make sure it doesn't muck with NOTIFY_CLIENT_STATE_*
|
|
#define N_NOTIFY_TYPES 8
|
|
|
|
|
|
#define NOTIFY_FLAG_SELF 0x80000000
|
|
#define NOTIFY_FLAG_REGEN 0x40000000
|
|
#define NOTIFY_FLAG_RELEASE_SEND 0x20000000
|
|
#define NOTIFY_FLAG_DISPATCH 0x10000000
|
|
#define NOTIFY_FLAG_COALESCE_BASE 0x08000000
|
|
#define NOTIFY_FLAG_COALESCED 0x04000000
|
|
#define NOTIFY_FLAG_RETAINED 0x02000000
|
|
#define NOTIFY_FLAG_CANCELED 0x01000000
|
|
#define NOTIFY_FLAG_SUSPENDED 0x00800000
|
|
#define NOTIFY_FLAG_DEFERRED_POST 0x00400000
|
|
|
|
#define notify_get_type(flags) ((flags) & NOTIFY_TYPE_MASK)
|
|
#define notify_is_type(flags, type) (notify_get_type(flags) == (type))
|
|
|
|
/* Return values for notify_check() */
|
|
#define NOTIFY_CHECK_FALSE 0
|
|
#define NOTIFY_CHECK_TRUE 1
|
|
#define NOTIFY_CHECK_ERROR 2
|
|
|
|
/* Access control */
|
|
#define NOTIFY_ACCESS_READ 1
|
|
#define NOTIFY_ACCESS_WRITE 2
|
|
|
|
#define NOTIFY_ACCESS_OTHER_SHIFT 8
|
|
#define NOTIFY_ACCESS_GROUP_SHIFT 4
|
|
#define NOTIFY_ACCESS_USER_SHIFT 0
|
|
|
|
#define NOTIFY_ACCESS_DEFAULT 0x00000333
|
|
#define NOTIFY_ACCESS_USER_RW 0x00000003
|
|
|
|
/* Filesystem Services */
|
|
#define NOTIFY_SERVICE_FILE_STATUS_QUO 0x00
|
|
#define NOTIFY_SERVICE_FILE_ADD 0x01
|
|
#define NOTIFY_SERVICE_FILE_DELETE 0x02
|
|
#define NOTIFY_SERVICE_FILE_MODIFY 0x04
|
|
#define NOTIFY_SERVICE_FILE_ATTR 0x08
|
|
|
|
#define NOTIFY_SERVICE_DIR_FILE_ADD 0x10
|
|
#define NOTIFY_SERVICE_DIR_FILE_DELETE 0x20
|
|
|
|
#define NOTIFY_CLIENT_STATE_SUSPENDED 0x00000020
|
|
#define NOTIFY_CLIENT_STATE_PENDING 0x00000040
|
|
#define NOTIFY_CLIENT_STATE_TIMEOUT 0x00000080
|
|
|
|
/* port_data_t::flags and proc_data_t::flags */
|
|
#define PORT_PROC_FLAGS_NONE 0x00000000
|
|
#define NOTIFY_PORT_PROC_STATE_SUSPENDED 0x00000001
|
|
#define NOTIFY_PORT_FLAG_COMMON 0x00000002
|
|
#define NOTIFY_PORT_FLAG_COMMON_READY_TO_FREE 0x00000004
|
|
|
|
/* notify state flags */
|
|
#define NOTIFY_STATE_USE_LOCKS 0x00000001
|
|
#define NOTIFY_STATE_ENABLE_RESEND 0x00000002
|
|
|
|
#define NOTIFY_XPC_EVENT_PAYLOAD_KEY_NAME "Notification"
|
|
#define NOTIFY_XPC_EVENT_PAYLOAD_KEY_STATE "_State"
|
|
|
|
#define NOTIFY_CLIENT_SELF 0
|
|
#define SIGNAL_NONE -1
|
|
#define FD_NONE -1
|
|
#define SLOT_NONE (uint32_t)~0
|
|
|
|
typedef struct
|
|
{
|
|
LIST_HEAD(, client_s) subscriptions;
|
|
char *name;
|
|
uint64_t name_id;
|
|
uint64_t state;
|
|
uint64_t state_time;
|
|
uint32_t uid;
|
|
uint32_t gid;
|
|
uint32_t access;
|
|
uint32_t slot;
|
|
uint32_t refcount;
|
|
uint32_t val;
|
|
uint32_t postcount;
|
|
uint32_t last_hour_postcount;
|
|
} name_info_t;
|
|
|
|
typedef union client_delivery_u
|
|
{
|
|
int fd;
|
|
mach_port_t port;
|
|
uint32_t sig;
|
|
uint64_t event_token;
|
|
} client_delivery_t;
|
|
|
|
typedef struct client_s
|
|
{
|
|
LIST_ENTRY(client_s) client_subscription_entry;
|
|
LIST_ENTRY(client_s) client_pid_entry;
|
|
LIST_ENTRY(client_s) client_port_entry;
|
|
name_info_t *name_info;
|
|
client_delivery_t deliver;
|
|
union client_id {
|
|
struct {
|
|
uint32_t token;
|
|
uint32_t pid;
|
|
};
|
|
uint64_t hash_key;
|
|
} cid;
|
|
uint32_t lastval;
|
|
uint16_t service_index;
|
|
uint8_t suspend_count;
|
|
uint8_t state_and_type;
|
|
} client_t;
|
|
|
|
typedef struct
|
|
{
|
|
LIST_HEAD(, client_s) clients;
|
|
mach_port_t port;
|
|
uint32_t flags;
|
|
} port_data_t;
|
|
|
|
typedef struct
|
|
{
|
|
LIST_HEAD(, client_s) clients;
|
|
dispatch_source_t src;
|
|
uint32_t pid;
|
|
uint32_t flags;
|
|
port_data_t *common_port_data;
|
|
} proc_data_t;
|
|
|
|
typedef struct
|
|
{
|
|
client_t *client;
|
|
uint64_t event_token;
|
|
} event_data_t;
|
|
|
|
typedef struct
|
|
{
|
|
/* last allocated name id */
|
|
uint64_t name_id;
|
|
table_t name_table;
|
|
table_64_t name_id_table;
|
|
table_64_t client_table;
|
|
table_n_t port_table;
|
|
table_n_t proc_table;
|
|
table_64_t event_table;
|
|
name_info_t **controlled_name;
|
|
xpc_event_publisher_t event_publisher;
|
|
uint32_t flags;
|
|
uint32_t controlled_name_count;
|
|
os_unfair_lock lock;
|
|
int sock;
|
|
uint32_t stat_name_alloc;
|
|
uint32_t stat_name_free;
|
|
uint32_t stat_client_alloc;
|
|
uint32_t stat_client_free;
|
|
uint32_t stat_portproc_alloc;
|
|
uint32_t stat_portproc_free;
|
|
} notify_state_t;
|
|
|
|
void _notify_lib_notify_state_init(notify_state_t * ns, uint32_t flags);
|
|
|
|
uint32_t _notify_lib_post(notify_state_t *ns, const char *name, uint32_t uid, uint32_t gid);
|
|
uint32_t _notify_lib_post_nid(notify_state_t *ns, uint64_t nid, uid_t uid, gid_t gid);
|
|
uint32_t _notify_lib_post_client(notify_state_t *ns, client_t *c);
|
|
|
|
uint32_t _notify_lib_check(notify_state_t *ns, pid_t pid, int token, int *check);
|
|
uint32_t _notify_lib_get_state(notify_state_t *ns, uint64_t nid, uint64_t *state, uint32_t uid, uint32_t gid);
|
|
uint32_t _notify_lib_set_state(notify_state_t *ns, uint64_t nid, uint64_t state, uint32_t uid, uint32_t gid);
|
|
|
|
uint32_t _notify_lib_register_plain(notify_state_t *ns, const char *name, pid_t pid, int token, uint32_t slot, uint32_t uid, uint32_t gid, uint64_t *out_nid);
|
|
uint32_t _notify_lib_register_signal(notify_state_t *ns, const char *name, pid_t pid, int token, uint32_t sig, uint32_t uid, uint32_t gid, uint64_t *out_nid);
|
|
uint32_t _notify_lib_register_mach_port(notify_state_t *ns, const char *name, pid_t pid, int token, mach_port_t port, uint32_t uid, uint32_t gid, uint64_t *out_nid);
|
|
uint32_t _notify_lib_register_file_descriptor(notify_state_t *ns, const char *name, pid_t pid, int token, int fd, uint32_t uid, uint32_t gid, uint64_t *out_nid);
|
|
uint32_t _notify_lib_register_xpc_event(notify_state_t *ns, const char *name, pid_t pid, int token, uint64_t event_token, uid_t uid, gid_t gid, uint64_t *out_nid);
|
|
uint32_t _notify_lib_register_common_port(notify_state_t *ns, const char *name, pid_t pid, int token, uid_t uid, gid_t gid, uint64_t *out_nid);
|
|
|
|
uint32_t _notify_lib_set_owner(notify_state_t *ns, const char *name, uint32_t uid, uint32_t gid);
|
|
uint32_t _notify_lib_set_access(notify_state_t *ns, const char *name, uint32_t access);
|
|
|
|
void _notify_lib_resume_client(notify_state_t *ns, client_t *c, proc_data_t *proc_data, port_data_t *port_data);
|
|
void _notify_lib_cancel_client(notify_state_t *ns, client_t *c);
|
|
|
|
void _notify_lib_cancel(notify_state_t *ns, pid_t pid, int token);
|
|
uint32_t _notify_lib_suspend(notify_state_t *ns, pid_t pid, int token);
|
|
uint32_t _notify_lib_resume(notify_state_t *ns, pid_t pid, int token);
|
|
|
|
uint32_t _notify_lib_check_controlled_access(notify_state_t *ns, char *name, uid_t uid, gid_t gid, int req);
|
|
|
|
uint64_t make_client_id(pid_t pid, int token);
|
|
|
|
|
|
#endif /* _LIBNOTIFY_H_ */
|