Skip to content

Commit 8bd1597

Browse files
committed
Add support for libxpc
1 parent 3fe43c2 commit 8bd1597

5 files changed

Lines changed: 284 additions & 26 deletions

File tree

Headers/GNUstepBase/GSConfig.h.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ typedef struct {
272272
#define GS_USE_LIBCURL @HAVE_LIBCURL@
273273
#define GS_USE_LIBDISPATCH @HAVE_LIBDISPATCH@
274274
#define GS_USE_LIBDISPATCH_RUNLOOP @HAVE_LIBDISPATCH_RUNLOOP@
275+
#define GS_USE_LIBXPC @HAVE_LIBXPC@
275276
#define GS_HAVE_FAST_ENUMERATION @OBJCFASTENUMERATION@
276277
#define GS_HAVE_FAST_ENUMERATION_SETTER @OBJCSETFASTENUMERATION@
277278
#define GS_HAVE_NSURLSESSION @GS_HAVE_NSURLSESSION@

Source/NSXPCConnection.m

Lines changed: 173 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -21,139 +21,286 @@
2121
Software Foundation, Inc., 31 Milk Street #960789 Boston, MA 02196 USA.
2222
*/
2323

24+
#import "common.h"
2425
#import "Foundation/NSXPCConnection.h"
2526
#import "GNUstepBase/NSObject+GNUstepBase.h"
27+
#import "GNUstepBase/GSConfig.h"
28+
29+
#if GS_USE_LIBXPC
30+
#include <xpc/xpc.h>
31+
#endif
32+
33+
@interface NSXPCConnection ()
34+
{
35+
NSString *_serviceName;
36+
NSXPCListenerEndpoint *_endpoint;
37+
NSXPCInterface *_exportedInterface;
38+
NSXPCInterface *_remoteObjectInterface;
39+
id _remoteObjectProxy;
40+
GSXPCInterruptionHandler _interruptionHandler;
41+
GSXPCInvalidationHandler _invalidationHandler;
42+
NSXPCConnectionOptions _options;
43+
BOOL _resumed;
44+
BOOL _invalidated;
45+
#if GS_USE_LIBXPC
46+
xpc_connection_t _xpcConnection;
47+
#endif
48+
}
49+
50+
- (void) _setupLibXPCConnectionIfPossible;
51+
@end
2652

2753
@implementation NSXPCConnection
2854

55+
- (instancetype) init
56+
{
57+
return [self initWithServiceName: nil];
58+
}
59+
60+
- (void) dealloc
61+
{
62+
[self invalidate];
63+
DESTROY(_serviceName);
64+
DESTROY(_endpoint);
65+
DESTROY(_exportedInterface);
66+
DESTROY(_remoteObjectInterface);
67+
DESTROY(_remoteObjectProxy);
68+
DESTROY(_interruptionHandler);
69+
DESTROY(_invalidationHandler);
70+
[super dealloc];
71+
}
72+
73+
- (void) _setupLibXPCConnectionIfPossible
74+
{
75+
#if GS_USE_LIBXPC
76+
uint64_t flags = 0;
77+
NSXPCConnection *connection = self;
78+
79+
if (_xpcConnection != NULL || _serviceName == nil || _invalidated == YES)
80+
{
81+
return;
82+
}
83+
#ifdef XPC_CONNECTION_MACH_SERVICE_PRIVILEGED
84+
if ((_options & NSXPCConnectionPrivileged) == NSXPCConnectionPrivileged)
85+
{
86+
flags |= XPC_CONNECTION_MACH_SERVICE_PRIVILEGED;
87+
}
88+
#endif
89+
_xpcConnection = xpc_connection_create_mach_service([_serviceName UTF8String],
90+
NULL, flags);
91+
if (_xpcConnection == NULL)
92+
{
93+
return;
94+
}
95+
96+
xpc_connection_set_event_handler(_xpcConnection, ^(xpc_object_t event) {
97+
if (event == XPC_ERROR_CONNECTION_INTERRUPTED)
98+
{
99+
if (connection->_interruptionHandler != NULL)
100+
{
101+
connection->_interruptionHandler();
102+
}
103+
}
104+
else if (event == XPC_ERROR_CONNECTION_INVALID)
105+
{
106+
connection->_invalidated = YES;
107+
if (connection->_invalidationHandler != NULL)
108+
{
109+
connection->_invalidationHandler();
110+
}
111+
}
112+
});
113+
114+
if (_resumed == YES)
115+
{
116+
xpc_connection_resume(_xpcConnection);
117+
}
118+
#endif
119+
}
120+
29121
- (instancetype) initWithServiceName:(NSString *)serviceName
30122
{
31-
return [self notImplemented: _cmd];
123+
return [self initWithMachServiceName: serviceName options: 0];
32124
}
33125

34126
- (NSString *) serviceName
35127
{
36-
return [self notImplemented: _cmd];
128+
return _serviceName;
37129
}
38130

39131
- (void) setServiceName: (NSString *)serviceName
40132
{
41-
[self notImplemented: _cmd];
133+
ASSIGNCOPY(_serviceName, serviceName);
134+
[self _setupLibXPCConnectionIfPossible];
42135
}
43136

44137
- (instancetype) initWithMachServiceName: (NSString *)name
45138
options: (NSXPCConnectionOptions)options
46139
{
47-
return [self notImplemented: _cmd];
140+
if ((self = [super init]) != nil)
141+
{
142+
_options = options;
143+
[self setServiceName: name];
144+
}
145+
return self;
48146
}
49147

50148
- (instancetype) initWithListenerEndpoint: (NSXPCListenerEndpoint *)endpoint
51149
{
52-
return [self notImplemented: _cmd];
150+
if ((self = [super init]) != nil)
151+
{
152+
ASSIGN(_endpoint, endpoint);
153+
}
154+
return self;
53155
}
54156

55157

56158
- (NSXPCListenerEndpoint *) endpoint
57159
{
58-
return [self notImplemented: _cmd];
160+
return _endpoint;
59161
}
60162

61163
- (void) setEndpoint: (NSXPCListenerEndpoint *) endpoint
62164
{
63-
[self notImplemented: _cmd];
165+
ASSIGN(_endpoint, endpoint);
64166
}
65167

66168
- (NSXPCInterface *) exportedInterface
67169
{
68-
return [self notImplemented: _cmd];
170+
return _exportedInterface;
69171
}
70172

71173
- (void) setExportInterface: (NSXPCInterface *)exportedInterface
72174
{
73-
[self notImplemented: _cmd];
175+
ASSIGN(_exportedInterface, exportedInterface);
74176
}
75177

76178
- (NSXPCInterface *) remoteObjectInterface
77179
{
78-
return [self notImplemented: _cmd];
180+
return _remoteObjectInterface;
79181
}
80182

81183
- (void) setRemoteObjectInterface: (NSXPCInterface *)remoteObjectInterface
82184
{
83-
[self notImplemented: _cmd];
185+
ASSIGN(_remoteObjectInterface, remoteObjectInterface);
84186
}
85187

86188
- (id) remoteObjectProxy
87189
{
88-
return [self notImplemented: _cmd];
190+
return _remoteObjectProxy;
89191
}
90192

91193
- (void) setRemoteObjectProxy: (id)remoteObjectProxy
92194
{
93-
[self notImplemented: _cmd];
195+
ASSIGN(_remoteObjectProxy, remoteObjectProxy);
94196
}
95197

96198
- (id) remoteObjectProxyWithErrorHandler:(GSXPCProxyErrorHandler)handler
97199
{
98-
return [self notImplemented: _cmd];
200+
return [self remoteObjectProxy];
99201
}
100202

101203
- (id) synchronousRemoteObjectProxyWithErrorHandler:
102204
(GSXPCProxyErrorHandler)handler
103205
{
104-
return [self notImplemented: _cmd];
206+
return [self remoteObjectProxy];
105207
}
106208

107209
- (GSXPCInterruptionHandler) interruptionHandler
108210
{
109-
return NULL;
211+
return _interruptionHandler;
110212
}
111213

112214
- (void) setInterruptionHandler: (GSXPCInterruptionHandler)handler
113215
{
114-
[self notImplemented: _cmd];
216+
ASSIGNCOPY(_interruptionHandler, handler);
115217
}
116218

117219
- (GSXPCInvalidationHandler) invalidationHandler
118220
{
119-
return NULL;
221+
return _invalidationHandler;
120222
}
121223

122224
- (void) setInvalidationHandler: (GSXPCInvalidationHandler)handler
123225
{
124-
[self notImplemented: _cmd];
226+
ASSIGNCOPY(_invalidationHandler, handler);
125227
}
126228

127229
- (void) resume
128230
{
129-
[self notImplemented: _cmd];
231+
_resumed = YES;
232+
[self _setupLibXPCConnectionIfPossible];
233+
#if GS_USE_LIBXPC
234+
if (_xpcConnection != NULL)
235+
{
236+
xpc_connection_resume(_xpcConnection);
237+
}
238+
#endif
130239
}
131240

132241
- (void) suspend
133242
{
134-
[self notImplemented: _cmd];
243+
_resumed = NO;
244+
#if GS_USE_LIBXPC
245+
if (_xpcConnection != NULL)
246+
{
247+
xpc_connection_suspend(_xpcConnection);
248+
}
249+
#endif
135250
}
136251

137252
- (void) invalidate
138253
{
139-
[self notImplemented: _cmd];
254+
BOOL wasInvalidated = _invalidated;
255+
256+
_invalidated = YES;
257+
#if GS_USE_LIBXPC
258+
if (_xpcConnection != NULL)
259+
{
260+
xpc_connection_cancel(_xpcConnection);
261+
xpc_release(_xpcConnection);
262+
_xpcConnection = NULL;
263+
}
264+
#endif
265+
if (wasInvalidated == NO && _invalidationHandler != NULL)
266+
{
267+
_invalidationHandler();
268+
}
140269
}
141270

142271
- (NSUInteger) auditSessionIdentifier
143272
{
144-
return (NSUInteger)[self notImplemented: _cmd];
273+
return 0;
145274
}
146275
- (pid_t) processIdentifier
147276
{
148-
return (pid_t)(uintptr_t)[self notImplemented: _cmd];
277+
#if GS_USE_LIBXPC
278+
if (_xpcConnection != NULL)
279+
{
280+
return xpc_connection_get_pid(_xpcConnection);
281+
}
282+
#endif
283+
return 0;
149284
}
150285
- (uid_t) effectiveUserIdentifier
151286
{
152-
return (uid_t)(uintptr_t)[self notImplemented: _cmd];
287+
#if GS_USE_LIBXPC
288+
if (_xpcConnection != NULL)
289+
{
290+
return xpc_connection_get_euid(_xpcConnection);
291+
}
292+
#endif
293+
return (uid_t)0;
153294
}
154295
- (gid_t) effectiveGroupIdentifier
155296
{
156-
return (gid_t)(uintptr_t)[self notImplemented: _cmd];
297+
#if GS_USE_LIBXPC
298+
if (_xpcConnection != NULL)
299+
{
300+
return xpc_connection_get_egid(_xpcConnection);
301+
}
302+
#endif
303+
return (gid_t)0;
157304
}
158305
@end
159306

config.mak.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ GNUSTEP_BASE_HAVE_ICU=@HAVE_ICU@
4242
GNUSTEP_BASE_HAVE_LIBCURL=@HAVE_LIBCURL@
4343
GNUSTEP_BASE_HAVE_LIBDISPATCH=@HAVE_LIBDISPATCH@
4444
GNUSTEP_BASE_HAVE_LIBDISPATCH_RUNLOOP=@HAVE_LIBDISPATCH_RUNLOOP@
45+
GNUSTEP_BASE_HAVE_LIBXPC=@HAVE_LIBXPC@
4546
GNUSTEP_BASE_HAVE_LIBXML=@HAVE_LIBXML@
4647
GNUSTEP_BASE_HAVE_MDNS=@HAVE_MDNS@
4748
GNUSTEP_BASE_WITH_NSURLSESSION=@GS_HAVE_NSURLSESSION@

0 commit comments

Comments
 (0)