Libnotify-241

This commit is contained in:
Ariel Abreu 2020-06-16 15:14:48 -04:00
parent 7c4e4da0de
commit 93ccfa643c
No known key found for this signature in database
GPG Key ID: F4D43CC7053EA2B3
51 changed files with 6698 additions and 4799 deletions

View File

@ -20,16 +20,27 @@
name = cli_apps;
productName = cli_apps;
};
72FA84FB1BD6EAB900A4CC6F /* tests */ = {
isa = PBXAggregateTarget;
buildConfigurationList = 72FA84FC1BD6EAB900A4CC6F /* Build configuration list for PBXAggregateTarget "tests" */;
buildPhases = (
);
dependencies = (
72FA84FF1BD6EC2000A4CC6F /* PBXTargetDependency */,
);
name = tests;
productName = tests;
};
/* End PBXAggregateTarget section */
/* Begin PBXBuildFile section */
1886391920E1A2BF00C8BEA9 /* notify_bench.c in Sources */ = {isa = PBXBuildFile; fileRef = 727C90371B9A372700D5B754 /* notify_bench.c */; };
2D312B76102CA2E300F90022 /* libnotify.c in Sources */ = {isa = PBXBuildFile; fileRef = 2D312B73102CA2E300F90022 /* libnotify.c */; };
2D312B77102CA2E300F90022 /* notify_client.c in Sources */ = {isa = PBXBuildFile; fileRef = 2D312B74102CA2E300F90022 /* notify_client.c */; };
2D312B78102CA2E300F90022 /* table.c in Sources */ = {isa = PBXBuildFile; fileRef = 2D312B75102CA2E300F90022 /* table.c */; };
2D312B7A102CA30200F90022 /* notify_ipc.defs in Sources */ = {isa = PBXBuildFile; fileRef = 2D312B79102CA30200F90022 /* notify_ipc.defs */; settings = {ATTRIBUTES = (Client, ); }; };
2D312B7E102CA32500F90022 /* notify_keys.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D312B7C102CA32500F90022 /* notify_keys.h */; settings = {ATTRIBUTES = (Public, ); }; };
2D312B7F102CA32500F90022 /* notify.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D312B7D102CA32500F90022 /* notify.h */; settings = {ATTRIBUTES = (Public, ); }; };
2D312B82102CA34D00F90022 /* libnotify.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D312B81102CA34D00F90022 /* libnotify.h */; settings = {ATTRIBUTES = (Private, ); }; };
2D312B87102CA36C00F90022 /* table.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D312B85102CA36C00F90022 /* table.h */; };
2D38AA0A102CD88300D3D622 /* notify.3 in Copy man3 Files */ = {isa = PBXBuildFile; fileRef = 2D312B92102CA38F00F90022 /* notify.3 */; };
2D38AA0B102CD89B00D3D622 /* notify_cancel.3 in Copy man3 Files */ = {isa = PBXBuildFile; fileRef = 2D312B88102CA38F00F90022 /* notify_cancel.3 */; };
@ -43,6 +54,7 @@
2D38AA13102CD8B800D3D622 /* notify_register_mach_port.3 in Copy man3 Files */ = {isa = PBXBuildFile; fileRef = 2D312B8F102CA38F00F90022 /* notify_register_mach_port.3 */; };
2D38AA14102CD8B800D3D622 /* notify_register_signal.3 in Copy man3 Files */ = {isa = PBXBuildFile; fileRef = 2D312B90102CA38F00F90022 /* notify_register_signal.3 */; };
2D38AA15102CD8B800D3D622 /* notify_set_state.3 in Copy man3 Files */ = {isa = PBXBuildFile; fileRef = 2D312B91102CA38F00F90022 /* notify_set_state.3 */; };
2D4F060B1B14E7DF00D59CEF /* com.apple.notifyd.sb in Install Sandbox profile */ = {isa = PBXBuildFile; fileRef = 2DD962061B14E6560040D341 /* com.apple.notifyd.sb */; };
2DCB287210D99ADA00DF3A8D /* notify_private.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DCB287110D99ADA00DF3A8D /* notify_private.h */; settings = {ATTRIBUTES = (Private, ); }; };
3FA21ACF148AAA5000099D2F /* notify_proc.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FA21A9C148AA7FA00099D2F /* notify_proc.c */; };
3FA21AD0148AAA5000099D2F /* notifyd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FA21A9E148AA7FA00099D2F /* notifyd.c */; };
@ -55,6 +67,16 @@
3FA21AD8148AAABE00099D2F /* com.apple.notifyd.plist in Install launchd.plist */ = {isa = PBXBuildFile; fileRef = 3FA21A99148AA7FA00099D2F /* com.apple.notifyd.plist */; };
3FA21AE6148AAEAC00099D2F /* notify_ipc.defs in Sources */ = {isa = PBXBuildFile; fileRef = 2D312B79102CA30200F90022 /* notify_ipc.defs */; settings = {ATTRIBUTES = (Client, Server, ); }; };
3FD0DBAD148AB12000C50811 /* libbsm.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 3FD0DBAC148AB12000C50811 /* libbsm.dylib */; };
6E8E6AD02282A7DA0084C085 /* notify.defs in Sources */ = {isa = PBXBuildFile; fileRef = 6E8E6ACD2282A7DA0084C085 /* notify.defs */; settings = {ATTRIBUTES = (Server, ); }; };
6EC91ED52178FF7100F11587 /* libCrashReporterClient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6EC91ED42178FF7100F11587 /* libCrashReporterClient.a */; };
94099C762087E7D50004B6BC /* RegisterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 94099C752087E7D50004B6BC /* RegisterTests.m */; settings = {COMPILER_FLAGS = "-Wno-gnu-statement-expression -fobjc-exceptions"; }; };
9456B8522023CAB300CF7D27 /* libnotify.c in Sources */ = {isa = PBXBuildFile; fileRef = 2D312B73102CA2E300F90022 /* libnotify.c */; };
9456B8532023CAB600CF7D27 /* table.c in Sources */ = {isa = PBXBuildFile; fileRef = 2D312B75102CA2E300F90022 /* table.c */; };
9487BF2A2089A99A0043BF74 /* notify_client.c in Sources */ = {isa = PBXBuildFile; fileRef = 2D312B74102CA2E300F90022 /* notify_client.c */; };
9487BF2B2089A9E30043BF74 /* notify_ipc.defs in Sources */ = {isa = PBXBuildFile; fileRef = 2D312B79102CA30200F90022 /* notify_ipc.defs */; };
9487BF2C2089BAA30043BF74 /* table.c in Sources */ = {isa = PBXBuildFile; fileRef = 2D312B75102CA2E300F90022 /* table.c */; };
9487BF2D2089BAB20043BF74 /* libnotify.c in Sources */ = {isa = PBXBuildFile; fileRef = 2D312B73102CA2E300F90022 /* libnotify.c */; };
E6481E7F2165785F00C04412 /* notify_probes.d in Sources */ = {isa = PBXBuildFile; fileRef = E6481E7E2165785F00C04412 /* notify_probes.d */; };
FC7B7A53155781930064D203 /* notify_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = FC7B7A52155781930064D203 /* notify_internal.h */; };
/* End PBXBuildFile section */
@ -73,13 +95,30 @@
remoteGlobalIDString = 3FA21ABD148AA8F000099D2F;
remoteInfo = notifyutil;
};
72FA84FE1BD6EC2000A4CC6F /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 72FA84F61BD6E9DF00A4CC6F;
remoteInfo = darwintests;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
1886391220E1A22F00C8BEA9 /* Install man page */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = /usr/share/man/man1;
dstSubfolderSpec = 0;
files = (
);
name = "Install man page";
runOnlyForDeploymentPostprocessing = 1;
};
2D38AA09102CD87C00D3D622 /* Copy man3 Files */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 8;
dstPath = "$(INSTALL_PATH_PREFIX)/usr/share/man/man3";
dstPath = /usr/share/man/man3;
dstSubfolderSpec = 0;
files = (
2D38AA0A102CD88300D3D622 /* notify.3 in Copy man3 Files */,
@ -98,10 +137,21 @@
name = "Copy man3 Files";
runOnlyForDeploymentPostprocessing = 1;
};
2D4F060A1B14E79900D59CEF /* Install Sandbox profile */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 8;
dstPath = /System/Library/Sandbox/Profiles;
dstSubfolderSpec = 0;
files = (
2D4F060B1B14E7DF00D59CEF /* com.apple.notifyd.sb in Install Sandbox profile */,
);
name = "Install Sandbox profile";
runOnlyForDeploymentPostprocessing = 1;
};
3FA21AAE148AA8E300099D2F /* Install man page */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "$(INSTALL_PATH_PREFIX)/usr/share/man/man8";
dstPath = /usr/share/man/man8;
dstSubfolderSpec = 0;
files = (
3FA21AD4148AAA5D00099D2F /* notifyd.8 in Install man page */,
@ -112,7 +162,7 @@
3FA21ABC148AA8F000099D2F /* Install man page */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "$(INSTALL_PATH_PREFIX)/usr/share/man/man1";
dstPath = /usr/share/man/man1;
dstSubfolderSpec = 0;
files = (
3FA21AD6148AAA7500099D2F /* notifyutil.1 in Install man page */,
@ -123,7 +173,7 @@
3FA21AD7148AAAA600099D2F /* Install launchd.plist */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 8;
dstPath = "$(INSTALL_PATH_PREFIX)/System/Library/LaunchDaemons";
dstPath = /System/Library/LaunchDaemons;
dstSubfolderSpec = 0;
files = (
3FA21AD8148AAABE00099D2F /* com.apple.notifyd.plist in Install launchd.plist */,
@ -134,15 +184,21 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
2D312B73102CA2E300F90022 /* libnotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = libnotify.c; sourceTree = "<group>"; };
2D312B74102CA2E300F90022 /* notify_client.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = notify_client.c; sourceTree = "<group>"; };
180F8D3E21136EBF009A472B /* notify_pathwatch.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = notify_pathwatch.c; sourceTree = "<group>"; };
182FD2C2210BB0F600BF263C /* notify_benchmark.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = notify_benchmark.c; sourceTree = "<group>"; };
18314CC821FF867600FEB43D /* notifyutil_entitlements.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = notifyutil_entitlements.plist; sourceTree = "<group>"; };
18383C6720F909A300D5C465 /* notify_regenerate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = notify_regenerate.c; sourceTree = "<group>"; };
18383C6820F909A300D5C465 /* notify_register_signal.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = notify_register_signal.c; sourceTree = "<group>"; };
18383C6920F909A300D5C465 /* notify_sigusr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = notify_sigusr.c; sourceTree = "<group>"; };
1886391720E1A22F00C8BEA9 /* notifybench */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = notifybench; sourceTree = BUILT_PRODUCTS_DIR; };
2D312B73102CA2E300F90022 /* libnotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = libnotify.c; sourceTree = "<group>"; usesTabs = 1; };
2D312B74102CA2E300F90022 /* notify_client.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = notify_client.c; sourceTree = "<group>"; usesTabs = 1; };
2D312B75102CA2E300F90022 /* table.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = table.c; sourceTree = "<group>"; };
2D312B79102CA30200F90022 /* notify_ipc.defs */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.mig; path = notify_ipc.defs; sourceTree = "<group>"; };
2D312B7C102CA32500F90022 /* notify_keys.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = notify_keys.h; sourceTree = "<group>"; };
2D312B7D102CA32500F90022 /* notify.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = notify.h; sourceTree = "<group>"; };
2D312B81102CA34D00F90022 /* libnotify.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = libnotify.h; sourceTree = "<group>"; };
2D312B84102CA36C00F90022 /* notify_ipc_types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = notify_ipc_types.h; sourceTree = "<group>"; };
2D312B85102CA36C00F90022 /* table.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = table.h; sourceTree = "<group>"; };
2D312B81102CA34D00F90022 /* libnotify.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = libnotify.h; sourceTree = "<group>"; usesTabs = 1; };
2D312B85102CA36C00F90022 /* table.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = table.h; sourceTree = "<group>"; usesTabs = 1; };
2D312B88102CA38F00F90022 /* notify_cancel.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = notify_cancel.3; sourceTree = "<group>"; };
2D312B89102CA38F00F90022 /* notify_check.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = notify_check.3; sourceTree = "<group>"; };
2D312B8A102CA38F00F90022 /* notify_get_state.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = notify_get_state.3; sourceTree = "<group>"; };
@ -156,6 +212,7 @@
2D312B92102CA38F00F90022 /* notify.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = notify.3; sourceTree = "<group>"; };
2D6D820D18DA602A0034E7B4 /* notify_is_valid_token.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = notify_is_valid_token.3; sourceTree = "<group>"; };
2DCB287110D99ADA00DF3A8D /* notify_private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = notify_private.h; sourceTree = "<group>"; };
2DD962061B14E6560040D341 /* com.apple.notifyd.sb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = com.apple.notifyd.sb; sourceTree = "<group>"; };
2DF9EA0B102CF33400DE9E8D /* APPLE_LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = APPLE_LICENSE; sourceTree = "<group>"; };
3F82235D12B18551005DD509 /* libnotify.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = libnotify.xcconfig; sourceTree = "<group>"; };
3F8223B412B18877005DD509 /* libsystem_notify.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libsystem_notify.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
@ -167,15 +224,14 @@
3FA21A99148AA7FA00099D2F /* com.apple.notifyd.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = com.apple.notifyd.plist; sourceTree = "<group>"; };
3FA21A9A148AA7FA00099D2F /* notify.conf */ = {isa = PBXFileReference; lastKnownFileType = text; path = notify.conf; sourceTree = "<group>"; };
3FA21A9B148AA7FA00099D2F /* notify.conf.iPhone */ = {isa = PBXFileReference; lastKnownFileType = text; name = notify.conf.iPhone; path = ../notify.conf.iPhone; sourceTree = "<group>"; };
3FA21A9C148AA7FA00099D2F /* notify_proc.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = notify_proc.c; sourceTree = "<group>"; };
3FA21A9C148AA7FA00099D2F /* notify_proc.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = notify_proc.c; sourceTree = "<group>"; usesTabs = 1; };
3FA21A9D148AA7FA00099D2F /* notifyd.8 */ = {isa = PBXFileReference; lastKnownFileType = text; path = notifyd.8; sourceTree = "<group>"; };
3FA21A9E148AA7FA00099D2F /* notifyd.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = notifyd.c; sourceTree = "<group>"; };
3FA21A9F148AA7FA00099D2F /* notifyd.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = notifyd.h; sourceTree = "<group>"; };
3FA21A9E148AA7FA00099D2F /* notifyd.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = notifyd.c; sourceTree = "<group>"; usesTabs = 1; };
3FA21A9F148AA7FA00099D2F /* notifyd.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = notifyd.h; sourceTree = "<group>"; usesTabs = 1; };
3FA21AA0148AA7FA00099D2F /* pathwatch.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = pathwatch.c; sourceTree = "<group>"; };
3FA21AA1148AA7FA00099D2F /* pathwatch.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = pathwatch.h; sourceTree = "<group>"; };
3FA21AA2148AA7FA00099D2F /* service.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = service.c; sourceTree = "<group>"; };
3FA21AA2148AA7FA00099D2F /* service.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = service.c; sourceTree = "<group>"; usesTabs = 1; };
3FA21AA3148AA7FA00099D2F /* service.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = service.h; sourceTree = "<group>"; };
3FA21AA4148AA7FA00099D2F /* table.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = table.h; sourceTree = "<group>"; };
3FA21AA5148AA7FA00099D2F /* timer.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = timer.c; sourceTree = "<group>"; };
3FA21AA6148AA7FA00099D2F /* timer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = timer.h; sourceTree = "<group>"; };
3FA21AA8148AA82700099D2F /* notifyutil.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = notifyutil.1; sourceTree = "<group>"; };
@ -185,10 +241,34 @@
3FA21ADD148AABA900099D2F /* mk_notify_conf.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = mk_notify_conf.sh; sourceTree = "<group>"; };
3FA21ADF148AACA000099D2F /* notify.conf.MacOSX */ = {isa = PBXFileReference; lastKnownFileType = text; name = notify.conf.MacOSX; path = notifyd/notify.conf.MacOSX; sourceTree = SOURCE_ROOT; };
3FD0DBAC148AB12000C50811 /* libbsm.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libbsm.dylib; path = /usr/lib/libbsm.dylib; sourceTree = "<absolute>"; };
FC7B7A52155781930064D203 /* notify_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = notify_internal.h; sourceTree = "<group>"; };
6E8DAA2E2184283500A90CEA /* table.in.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = table.in.c; sourceTree = "<group>"; usesTabs = 1; };
6E8E6ACC2282A7D30084C085 /* notify.defs */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.mig; name = notify.defs; path = usr/include/mach/notify.defs; sourceTree = SDKROOT; };
6E8E6ACD2282A7DA0084C085 /* notify.defs */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.mig; name = notify.defs; path = usr/include/mach/notify.defs; sourceTree = SDKROOT; };
6EC91ED42178FF7100F11587 /* libCrashReporterClient.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libCrashReporterClient.a; path = /usr/local/lib/libCrashReporterClient.a; sourceTree = "<absolute>"; };
727C90301B9A372700D5B754 /* dispatch_cancel_in_block.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dispatch_cancel_in_block.c; sourceTree = "<group>"; };
727C90341B9A372700D5B754 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
727C90371B9A372700D5B754 /* notify_bench.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = notify_bench.c; sourceTree = "<group>"; };
727C90381B9A372700D5B754 /* notify_control.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = notify_control.c; sourceTree = "<group>"; };
727C90391B9A372700D5B754 /* notify_disable_test.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = notify_disable_test.c; sourceTree = "<group>"; };
727C903A1B9A372700D5B754 /* notify_many_dups.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = notify_many_dups.c; sourceTree = "<group>"; };
727C903B1B9A372700D5B754 /* random_test.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = random_test.c; sourceTree = "<group>"; };
94099C732087E7D50004B6BC /* xctests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = xctests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
94099C752087E7D50004B6BC /* RegisterTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RegisterTests.m; sourceTree = "<group>"; };
94099C772087E7D50004B6BC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
9487BF2820882DAD0043BF74 /* parallel_register_cancel.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = parallel_register_cancel.c; sourceTree = "<group>"; };
9B71D22F206AB52200BB9574 /* notify_qos.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = notify_qos.c; sourceTree = "<group>"; };
E6481E7E2165785F00C04412 /* notify_probes.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; path = notify_probes.d; sourceTree = "<group>"; };
FC7B7A52155781930064D203 /* notify_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = notify_internal.h; sourceTree = "<group>"; usesTabs = 1; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
1886391120E1A22F00C8BEA9 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
3FA21AAD148AA8E300099D2F /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@ -204,10 +284,18 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
94099C702087E7D50004B6BC /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
D289987405E68DCB004EDB86 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
6EC91ED52178FF7100F11587 /* libCrashReporterClient.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -217,24 +305,41 @@
08FB7794FE84155DC02AAC07 /* Libnotify */ = {
isa = PBXGroup;
children = (
1886391820E1A24A00C8BEA9 /* notifybench */,
3F94777F191C322100A93E8E /* xcodescripts */,
3F999960185C474E00EAD3A0 /* xcodeconfig */,
2D312B79102CA30200F90022 /* notify_ipc.defs */,
6E8E6ACD2282A7DA0084C085 /* notify.defs */,
3FA21A97148AA7CD00099D2F /* libsystem_notify */,
3FA21AA7148AA82700099D2F /* notifyutil */,
3FA21A98148AA7FA00099D2F /* notifyd */,
2DF9EA0A102CF31700DE9E8D /* Additional Files */,
94099C742087E7D50004B6BC /* xctests */,
3FA21ACE148AAA0D00099D2F /* Products */,
727C902F1B9A372700D5B754 /* tests */,
94099C732087E7D50004B6BC /* xctests.xctest */,
1886391720E1A22F00C8BEA9 /* notifybench */,
6EC91ED32178FF7100F11587 /* Frameworks */,
);
name = Libnotify;
sourceTree = "<group>";
};
1886391820E1A24A00C8BEA9 /* notifybench */ = {
isa = PBXGroup;
children = (
727C90371B9A372700D5B754 /* notify_bench.c */,
);
path = notifybench;
sourceTree = "<group>";
};
2D312B72102CA2C400F90022 /* Source */ = {
isa = PBXGroup;
children = (
E6481E7E2165785F00C04412 /* notify_probes.d */,
2D312B73102CA2E300F90022 /* libnotify.c */,
2D312B74102CA2E300F90022 /* notify_client.c */,
2D312B75102CA2E300F90022 /* table.c */,
6E8DAA2E2184283500A90CEA /* table.in.c */,
);
name = Source;
sourceTree = "<group>";
@ -261,7 +366,6 @@
isa = PBXGroup;
children = (
FC7B7A52155781930064D203 /* notify_internal.h */,
2D312B84102CA36C00F90022 /* notify_ipc_types.h */,
2D312B85102CA36C00F90022 /* table.h */,
);
name = "Project Headers";
@ -287,6 +391,7 @@
3F999960185C474E00EAD3A0 /* xcodeconfig */ = {
isa = PBXGroup;
children = (
6E8E6ACC2282A7D30084C085 /* notify.defs */,
3F999961185C474E00EAD3A0 /* base.xcconfig */,
3F82235D12B18551005DD509 /* libnotify.xcconfig */,
3F999963185C474E00EAD3A0 /* notifyd.xcconfig */,
@ -310,6 +415,7 @@
3FA21A98148AA7FA00099D2F /* notifyd */ = {
isa = PBXGroup;
children = (
2DD962061B14E6560040D341 /* com.apple.notifyd.sb */,
3FA21ADC148AABA900099D2F /* Build Support */,
3FA21A99148AA7FA00099D2F /* com.apple.notifyd.plist */,
3FA21A9A148AA7FA00099D2F /* notify.conf */,
@ -325,6 +431,7 @@
children = (
3FA21AA8148AA82700099D2F /* notifyutil.1 */,
3FA21AA9148AA82700099D2F /* notifyutil.c */,
18314CC821FF867600FEB43D /* notifyutil_entitlements.plist */,
);
path = notifyutil;
sourceTree = "<group>";
@ -347,7 +454,6 @@
3FA21A9F148AA7FA00099D2F /* notifyd.h */,
3FA21AA1148AA7FA00099D2F /* pathwatch.h */,
3FA21AA3148AA7FA00099D2F /* service.h */,
3FA21AA4148AA7FA00099D2F /* table.h */,
3FA21AA6148AA7FA00099D2F /* timer.h */,
);
name = "Private Headers";
@ -375,6 +481,43 @@
path = xcodescripts;
sourceTree = "<group>";
};
6EC91ED32178FF7100F11587 /* Frameworks */ = {
isa = PBXGroup;
children = (
6EC91ED42178FF7100F11587 /* libCrashReporterClient.a */,
);
name = Frameworks;
sourceTree = "<group>";
};
727C902F1B9A372700D5B754 /* tests */ = {
isa = PBXGroup;
children = (
18383C6720F909A300D5C465 /* notify_regenerate.c */,
18383C6820F909A300D5C465 /* notify_register_signal.c */,
18383C6920F909A300D5C465 /* notify_sigusr.c */,
727C90341B9A372700D5B754 /* Makefile */,
9B71D22F206AB52200BB9574 /* notify_qos.c */,
727C90301B9A372700D5B754 /* dispatch_cancel_in_block.c */,
727C90381B9A372700D5B754 /* notify_control.c */,
727C90391B9A372700D5B754 /* notify_disable_test.c */,
727C903A1B9A372700D5B754 /* notify_many_dups.c */,
727C903B1B9A372700D5B754 /* random_test.c */,
9487BF2820882DAD0043BF74 /* parallel_register_cancel.c */,
182FD2C2210BB0F600BF263C /* notify_benchmark.c */,
180F8D3E21136EBF009A472B /* notify_pathwatch.c */,
);
path = tests;
sourceTree = "<group>";
};
94099C742087E7D50004B6BC /* xctests */ = {
isa = PBXGroup;
children = (
94099C752087E7D50004B6BC /* RegisterTests.m */,
94099C772087E7D50004B6BC /* Info.plist */,
);
path = xctests;
sourceTree = "<group>";
};
C6A0FF2B0290797F04C91782 /* Documentation */ = {
isa = PBXGroup;
children = (
@ -403,7 +546,6 @@
files = (
2D312B7E102CA32500F90022 /* notify_keys.h in Headers */,
2D312B7F102CA32500F90022 /* notify.h in Headers */,
2D312B82102CA34D00F90022 /* libnotify.h in Headers */,
2D312B87102CA36C00F90022 /* table.h in Headers */,
2DCB287210D99ADA00DF3A8D /* notify_private.h in Headers */,
FC7B7A53155781930064D203 /* notify_internal.h in Headers */,
@ -412,7 +554,41 @@
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXLegacyTarget section */
72FA84F61BD6E9DF00A4CC6F /* darwintests */ = {
isa = PBXLegacyTarget;
buildArgumentsString = "$(ACTION)";
buildConfigurationList = 72FA84F71BD6E9DF00A4CC6F /* Build configuration list for PBXLegacyTarget "darwintests" */;
buildPhases = (
);
buildToolPath = /usr/bin/make;
buildWorkingDirectory = tests;
dependencies = (
);
name = darwintests;
passBuildSettingsInEnvironment = 1;
productName = darwintests;
};
/* End PBXLegacyTarget section */
/* Begin PBXNativeTarget section */
1886390E20E1A22F00C8BEA9 /* notifybench */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1886391420E1A22F00C8BEA9 /* Build configuration list for PBXNativeTarget "notifybench" */;
buildPhases = (
1886390F20E1A22F00C8BEA9 /* Sources */,
1886391120E1A22F00C8BEA9 /* Frameworks */,
1886391220E1A22F00C8BEA9 /* Install man page */,
);
buildRules = (
);
dependencies = (
);
name = notifybench;
productName = notifyutil;
productReference = 1886391720E1A22F00C8BEA9 /* notifybench */;
productType = "com.apple.product-type.tool";
};
3FA21AAF148AA8E300099D2F /* notifyd */ = {
isa = PBXNativeTarget;
buildConfigurationList = 3FA21AB8148AA8E300099D2F /* Build configuration list for PBXNativeTarget "notifyd" */;
@ -422,6 +598,7 @@
3FA21AAE148AA8E300099D2F /* Install man page */,
3FA21AD7148AAAA600099D2F /* Install launchd.plist */,
3FA21ADB148AAB1C00099D2F /* Install notify.conf */,
2D4F060A1B14E79900D59CEF /* Install Sandbox profile */,
);
buildRules = (
);
@ -449,6 +626,23 @@
productReference = 3FA21ABE148AA8F000099D2F /* notifyutil */;
productType = "com.apple.product-type.tool";
};
94099C722087E7D50004B6BC /* xctests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 94099C792087E7D50004B6BC /* Build configuration list for PBXNativeTarget "xctests" */;
buildPhases = (
94099C6F2087E7D50004B6BC /* Sources */,
94099C702087E7D50004B6BC /* Frameworks */,
94099C712087E7D50004B6BC /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = xctests;
productName = xctests;
productReference = 94099C732087E7D50004B6BC /* xctests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
D2AAC045055464E500DB518D /* libnotify */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1DEB91EB08733DB70010E9CD /* Build configuration list for PBXNativeTarget "libnotify" */;
@ -475,6 +669,17 @@
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
attributes = {
TargetAttributes = {
72FA84F61BD6E9DF00A4CC6F = {
CreatedOnToolsVersion = 7.1;
};
72FA84FB1BD6EAB900A4CC6F = {
CreatedOnToolsVersion = 7.1;
};
94099C722087E7D50004B6BC = {
CreatedOnToolsVersion = 10.0;
};
};
};
buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "Libnotify" */;
compatibilityVersion = "Xcode 3.1";
@ -494,11 +699,25 @@
D2AAC045055464E500DB518D /* libnotify */,
3FA21AAF148AA8E300099D2F /* notifyd */,
3FA21ABD148AA8F000099D2F /* notifyutil */,
1886390E20E1A22F00C8BEA9 /* notifybench */,
3FA21AC7148AA93000099D2F /* cli_apps */,
72FA84F61BD6E9DF00A4CC6F /* darwintests */,
72FA84FB1BD6EAB900A4CC6F /* tests */,
94099C722087E7D50004B6BC /* xctests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
94099C712087E7D50004B6BC /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
3F947782191C324900A93E8E /* No Simulator Man Pages */ = {
isa = PBXShellScriptBuildPhase;
@ -558,18 +777,29 @@
);
runOnlyForDeploymentPostprocessing = 1;
shellPath = "/bin/bash -e -x";
shellScript = "exec \"${SCRIPT_INPUT_FILE_0}\"";
shellScript = "if [ $(id -u) != 0 ]; then\n\tosascript -e \"do shell script quoted form of \\\"${SRCROOT}/notifyd/xcodescripts/mk_notify_conf.sh\\\" with administrator privileges\"\nelse\n\texec \"${SCRIPT_INPUT_FILE_0}\"\nfi\n";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
1886390F20E1A22F00C8BEA9 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
1886391920E1A2BF00C8BEA9 /* notify_bench.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
3FA21AAC148AA8E300099D2F /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
6E8E6AD02282A7DA0084C085 /* notify.defs in Sources */,
9456B8532023CAB600CF7D27 /* table.c in Sources */,
3FA21AE6148AAEAC00099D2F /* notify_ipc.defs in Sources */,
3FA21ACF148AAA5000099D2F /* notify_proc.c in Sources */,
3FA21AD0148AAA5000099D2F /* notifyd.c in Sources */,
9456B8522023CAB300CF7D27 /* libnotify.c in Sources */,
3FA21AD1148AAA5000099D2F /* pathwatch.c in Sources */,
3FA21AD2148AAA5000099D2F /* service.c in Sources */,
3FA21AD3148AAA5000099D2F /* timer.c in Sources */,
@ -584,6 +814,18 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
94099C6F2087E7D50004B6BC /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
9487BF2C2089BAA30043BF74 /* table.c in Sources */,
9487BF2A2089A99A0043BF74 /* notify_client.c in Sources */,
94099C762087E7D50004B6BC /* RegisterTests.m in Sources */,
9487BF2B2089A9E30043BF74 /* notify_ipc.defs in Sources */,
9487BF2D2089BAB20043BF74 /* libnotify.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
D2AAC044055464E500DB518D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@ -591,6 +833,7 @@
2D312B7A102CA30200F90022 /* notify_ipc.defs in Sources */,
2D312B76102CA2E300F90022 /* libnotify.c in Sources */,
2D312B77102CA2E300F90022 /* notify_client.c in Sources */,
E6481E7F2165785F00C04412 /* notify_probes.d in Sources */,
2D312B78102CA2E300F90022 /* table.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -608,9 +851,32 @@
target = 3FA21ABD148AA8F000099D2F /* notifyutil */;
targetProxy = 3FA21ACC148AA94A00099D2F /* PBXContainerItemProxy */;
};
72FA84FF1BD6EC2000A4CC6F /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 72FA84F61BD6E9DF00A4CC6F /* darwintests */;
targetProxy = 72FA84FE1BD6EC2000A4CC6F /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
1886391520E1A22F00C8BEA9 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 3F999964185C474E00EAD3A0 /* notifyutil.xcconfig */;
buildSettings = {
INSTALL_PATH = /usr/local/bin;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
1886391620E1A22F00C8BEA9 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 3F999964185C474E00EAD3A0 /* notifyutil.xcconfig */;
buildSettings = {
INSTALL_PATH = /usr/local/bin;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
1DEB91ED08733DB70010E9CD /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 3F82235D12B18551005DD509 /* libnotify.xcconfig */;
@ -621,7 +887,21 @@
1DEB91F108733DB70010E9CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
APPLY_RULES_IN_COPY_FILES = YES;
APPLY_RULES_IN_COPY_FILES = "";
CLANG_WARN_ASSIGN_ENUM = YES;
CLANG_WARN_NULLABLE_TO_NONNULL_CONVERSION = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_LABEL = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
LLVM_LTO = YES;
SUPPORTED_PLATFORMS = "watchsimulator watchos iphonesimulator iphoneos macosx bridgeos appletvsimulator appletvos";
WARNING_CFLAGS = "-Wno-dollar-in-identifier-extension";
};
name = Release;
};
@ -629,6 +909,10 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 3F999963185C474E00EAD3A0 /* notifyd.xcconfig */;
buildSettings = {
OTHER_CFLAGS = (
"$(inherited)",
"-DSINGLE_THREADED_NOTIFY_STATE=1",
);
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
@ -637,6 +921,7 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 3F999964185C474E00EAD3A0 /* notifyutil.xcconfig */;
buildSettings = {
CODE_SIGN_ENTITLEMENTS = notifyutil/notifyutil_entitlements.plist;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
@ -649,13 +934,240 @@
};
name = Release;
};
72FA84F81BD6E9DF00A4CC6F /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = "";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx.internal;
SUPPORTED_PLATFORMS = "iphoneos macosx watchos appletvos bridgeos";
};
name = Release;
};
72FA84FD1BD6EAB900A4CC6F /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "macosx iphoneos watchos appletvos";
};
name = Release;
};
94099C782087E7D50004B6BC /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 3F82235D12B18551005DD509 /* libnotify.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = NO;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = NO;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
INFOPLIST_FILE = xctests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
LINK_WITH_STANDARD_LIBRARIES = YES;
MTL_ENABLE_DEBUG_INFO = NO;
OTHER_CFLAGS = (
"$(inherited)",
"-DBUILDING_TESTS=1",
"-fno-lto",
);
OTHER_MIGFLAGS = "-DBUILDING_TESTS=1";
PRODUCT_BUNDLE_IDENTIFIER = com.example.xctests;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx.internal;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
949B783D208BE1F2002AD6AF /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
APPLY_RULES_IN_COPY_FILES = "";
CLANG_WARN_ASSIGN_ENUM = YES;
CLANG_WARN_NULLABLE_TO_NONNULL_CONVERSION = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_LABEL = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
LLVM_LTO = YES;
SUPPORTED_PLATFORMS = "watchsimulator watchos iphonesimulator iphoneos macosx bridgeos appletvsimulator appletvos";
WARNING_CFLAGS = "-Wno-dollar-in-identifier-extension";
};
name = Debug;
};
949B783E208BE1F2002AD6AF /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 3F82235D12B18551005DD509 /* libnotify.xcconfig */;
buildSettings = {
};
name = Debug;
};
949B783F208BE1F2002AD6AF /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 3F999963185C474E00EAD3A0 /* notifyd.xcconfig */;
buildSettings = {
OTHER_CFLAGS = (
"$(inherited)",
"-DSINGLE_THREADED_NOTIFY_STATE=1",
);
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
949B7840208BE1F2002AD6AF /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 3F999964185C474E00EAD3A0 /* notifyutil.xcconfig */;
buildSettings = {
CODE_SIGN_ENTITLEMENTS = notifyutil/notifyutil_entitlements.plist;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
949B7841208BE1F2002AD6AF /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 3F999961185C474E00EAD3A0 /* base.xcconfig */;
buildSettings = {
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
949B7842208BE1F2002AD6AF /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = "";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx.internal;
SUPPORTED_PLATFORMS = "iphoneos macosx watchos appletvos bridgeos";
};
name = Debug;
};
949B7843208BE1F2002AD6AF /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "macosx iphoneos watchos appletvos";
};
name = Debug;
};
949B7844208BE1F2002AD6AF /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 3F82235D12B18551005DD509 /* libnotify.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = NO;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = NO;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
INFOPLIST_FILE = xctests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
LINK_WITH_STANDARD_LIBRARIES = YES;
MTL_ENABLE_DEBUG_INFO = NO;
OTHER_CFLAGS = (
"$(inherited)",
"-DDEBUG=1",
"-O0",
"-DBUILDING_TESTS=1",
"-fno-lto",
);
OTHER_MIGFLAGS = "-DBUILDING_TESTS=1";
PRODUCT_BUNDLE_IDENTIFIER = com.example.xctests;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx.internal;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Debug;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1886391420E1A22F00C8BEA9 /* Build configuration list for PBXNativeTarget "notifybench" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1886391520E1A22F00C8BEA9 /* Release */,
1886391620E1A22F00C8BEA9 /* Debug */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
1DEB91EB08733DB70010E9CD /* Build configuration list for PBXNativeTarget "libnotify" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1DEB91ED08733DB70010E9CD /* Release */,
949B783E208BE1F2002AD6AF /* Debug */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
@ -664,6 +1176,7 @@
isa = XCConfigurationList;
buildConfigurations = (
1DEB91F108733DB70010E9CD /* Release */,
949B783D208BE1F2002AD6AF /* Debug */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
@ -672,6 +1185,7 @@
isa = XCConfigurationList;
buildConfigurations = (
3FA21AB9148AA8E300099D2F /* Release */,
949B783F208BE1F2002AD6AF /* Debug */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
@ -680,6 +1194,7 @@
isa = XCConfigurationList;
buildConfigurations = (
3FA21AC6148AA8F000099D2F /* Release */,
949B7840208BE1F2002AD6AF /* Debug */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
@ -688,6 +1203,34 @@
isa = XCConfigurationList;
buildConfigurations = (
3FA21AC9148AA93000099D2F /* Release */,
949B7841208BE1F2002AD6AF /* Debug */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
72FA84F71BD6E9DF00A4CC6F /* Build configuration list for PBXLegacyTarget "darwintests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
72FA84F81BD6E9DF00A4CC6F /* Release */,
949B7842208BE1F2002AD6AF /* Debug */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
72FA84FC1BD6EAB900A4CC6F /* Build configuration list for PBXAggregateTarget "tests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
72FA84FD1BD6EAB900A4CC6F /* Release */,
949B7843208BE1F2002AD6AF /* Debug */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
94099C792087E7D50004B6BC /* Build configuration list for PBXNativeTarget "xctests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
94099C782087E7D50004B6BC /* Release */,
949B7844208BE1F2002AD6AF /* Debug */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;

View File

@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1000"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "NO">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "NO"
buildForProfiling = "NO"
buildForArchiving = "YES"
buildForAnalyzing = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "94099C722087E7D50004B6BC"
BuildableName = "xctests.xctest"
BlueprintName = "xctests"
ReferencedContainer = "container:Libnotify.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "94099C722087E7D50004B6BC"
BuildableName = "xctests.xctest"
BlueprintName = "xctests"
ReferencedContainer = "container:Libnotify.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -1 +0,0 @@
../libnotify.h

View File

@ -1 +0,0 @@
../notify.h

View File

@ -1 +0,0 @@
../notify_internal.h

View File

@ -1 +0,0 @@
../notify_ipc_types.h

View File

@ -1 +0,0 @@
../notify_keys.h

View File

@ -1 +0,0 @@
../notify_private.h

View File

@ -1 +0,0 @@
../table.h

File diff suppressed because it is too large Load Diff

View File

@ -24,6 +24,8 @@
#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>
@ -31,31 +33,40 @@
#include <TargetConditionals.h>
#if TARGET_IPHONE_SIMULATOR
extern const char *_notify_shm_id();
extern const char *_notify_shm_id(void);
#define SHM_ID _notify_shm_id()
#else
#define SHM_ID "apple.shm.notification_center"
#endif
#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
#define COMMON_PORT_KEY "com.apple.system.notify.common"
/* 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 0x00000004
#define NOTIFY_TYPE_FILE 0x00000008
#define NOTIFY_TYPE_SIGNAL 0x00000010
#define NOTIFY_TYPE_MASK 0x000000ff
#define NOTIFY_FLAG_SELF 0x80000000
#define NOTIFY_FLAG_REGEN 0x40000000
#define NOTIFY_FLAG_RELEASE_SEND 0x20000000
#define NOTIFY_TYPE_NONE 0x00000000
#define NOTIFY_TYPE_MEMORY 0x00000001
#define NOTIFY_TYPE_PLAIN 0x00000002
#define NOTIFY_TYPE_PORT 0x00000004
#define NOTIFY_TYPE_FILE 0x00000008
#define NOTIFY_TYPE_SIGNAL 0x00000010
#define NOTIFY_TYPE_MASK 0x0000001f // If this is changed, make sure it doesn't muck with struct client_s
#define NOTIFY_FLAG_SELF 0x80000000
#define NOTIFY_FLAG_REGEN 0x40000000
#define NOTIFY_FLAG_RELEASE_SEND 0x20000000
#define NOTIFY_FLAG_DISPATCH 0x10000000
#define NOTIFY_TYPE_COALESCE_BASE 0x08000000
#define NOTIFY_TYPE_COALESCED 0x04000000
#define NOTIFY_FLAG_RETAINED 0x02000000
#define NOTIFY_FLAG_CANCELED 0x01000000
/* Used to check for a polled or delivered types */
#define NOTIFY_TYPE_POLLED (NOTIFY_TYPE_MEMORY | NOTIFY_TYPE_PLAIN)
#define NOTIFY_TYPE_DELIVERED (NOTIFY_TYPE_PORT | NOTIFY_TYPE_FILE | NOTIFY_TYPE_SIGNAL)
/* Return values for notify_check() */
#define NOTIFY_CHECK_FALSE 0
@ -83,16 +94,13 @@ extern const char *_notify_shm_id();
#define NOTIFY_SERVICE_DIR_FILE_ADD 0x10
#define NOTIFY_SERVICE_DIR_FILE_DELETE 0x20
#define NOTIFY_CLIENT_STATE_SUSPENDED 0x00000001
#define NOTIFY_CLIENT_STATE_PENDING 0x00000002
#define NOTIFY_CLIENT_STATE_TIMEOUT 0x00000004
#define NOTIFY_CLIENT_STATE_SUSPENDED 0x00000020
#define NOTIFY_CLIENT_STATE_PENDING 0x00000040
#define NOTIFY_CLIENT_STATE_TIMEOUT 0x00000080
#define NOTIFY_PORT_PROC_TYPE_PORT 0x00000010
#define NOTIFY_PORT_PROC_TYPE_PROC 0x00000020
#define NOTIFY_PORT_PROC_TYPE_MASK 0x000000f0
#define NOTIFY_PORT_PROC_STATE_INVALID 0x00000001
#define NOTIFY_PORT_PROC_STATE_SUSPENDED 0x00000002
#define NOTIFY_PORT_PROC_STATE_MASK 0x0000000f
/* port_data_t::flags and proc_data_t::flags */
#define PORT_PROC_FLAGS_NONE 0x00000000
#define NOTIFY_PORT_PROC_STATE_SUSPENDED 0x00000001
/* notify state flags */
#define NOTIFY_STATE_USE_LOCKS 0x00000001
@ -103,63 +111,79 @@ extern const char *_notify_shm_id();
#define FD_NONE -1
#define SLOT_NONE -1
#define _notify_lib_port_new(A,B,C,D) _notify_lib_port_proc_new(A,B,0,C,D)
#define _notify_lib_proc_new(A,B,C,D) _notify_lib_port_proc_new(A,MACH_PORT_NULL,B,C,D)
#define _notify_lib_port_find(A,B) _notify_lib_port_proc_find(A,B,0)
#define _notify_lib_proc_find(A,B) _notify_lib_port_proc_find(A,MACH_PORT_NULL,B)
#define _notify_lib_port_release(A,B) _notify_lib_port_proc_release(A,B,0)
#define _notify_lib_proc_release(A,B) _notify_lib_port_proc_release(A,MACH_PORT_NULL,B)
typedef struct
{
LIST_HEAD(, client_s) subscriptions;
char *name;
void *private;
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;
uint64_t state;
uint64_t state_time;
void *private;
list_t *subscriptions;
uint32_t postcount;
uint32_t last_hour_postcount;
} name_info_t;
typedef struct
typedef union client_delivery_u
{
uint64_t client_id;
uint32_t state;
name_info_t *name_info;
uint32_t suspend_count;
uint32_t notify_type;
uint32_t lastval;
mach_port_t port;
int fd;
uint32_t send_val;
uint32_t pid;
mach_port_t port;
uint32_t sig;
void *private;
} 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
{
uint32_t refcount;
LIST_HEAD(, client_s) clients;
uint32_t port;
uint32_t flags;
dispatch_source_t src;
} portproc_data_t;
} port_data_t;
typedef struct
{
LIST_HEAD(, client_s) clients;
dispatch_source_t src;
uint32_t pid;
uint32_t flags;
table_t *name_table;
table_t *name_id_table;
table_t *client_table;
table_t *port_table;
table_t *proc_table;
} proc_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;
name_info_t **controlled_name;
uint32_t flags;
uint32_t controlled_name_count;
pthread_mutex_t *lock;
os_unfair_lock lock;
int sock;
uint32_t stat_name_alloc;
uint32_t stat_name_free;
@ -169,8 +193,7 @@ typedef struct
uint32_t stat_portproc_free;
} notify_state_t;
notify_state_t *_notify_lib_notify_state_new(uint32_t flags, uint32_t table_size);
void _notify_lib_notify_state_free(notify_state_t *ns);
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);
@ -185,32 +208,19 @@ uint32_t _notify_lib_register_signal(notify_state_t *ns, const char *name, pid_t
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_get_owner(notify_state_t *ns, const char *name, uint32_t *uid, uint32_t *gid);
uint32_t _notify_lib_get_access(notify_state_t *ns, const char *name, uint32_t *access);
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);
uint32_t _notify_lib_release_name(notify_state_t *ns, const char *name, uint32_t uid, uint32_t gid);
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);
void _notify_lib_suspend(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);
void _notify_lib_cancel_proc(notify_state_t *ns, pid_t pid);
void _notify_lib_suspend_proc(notify_state_t *ns, pid_t pid);
void _notify_lib_resume_proc(notify_state_t *ns, pid_t pid);
void _notify_lib_suspend_port(notify_state_t *ns, mach_port_t port);
void _notify_lib_resume_port(notify_state_t *ns, mach_port_t port);
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);
uint32_t _notify_lib_port_proc_new(notify_state_t *ns, mach_port_t port, pid_t proc, uint32_t state, dispatch_source_t src);
portproc_data_t *_notify_lib_port_proc_find(notify_state_t *ns, mach_port_t port, pid_t proc);
void _notify_lib_port_proc_release(notify_state_t *ns, mach_port_t port, pid_t proc);
#endif /* _LIBNOTIFY_H_ */

View File

@ -46,6 +46,8 @@
.Fn notify_post "const char *name"
.Ft uint32_t
.Fn notify_register_check "const char *name, int *out_token"
.Ft void
.Fn (^notify_handler_t) "int token"
.Ft uint32_t
.Fn notify_register_dispatch "const char *name, int *out_token" "dispatch_queue_t queue" "notify_handler_t handler"
.Ft uint32_t
@ -142,13 +144,6 @@ registers a client for notification delivery via a signal.
This fits
well with the design of many UNIX daemons that use a signal such as SIGHUP
to reinitialize of reset internal state information.
Clients may use the
registration token generated by this routine to check for notifications using
.Fn notify_check .
This allows the application to determine if a signal was received as the
result of a notification, or if the signal was generated by some other source.
It also permits the application that registers for signal notification for
multiple names to determine which name was associated with the notification.
.Ss notify_register_mach_port
registers a client for notification delivery via mach messaging.
Notifications are delivered by an empty message sent to a mach port.
@ -160,6 +155,8 @@ set in the flags parameter.
The notification service must be able to extract
send rights to the port.
.Pp
Values for the flags parameter may only be 0 (zero) or NOTIFY_REUSE.
.Pp
Note that the kernel limits the size of the message queue for any port.
If it is important that notifications should not be lost due to queue
overflow, clients should service messages quickly, and be cautious in
@ -180,7 +177,9 @@ is returned as the value of the "notify_fd" parameter.
A file descriptor
created by a previous call to this routine may be used for notifications
if a pointer to that file descriptor is passed in to the routine and
NOTIFY_REUSE is set in the flags parameter.
NOTIFY_REUSE is set in the flags parameter.
.Pp
Values for the flags parameter may only be 0 (zero) or NOTIFY_REUSE.
.Pp
Note that the kernel limits the buffer space for queued writes on a
file descriptor.
@ -254,6 +253,60 @@ the port or file descriptor have been cancelled.
Determines if an integer value is valid for a current registration.
Negative integers are never valid.
A positive or zero value is valid if the current process has a registration associated with the given value.
.Sh RETURN VALUES
Many notify functions return status (uint32_t) to indicate success or failure.
This will always be one of the following:
.Ss NOTIFY_STATUS_OK
The function did not encounter any issues.
.Ss NOTIFY_STATUS_INVALID_NAME
Name argument is not valid.
Often this will indicate that the name passed to the function is NULL.
.Ss NOTIFY_STATUS_INVALID_TOKEN
The function expected a valid token, given by a notify_register_* function, and was passed an invalid token.
Token validity can by checked with
.Fn notify_is_valid_token .
.Ss NOTIFY_STATUS_INVALID_PORT
The function is not able to use the port passed.
This may be because the port is NULL, MACH_PORT_NULL, MACH_PORT_DEAD, or the calling process does not have the
correct rights to the port.
.Ss NOTIFY_STATUS_INVALID_FILE
The function was passed NULL, or something that is not a file descriptor generated by notify_register_file_descriptor.
.Ss NOTIFY_STATUS_INVALID_SIGNAL
Legacy, currently unused.
.Ss NOTIFY_STATUS_INVALID_REQUEST
An internal error occurred.
.Ss NOTIFY_STATUS_NOT_AUTHORIZED
The calling process is not authorized to take this action.
Usually this indicates that the calling process may not act on the name given.
.Ss NOTIFY_STATUS_OPT_DISABLE
An internal error occurred.
.Ss NOTIFY_STATUS_SERVER_NOT_FOUND
The server could not be found.
This usually indicates that sandboxing is preventing the calling process from accessing notifyd.
.Ss NOTIFY_STATUS_NULL_INPUT
One of the inputs was called with NULL when it must not be NULL.
For legacy support, if name, token, port, or file descriptor is NULL, the respective NOTIFY_STATUS_INVALID_* return code
will be used instead.
.Ss NOTIFY_STATUS_FAILED
Indicates an internal failure of the library.
The caller may try again; another attempt may be successful.
Please report any instances where this is returned.
.Sh NAMESPACE CONVENTIONS
Names in the namespace must be NULL-terminated.
Names should be encoded as UTF-8 strings.

View File

@ -29,6 +29,7 @@
#include <sys/cdefs.h>
#include <stdint.h>
#include <mach/message.h>
#include <os/base.h>
#include <Availability.h>
#ifdef __BLOCKS__
#include <dispatch/dispatch.h>
@ -75,7 +76,7 @@
*/
/*! @defineblock Status Codes
* Status codes returned by the API.
* Status codes returned by the API. See notify(3) for detailed description.
*/
#define NOTIFY_STATUS_OK 0
#define NOTIFY_STATUS_INVALID_NAME 1
@ -85,7 +86,12 @@
#define NOTIFY_STATUS_INVALID_SIGNAL 5
#define NOTIFY_STATUS_INVALID_REQUEST 6
#define NOTIFY_STATUS_NOT_AUTHORIZED 7
#define NOTIFY_STATUS_OPT_DISABLE 8
#define NOTIFY_STATUS_SERVER_NOT_FOUND 9
#define NOTIFY_STATUS_NULL_INPUT 10
#define NOTIFY_STATUS_FAILED 1000000
/*! @/defineblock */
/*!
@ -110,7 +116,7 @@ __BEGIN_DECLS
* This is the only call that is required for a notification producer.
* Returns status.
*/
uint32_t notify_post(const char *name);
OS_EXPORT uint32_t notify_post(const char *name);
#ifdef __BLOCKS__
@ -131,13 +137,13 @@ typedef void (^notify_handler_t)(int token);
* The dispatch queue is retained by the notify subsystem while
* the notification is registered, and will be released when
* notification is canceled.
* @param block (input) The Block to invoke on the dispatch queue in response
* @param handler (input) The Block to invoke on the dispatch queue in response
* to a notification. The notification token is passed to the
* Block as an argument so that the callee can modify the state
* of the notification or cancel the registration.
* @result Returns status.
*/
uint32_t notify_register_dispatch(const char *name, int *out_token, dispatch_queue_t queue, notify_handler_t handler)
OS_EXPORT uint32_t notify_register_dispatch(const char *name, int *out_token, dispatch_queue_t queue, notify_handler_t handler)
__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_3_2);
#endif /* __BLOCKS__ */
@ -151,7 +157,7 @@ __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_3_2);
* (output) registration token
* @result Returns status.
*/
uint32_t notify_register_check(const char *name, int *out_token);
OS_EXPORT uint32_t notify_register_check(const char *name, int *out_token);
/*!
* Request notification delivery by UNIX signal.
@ -165,7 +171,7 @@ uint32_t notify_register_check(const char *name, int *out_token);
* @param out_token (output) notification token
* @result Returns status.
*/
uint32_t notify_register_signal(const char *name, int sig, int *out_token);
OS_EXPORT uint32_t notify_register_signal(const char *name, int sig, int *out_token);
/*!
* Request notification by mach message.
@ -197,9 +203,9 @@ uint32_t notify_register_signal(const char *name, int sig, int *out_token);
* (input/output) pointer to a mach port
* @result Returns status.
*/
uint32_t notify_register_mach_port(const char *name, mach_port_t *notify_port, int flags, int *out_token);
OS_EXPORT uint32_t notify_register_mach_port(const char *name, mach_port_t *notify_port, int flags, int *out_token);
/*
/*!
* Request notification by a write to a file descriptor.
*
* Notifications are delivered by a write to a file descriptor.
@ -227,7 +233,7 @@ uint32_t notify_register_mach_port(const char *name, mach_port_t *notify_port, i
* (input/output) pointer to a file descriptor
* @result Returns status.
*/
uint32_t notify_register_file_descriptor(const char *name, int *notify_fd, int flags, int *out_token);
OS_EXPORT uint32_t notify_register_file_descriptor(const char *name, int *notify_fd, int flags, int *out_token);
/*!
* Check if any notifications have been posted.
@ -246,7 +252,7 @@ uint32_t notify_register_file_descriptor(const char *name, int *notify_fd, int f
* (output) true/false indication
* @result Returns status.
*/
uint32_t notify_check(int token, int *check);
OS_EXPORT uint32_t notify_check(int token, int *check);
/*!
* Cancel notification and free resources associated with a notification
@ -258,7 +264,7 @@ uint32_t notify_check(int token, int *check);
* (input) notification token
* @result Returns status.
*/
uint32_t notify_cancel(int token);
OS_EXPORT uint32_t notify_cancel(int token);
/*!
* Suspend delivery of notifications for a token. Notifications for this token will be
@ -270,7 +276,7 @@ uint32_t notify_cancel(int token);
* (input) notification token
* @result Returns status.
*/
uint32_t notify_suspend(int token)
OS_EXPORT uint32_t notify_suspend(int token)
__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0);
/*!
@ -284,7 +290,7 @@ __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0);
* (input) notification token
* @result Returns status.
*/
uint32_t notify_resume(int token)
OS_EXPORT uint32_t notify_resume(int token)
__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0);
/*!
@ -305,7 +311,7 @@ __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0);
* (input) 64-bit unsigned integer value
* @result Returns status.
*/
uint32_t notify_set_state(int token, uint64_t state64)
OS_EXPORT uint32_t notify_set_state(int token, uint64_t state64)
__OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0);
/*!
@ -317,20 +323,20 @@ __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0);
* (output) 64-bit unsigned integer value
* @result Returns status.
*/
uint32_t notify_get_state(int token, uint64_t *state64)
OS_EXPORT uint32_t notify_get_state(int token, uint64_t *state64)
__OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0);
/*!
* Determine if a token is valid (currently registered).
* Negative integer values are always invalid. Positive or
* zero values are valid only if they are associated with an
* existing registratiom.
* existing registration.
*
* @param val
* (input) integer value
* @result Returns true if the value is a valid token, false otherwise.
*/
bool notify_is_valid_token(int val)
OS_EXPORT bool notify_is_valid_token(int val)
__OSX_AVAILABLE_STARTING(__MAC_10_10,__IPHONE_8_0);
__END_DECLS

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,7 @@
* 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,
@ -17,83 +17,137 @@
* 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@
*/
#define __OS_EXPOSE_INTERNALS__ 1
#include <os/internal/internal_shared.h>
#include <dispatch/dispatch.h>
#include <mach/mach.h>
#include <pthread.h>
#include <os/lock.h>
#include <stdatomic.h>
#include <stdint.h>
#include <TargetConditionals.h>
struct notify_globals_s {
// Global lock.
pthread_mutex_t notify_lock;
#include "libnotify.h"
int32_t notify_ipc_version;
#define NOTIFY_INTERNAL_CRASH(c, x) __extension__({ \
_os_set_crash_log_cause_and_message(c, "BUG IN LIBNOTIFY: " x); \
__builtin_trap(); \
})
#define NOTIFY_CLIENT_CRASH(c, x) __extension__({ \
_os_set_crash_log_cause_and_message(c, \
"BUG IN CLIENT OF LIBNOTIFY: " x); \
__builtin_trap(); \
})
#define NOTIFY_STATUS_SERVER_CHECKIN_FAILED 11
// was NOTIFY_STATUS_LIB_SELF_STATE_FAILED 12
#define NOTIFY_STATUS_SERVER_REGEN_FAILED 13
#define NOTIFY_STATUS_CLIENT_REG_FAILED 14
#define NOTIFY_STATUS_SERVER_POST_4_FAILED 15
#define NOTIFY_STATUS_SERVER_POST_2_FAILED 16
#define NOTIFY_STATUS_SERVER_POST_3_FAILED 17
#define NOTIFY_STATUS_TOKEN_NOT_FOUND 18
#define NOTIFY_STATUS_COMMON_PORT_NULL 19
#define NOTIFY_STATUS_SERVER_PORT_NULL 20
#define NOTIFY_STATUS_REG_CHECK_2_FAILED 21
#define NOTIFY_STATUS_SHM_ATTACH_FAILED 22
#define NOTIFY_STATUS_SHM_BASE_REMAINS_NULL 23
#define NOTIFY_STATUS_REG_PLAIN_2_FAILED 24
#define NOTIFY_STATUS_REG_SIGNAL_2_FAILED 25
#define NOTIFY_STATUS_MACH_PORT_ALLOC_FAILED 26
#define NOTIFY_STATUS_MACH_PORT_INSERT_RIGHT_FAILED 27
#define NOTIFY_STATUS_REG_MACH_PORT_2_FAILED 28
#define NOTIFY_STATUS_PIPE_FAILED 29
#define NOTIFY_STATUS_FILEPORT_MAKEPORT_FAILED 30
#define NOTIFY_STATUS_REG_FD_2_FAILED 31
#define NOTIFY_STATUS_SHM_BASE_NULL 32
#define NOTIFY_STATUS_SERVER_CHECK_FAILED 33
#define NOTIFY_STATUS_STRDUP_FAILED 34
#define NOTIFY_STATUS_SERVER_MONITOR_FILE_2_FAILED 35
#define NOTIFY_STATUS_SERVER_GET_STATE_2_FAILED 36
#define NOTIFY_STATUS_SERVER_SET_STATE_2_FAILED 37
#define NOTIFY_STATUS_SERVER_SUSPEND_FAILED 38
#define NOTIFY_STATUS_SERVER_RESUME_FAILED 39
#define NOTIFY_STATUS_SERVER_SUSPEND_PID_FAILED 40
#define NOTIFY_STATUS_SERVER_RESUME_PID_FAILED 41
#define NOTIFY_STATUS_ALLOC_FAILED 42
#define NOTIFY_STATUS_KILL_FAILED 43
#define NOTIFY_STATUS_WRITE_FAILED 44
#define NOTIFY_STATUS_MACH_MSG_TIMEOUT 45
#define NOTIFY_STATUS_MACH_MSG_FAILED 46
#define NOTIFY_STATUS_NEW_NAME_FAILED 47
#define NOTIFY_STATUS_NEW_CLIENT_FAILED 48
#define NOTIFY_STATUS_STATE_NULL 49
#define NOTIFY_STATUS_CLIENT_NOT_FOUND 50
#define NOTIFY_STATUS_DUP_CLIENT 51
#define NOTIFY_STATUS_TYPE_ISSUE 52
#define NOTIFY_STATUS_PATH_NODE_CREATE_FAILED 53
#define NOTIFY_STATUS_INVALID_TIME_EVENT 54
#define NOTIFY_STATUS_TIMER_FAILED 55
#define NOTIFY_STATUS_DOUBLE_REG 56
#define NOTIFY_STATUS_NO_REGEN_NEEDED 57
#define IS_INTERNAL_ERROR(X) (X >= 11)
#define USER_PROTECTED_UID_PREFIX "user.uid."
#define USER_PROTECTED_UID_PREFIX_LEN 9
struct notify_globals_s
{
/* global lock */
os_unfair_lock notify_lock;
/* notify_check() lock */
os_unfair_lock check_lock;
pid_t notify_server_pid;
uint32_t client_opts;
atomic_uint_fast32_t client_opts;
uint32_t saved_opts;
// Last allocated name id.
uint64_t name_id;
dispatch_once_t self_state_once;
notify_state_t *self_state;
notify_state_t self_state;
dispatch_once_t notify_server_port_once;
mach_port_t notify_server_port;
mach_port_t saved_server_port;
mach_port_t notify_common_port;
int notify_common_token;
dispatch_source_t notify_dispatch_source;
dispatch_source_t server_proc_source;
dispatch_once_t token_table_once;
table_t *token_table;
table_t *token_name_table;
uint32_t token_id;
// File descriptor list.
dispatch_once_t internal_once;
table_n_t registration_table;
table_t name_node_table;
atomic_uint_fast32_t token_id;
dispatch_once_t make_background_send_queue_once;
dispatch_queue_t background_send_queue;
/* file descriptor list */
uint32_t fd_count;
int *fd_clnt;
int *fd_srv;
int *fd_refcount;
// Mach port list.
/* mach port list */
uint32_t mp_count;
mach_port_t *mp_list;
int *mp_refcount;
int *mp_mine;
// Shared memory base address.
uint32_t mp_size;
struct mp_entry {
mach_port_t mpl_port_name;
int mpl_refs;
bool mpl_mine;
} *mp_list;
/* shared memory base address */
uint32_t *shm_base;
};
typedef struct notify_globals_s *notify_globals_t;
#if __has_include(<os/alloc_once_private.h>)
#include <os/alloc_once_private.h>
#if defined(OS_ALLOC_ONCE_KEY_LIBSYSTEM_NOTIFY)
#define _NOTIFY_HAS_ALLOC_ONCE 1
#endif
#endif
__private_extern__ uint32_t _notify_lib_peek(notify_state_t *ns, pid_t pid, int token, int *val);
__attribute__((visibility("hidden")))
void _notify_init_globals(void * /* notify_globals_t */ globals);
__attribute__((visibility("hidden")))
notify_globals_t _notify_globals_impl(void);
__attribute__((__pure__))
static inline notify_globals_t
_notify_globals(void) {
#if _NOTIFY_HAS_ALLOC_ONCE
return (notify_globals_t)os_alloc_once(OS_ALLOC_ONCE_KEY_LIBSYSTEM_NOTIFY,
sizeof(struct notify_globals_s), &_notify_init_globals);
#else
return _notify_globals_impl();
#endif
}

View File

@ -9,7 +9,7 @@
* 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,
@ -17,136 +17,28 @@
* 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@
*/
#include <mach/std_types.defs>
#include <mach/mach_types.defs>
subsystem notify_ipc 78945668;
subsystem notify_ipc 78945000;
serverprefix _;
import <sys/types.h>;
import "notify_ipc_types.h";
type notify_name = ^ array [] of MACH_MSG_TYPE_BYTE
type notify_name = c_string[*:512]
ctype : caddr_t;
routine _notify_server_post
(
server : mach_port_t;
name : notify_name;
out status : int;
ServerAuditToken audit : audit_token_t
);
type notify_path = array[] of char
ctype : caddr_t;
routine _notify_server_register_plain
(
server : mach_port_t;
name : notify_name;
out token : int;
out status : int;
ServerAuditToken audit : audit_token_t
);
UseSpecialReplyPort 1;
routine _notify_server_register_check
(
server : mach_port_t;
name : notify_name;
out size : int;
out slot : int;
out token : int;
out status : int;
ServerAuditToken audit : audit_token_t
);
routine _notify_server_register_signal
(
server : mach_port_t;
name : notify_name;
sig: int;
out token : int;
out status : int;
ServerAuditToken audit : audit_token_t
);
routine _notify_server_register_file_descriptor
(
server : mach_port_t;
name : notify_name;
fileport : mach_port_move_send_t;
ntoken : int;
out token : int;
out status : int;
ServerAuditToken audit : audit_token_t
);
routine _notify_server_register_mach_port
(
server : mach_port_t;
name : notify_name;
port : mach_port_move_send_t;
ntoken : int;
out token : int;
out status : int;
ServerAuditToken audit : audit_token_t
);
routine _notify_server_set_owner
(
server : mach_port_t;
name : notify_name;
user : int;
group : int;
out status : int;
ServerAuditToken audit : audit_token_t
);
routine _notify_server_get_owner
(
server : mach_port_t;
name : notify_name;
out user : int;
out group : int;
out status : int;
ServerAuditToken audit : audit_token_t
);
routine _notify_server_set_access
(
server : mach_port_t;
name : notify_name;
mode : int;
out status : int;
ServerAuditToken audit : audit_token_t
);
routine _notify_server_get_access
(
server : mach_port_t;
name : notify_name;
out mode : int;
out status : int;
ServerAuditToken audit : audit_token_t
);
routine _notify_server_release_name
(
server : mach_port_t;
name : notify_name;
out status : int;
ServerAuditToken audit : audit_token_t
);
routine _notify_server_cancel
(
server : mach_port_t;
token : int;
out status : int;
ServerAuditToken audit : audit_token_t
);
skip; // was _notify_server_register_plain
skip; // was _notify_server_cancel
routine _notify_server_check
(
@ -166,28 +58,6 @@ routine _notify_server_get_state
ServerAuditToken audit : audit_token_t
);
routine _notify_server_set_state
(
server : mach_port_t;
token : int;
state : uint64_t;
out status : int;
ServerAuditToken audit : audit_token_t
);
skip; /* formerly _notify_server_get_val */
skip; /* formerly _notify_server_set_val */
routine _notify_server_monitor_file
(
server : mach_port_t;
token : int;
path : notify_name;
flags : int;
out status : int;
ServerAuditToken audit : audit_token_t
);
routine _notify_server_suspend
(
@ -205,30 +75,23 @@ routine _notify_server_resume
ServerAuditToken audit : audit_token_t
);
routine _notify_server_suspend_pid
simpleroutine _notify_server_suspend_pid
(
server : mach_port_t;
pid : int;
out status : int;
ServerAuditToken audit : audit_token_t
);
routine _notify_server_resume_pid
simpleroutine _notify_server_resume_pid
(
server : mach_port_t;
pid : int;
out status : int;
ServerAuditToken audit : audit_token_t
);
simpleroutine _notify_server_simple_post
(
server : mach_port_t;
name : notify_name;
ServerAuditToken audit : audit_token_t
);
/* Additions for version 2 - more async support */
MsgOption MACH_SEND_PROPAGATE_QOS;
routine _notify_server_post_2
(
@ -236,6 +99,7 @@ routine _notify_server_post_2
name : notify_name;
out name_id : uint64_t;
out status : int;
claim_root_access : boolean_t;
ServerAuditToken audit : audit_token_t
);
@ -243,6 +107,7 @@ simpleroutine _notify_server_post_3
(
server : mach_port_t;
name_id : uint64_t;
claim_root_access : boolean_t;
ServerAuditToken audit : audit_token_t
);
@ -250,9 +115,12 @@ simpleroutine _notify_server_post_4
(
server : mach_port_t;
name : notify_name;
claim_root_access : boolean_t;
ServerAuditToken audit : audit_token_t
);
MsgOption MACH_MSG_OPTION_NONE;
simpleroutine _notify_server_register_plain_2
(
server : mach_port_t;
@ -296,7 +164,7 @@ simpleroutine _notify_server_register_mach_port_2
server : mach_port_t;
name : notify_name;
token: int;
port : mach_port_move_send_t;
port : mach_port_make_send_t;
ServerAuditToken audit : audit_token_t
);
@ -331,6 +199,7 @@ simpleroutine _notify_server_set_state_2
server : mach_port_t;
name_id : uint64_t;
state : uint64_t;
claim_root_access : boolean_t;
ServerAuditToken audit : audit_token_t
);
@ -341,6 +210,7 @@ routine _notify_server_set_state_3
state : uint64_t;
out nid : uint64_t;
out status : int;
claim_root_access : boolean_t;
ServerAuditToken audit : audit_token_t
);
@ -348,7 +218,7 @@ simpleroutine _notify_server_monitor_file_2
(
server : mach_port_t;
token : int;
path : notify_name;
path : notify_path;
flags : int;
ServerAuditToken audit : audit_token_t
);
@ -364,10 +234,28 @@ routine _notify_server_regenerate
prev_slot: int;
prev_state : uint64_t;
prev_time : uint64_t;
path : notify_name;
path : notify_path;
path_flags: int;
out new_slot : int;
out new_name_id : uint64_t;
out status : int;
ServerAuditToken audit : audit_token_t
);
routine _notify_server_checkin
(
server : mach_port_t;
out version: uint32_t;
out server_pid : uint32_t;
out status : int;
ServerAuditToken audit : audit_token_t
);
routine _notify_server_dump
(
server : mach_port_t;
fileport : mach_port_move_send_t;
ServerAuditToken audit : audit_token_t
);

View File

@ -1,32 +0,0 @@
/*
* Copyright (c) 2003-2009 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* Portions Copyright (c) 2003-2009 Apple Inc. All Rights Reserved.
*
* 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 _NOTIFY_IPC_TYPES_H_
#define _NOTIFY_IPC_TYPES_H_
#include <sys/types.h>
typedef char inline_data_t[2048];
#endif

View File

@ -25,23 +25,46 @@
#define __NOTIFY_PRIVATE_H__
#include <stdint.h>
#include <sys/types.h>
#include <os/base.h>
#include <Availability.h>
#define NOTIFY_OPT_DEMUX 0x00000001
#define NOTIFY_OPT_REGEN 0x00000002
#define NOTIFY_OPT_ENABLE 0x04000000
#define NOTIFY_OPT_DISABLE 0x08000000
#define NOTIFY_OPT_DISPATCH 0x00000001
#define NOTIFY_OPT_REGEN 0x00000002
#define NOTIFY_OPT_ENABLE 0x04000000
#define NOTIFY_OPT_DISABLE 0x08000000
uint32_t notify_suspend_pid(pid_t pid)
#define NOTIFY_NO_DISPATCH 0x80000000
#define ROOT_ENTITLEMENT_KEY "com.apple.notify.root_access"
OS_EXPORT uint32_t notify_suspend_pid(pid_t pid)
__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_0);
uint32_t notify_resume_pid(pid_t pid)
OS_EXPORT uint32_t notify_resume_pid(pid_t pid)
__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_0);
uint32_t notify_simple_post(const char *name)
__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_3);
OS_EXPORT uint32_t notify_simple_post(const char *name)
__API_DEPRECATED("No longer supported, use notify_post", macos(10.7, 10.15), ios(4.3, 13.0), watchos(1.0, 6.0), tvos(1.0, 13.0));
void notify_set_options(uint32_t opts)
OS_EXPORT void notify_set_options(uint32_t opts)
__OSX_AVAILABLE_STARTING(__MAC_10_8,__IPHONE_6_0);
OS_EXPORT void _notify_fork_child(void)
__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_3);
OS_EXPORT uint32_t notify_peek(int token, uint32_t *val)
__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_3);
OS_EXPORT uint32_t notify_monitor_file(int token, char *path, int flags)
__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_3);
OS_EXPORT uint32_t notify_get_event(int token, int *ev, char *buf, int *len)
__API_DEPRECATED("No longer supported", macos(10.7, 10.15), ios(4.3, 13.0), watchos(1.0, 6.0), tvos(1.0, 13.0));
OS_EXPORT uint32_t notify_register_plain(const char *name, int *out_token)
__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_3);
OS_EXPORT uint32_t notify_dump_status(const char *filepath);
#endif /* __NOTIFY_PRIVATE_H__ */

View File

@ -0,0 +1,7 @@
provider notify {
probe register_mach_port(const char *name, mach_port_name_t notify_port, int flags, int token);
probe post(const char *name);
probe check(int token, int check);
probe deliver_start(const char *name);
probe deliver_end(const char *name);
};

View File

@ -0,0 +1,451 @@
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <math.h>
#include <notify.h>
#include <mach/mach.h>
#include <mach/mach_time.h>
#include <assert.h>
#include "notify_private.h"
#ifdef NO_OP_TESTS
extern uint32_t notify_no_op_str_sync(const char *name, size_t len);
extern uint32_t notify_no_op_str_async(const char *name, size_t len);
extern uint32_t notify_no_op_int_sync(int n);
extern uint32_t notify_no_op_int_async(int n);
#endif
#define MAX_CNT 100
#define MAX_SPL 10000
#define DEFAULT_CNT 50
#if defined(__arm__)
#define DEFAULT_SPL 501
#else
#define DEFAULT_SPL 1001
#endif
static uint32_t cnt = DEFAULT_CNT;
static uint32_t spl = DEFAULT_SPL;
static long double time_round_to = (long double)200.0;
static long double loop_cost;
static mach_timebase_info_data_t tbi;
static uint64_t dmy[MAX_SPL], reg_plain[MAX_SPL], cancel_plain[MAX_SPL], reg_port[MAX_SPL], cancel_port[MAX_SPL];
static uint64_t post_plain1[MAX_SPL], post_plain2[MAX_SPL], post_plain3[MAX_SPL];
static uint64_t set_state1[MAX_SPL], set_state2[MAX_SPL], get_state[MAX_SPL];
static uint64_t reg_check[MAX_SPL], cancel_check[MAX_SPL];
static uint64_t check1[MAX_SPL], check2[MAX_SPL], check3[MAX_SPL], check4[MAX_SPL], check5[MAX_SPL];
static uint64_t reg_disp1[MAX_SPL], reg_disp2[MAX_SPL], cancel_disp[MAX_SPL];
volatile static int dispatch_changer = 0;
#ifdef NO_OP_TESTS
static uint64_t nss[MAX_SPL], nsa[MAX_SPL], nis[MAX_SPL], nia[MAX_SPL];
#endif
static void __attribute__((noinline))
print_result(uint64_t *s, const char *str)
{
unsigned j;
uint64_t m;
long double dd = 0, mm, sd = 0;
for (j = 0 ; j < spl; j++) {
dd += (long double)s[j]/(long double)cnt;
}
dd = dd/(long double)spl;
for (j = 0 ; j < spl; j++) {
long double tmp = (long double)s[j]/(long double)cnt - dd;
sd += tmp * tmp;
}
sd = sqrtl(sd/(long double)spl);
qsort_b(s, spl, sizeof(uint64_t),
^(const void *a, const void *b){
const uint64_t l = *(const uint64_t*)a;
const uint64_t r = *(const uint64_t*)b;
return l == r ? 0 : (l < r ? -1 : 1);
});
m = s[spl/2];
mm = (long double)m / (long double)cnt;
if (tbi.numer != tbi.denom) {
dd *= tbi.numer;
dd /= tbi.denom;
mm *= tbi.numer;
mm /= tbi.denom;
sd *= tbi.numer;
sd /= tbi.denom;
}
if (str) {
dd -= loop_cost;
mm -= loop_cost;
} else {
loop_cost = mm;
}
dd /= NSEC_PER_USEC;
dd = roundl(dd * time_round_to) / time_round_to;
mm /= NSEC_PER_USEC;
mm = roundl(mm * time_round_to) / time_round_to;
sd /= NSEC_PER_USEC;
sd = roundl(sd * time_round_to) / time_round_to;
if (!str) {
printf("%-40s %-8s %-8s %-8s\n",
"Symbol", "Median", "Average", "StdDev");
}
printf("%-36s%8.3Lf us %8.3Lf us %8.3Lf us\n",
str ? str : "Empty loop:", mm, dd, sd);
}
static void
notify_fence()
{
int fence_token;
notify_register_check("com.apple.notify.test", &fence_token);
notify_cancel(fence_token);
}
int
main(int argc, char *argv[])
{
uint32_t r;
kern_return_t kr;
unsigned i, j;
kr = mach_timebase_info(&tbi);
assert(!kr);
int tok;
r = notify_register_check("dummy.test", &tok);
assert(r == 0);
r = notify_cancel(tok);
assert(r == 0);
int t[MAX_CNT];
int t_2[MAX_CNT];
mach_port_t p[MAX_CNT];
char *n[MAX_CNT];
size_t l[MAX_CNT];
uint64_t s;
int check;
volatile uint32_t spin = 0;
dispatch_queue_t disp_q = dispatch_queue_create("Notify.Test", NULL);
for (i = 1; i < argc; i++)
{
if (!strcmp(argv[i], "-c")) cnt = atoi(argv[++i]);
else if (!strcmp(argv[i], "-s")) spl = atoi(argv[++i]) + 1;
}
if (cnt > MAX_CNT) cnt = MAX_CNT;
if (spl > MAX_SPL) spl = MAX_SPL + 1;
for (j = 0 ; j < spl; j++)
{
for (i = 0; i < cnt; i++)
{
r = asprintf(&n[i], "dummy.test.%d", i);
assert(r != -1);
l[i] = strlen(n[i]);
kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &p[i]);
assert(kr == 0);
}
/* Empty Loop */
s = mach_absolute_time();
for (i = 0; i < cnt; i++)
{
spin++;
}
dmy[j] = mach_absolute_time() - s;
#ifdef NO_OP_TESTS
s = mach_absolute_time();
for (i = 0; i < cnt; i++)
{
r = notify_no_op_str_sync(n[i], l[i]);
assert(r == 0);
}
nss[j] = mach_absolute_time() - s;
s = mach_absolute_time();
for (i = 0; i < cnt; i++)
{
r = notify_no_op_str_async(n[i], l[i]);
assert(r == 0);
}
nsa[j] = mach_absolute_time() - s;
s = mach_absolute_time();
for (i = 0; i < cnt; i++)
{
r = notify_no_op_int_sync(i);
assert(r == 0);
}
nis[j] = mach_absolute_time() - s;
s = mach_absolute_time();
for (i = 0; i < cnt; i++)
{
r = notify_no_op_int_async(i);
assert(r == 0);
}
nia[j] = mach_absolute_time() - s;
#endif
/* Register Plain */
s = mach_absolute_time();
for (i = 0; i < cnt; i++)
{
r = notify_register_plain(n[i], &t[i]);
assert(r == 0);
}
reg_plain[j] = mach_absolute_time() - s;
/* Post 1 */
s = mach_absolute_time();
for (i = 0; i < cnt; i++)
{
r = notify_post(n[i]);
assert(r == 0);
}
post_plain1[j] = mach_absolute_time() - s;
/* Post 2 */
s = mach_absolute_time();
for (i = 0; i < cnt; i++)
{
r = notify_post(n[i]);
assert(r == 0);
}
post_plain2[j] = mach_absolute_time() - s;
/* Post 3 */
s = mach_absolute_time();
for (i = 0; i < cnt; i++)
{
r = notify_post(n[i]);
assert(r == 0);
}
post_plain3[j] = mach_absolute_time() - s;
/* Cancel Plain */
s = mach_absolute_time();
for (i = 0; i < cnt; i++)
{
r = notify_cancel(t[i]);
assert(r == 0);
}
cancel_plain[j] = mach_absolute_time() - s;
/* Register Mach Port */
s = mach_absolute_time();
for (i = 0; i < cnt; i++)
{
r = notify_register_mach_port(n[i], &p[i], NOTIFY_REUSE, &t[i]);
assert(r == 0);
}
reg_port[j] = mach_absolute_time() - s;
/* Set State 1 */
s = mach_absolute_time();
for (i = 0; i < cnt; i++)
{
r = notify_set_state(t[i], 1);
assert(r == 0);
}
set_state1[j] = mach_absolute_time() - s;
/* Get State */
s = mach_absolute_time();
for (i = 0; i < cnt; i++)
{
uint64_t dummy;
r = notify_get_state(t[i], &dummy);
assert(r == 0);
}
get_state[j] = mach_absolute_time() - s;
/* Set State 2 */
s = mach_absolute_time();
for (i = 0; i < cnt; i++)
{
r = notify_set_state(t[i], 2);
assert(r == 0);
}
set_state2[j] = mach_absolute_time() - s;
/* Cancel Port */
s = mach_absolute_time();
for (i = 0; i < cnt; i++)
{
r = notify_cancel(t[i]);
assert(r == 0);
}
cancel_port[j] = mach_absolute_time() - s;
/* Register Check */
s = mach_absolute_time();
for (i = 0; i < cnt; i++)
{
r = notify_register_check("com.apple.notify.test.check", &t[i]);
assert(r == 0);
}
reg_check[j] = mach_absolute_time() - s;
/* Check 1 */
s = mach_absolute_time();
for (i = 0; i < cnt; i++)
{
r = notify_check(t[i], &check);
assert(r == 0);
assert(check == 1);
}
check1[j] = mach_absolute_time() - s;
/* Check 2 */
s = mach_absolute_time();
for (i = 0; i < cnt; i++)
{
r = notify_check(t[i], &check);
assert(r == 0);
assert(check == 0);
}
check2[j] = mach_absolute_time() - s;
/* Check 3 */
s = mach_absolute_time();
for (i = 0; i < cnt; i++)
{
r = notify_check(t[i], &check);
assert(r == 0);
assert(check == 0);
}
check3[j] = mach_absolute_time() - s;
notify_post("com.apple.notify.test.check");
notify_fence();
/* Check 4 */
s = mach_absolute_time();
for (i = 0; i < cnt; i++)
{
r = notify_check(t[i], &check);
assert(r == 0);
assert(check == 1);
}
check4[j] = mach_absolute_time() - s;
/* Check 5 */
s = mach_absolute_time();
for (i = 0; i < cnt; i++)
{
r = notify_check(t[i], &check);
assert(r == 0);
assert(check == 0);
}
check5[j] = mach_absolute_time() - s;
/* Cancel Check */
s = mach_absolute_time();
for (i = 0; i < cnt; i++)
{
r = notify_cancel(t[i]);
assert(r == 0);
}
cancel_check[j] = mach_absolute_time() - s;
/* Register Dispatch 1 */
s = mach_absolute_time();
for (i = 0; i < cnt; i++)
{
r = notify_register_dispatch(n[i], &t[i], disp_q, ^(int x){
dispatch_changer = x;
});
assert(r == 0);
}
reg_disp1[j] = mach_absolute_time() - s;
/* Register Dispatch 2 (Coalesced) */
s = mach_absolute_time();
for (i = 0; i < cnt; i++)
{
r = notify_register_dispatch(n[i], &t_2[i], disp_q, ^(int x){
dispatch_changer = x;
});
assert(r == 0);
}
reg_disp2[j] = mach_absolute_time() - s;
/* Cancel Dispatch */
s = mach_absolute_time();
for (i = 0; i < cnt; i++)
{
r = notify_cancel(t[i]);
assert(r == 0);
r = notify_cancel(t_2[i]);
assert(r == 0);
}
cancel_disp[j] = mach_absolute_time() - s;
for (i = 0; i < cnt; i++)
{
free(n[i]);
kr = mach_port_mod_refs(mach_task_self(), p[i], MACH_PORT_RIGHT_RECEIVE, -1);
assert(kr == 0);
}
}
print_result(dmy, NULL);
#ifdef NO_OP_TESTS
print_result(nss, "notify_no_op_str_sync:");
print_result(nsa, "notify_no_op_str_async:");
print_result(nis, "notify_no_op_int_sync:");
print_result(nia, "notify_no_op_int_async:");
#endif
print_result(reg_plain, "notify_register_plain:");
print_result(post_plain1, "notify_post [plain 1]:");
print_result(post_plain2, "notify_post [plain 2]:");
print_result(post_plain3, "notify_post [plain 3]:");
print_result(cancel_plain, "notify_cancel [plain]:");
print_result(reg_port, "notify_register_mach_port:");
print_result(set_state1, "notify_set_state [1]:");
print_result(set_state2, "notify_set_state [2]:");
print_result(get_state, "notify_get_state:");
print_result(cancel_port, "notify_cancel [port]");
print_result(reg_check, "notify_register_check:");
print_result(check1, "notify_check [1]:");
print_result(check2, "notify_check [2]:");
print_result(check3, "notify_check [3]:");
print_result(check4, "notify_check [4]:");
print_result(check5, "notify_check [5]:");
print_result(cancel_check, "notfiy_cancel [check]:");
print_result(reg_disp1, "notify_register_dispatch [1]:");
print_result(reg_disp2, "notify_register_dispatch [2]:");
print_result(cancel_disp, "notify_cancel [both disp]:");
return 0;
}

View File

@ -2,6 +2,8 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>EnablePressuredExit</key>
<false/>
<key>EnableTransactions</key>
<true/>
<key>Label</key>

View File

@ -0,0 +1,24 @@
;; Copyright (c) 2015 Apple Inc. All Rights reserved.
;;
;; WARNING: The sandbox rules in this file currently constitute
;; Apple System Private Interface and are subject to change at any time and
;; without notice.
;;
(version 1)
(deny default)
(import "system.sb")
;; Allow files to be read
(allow file-read*)
;; Allow debug status files to be written
(allow file-write*
(regex #"^/private/var/run/notifyd")
)
;; Allow UNIX signals
(allow signal)
;; Allow shared memory
(allow ipc-posix-shm)

View File

@ -3,6 +3,7 @@
#
reserve com.apple.system. 0 0 rwr-r-
reserve com.apple.system.clock_set 0 266 rwrwr-
monitor com.apple.system.timezone /etc/localtime
monitor com.apple.system.info:/etc/hosts /etc/hosts
monitor com.apple.system.info:/etc/services /etc/services

View File

@ -0,0 +1,5 @@
#
# Notification Center configuration file
#
monitor com.apple.system.timezone /etc/localtime

View File

@ -3,5 +3,7 @@
#
reserve com.apple.system. 0 0 rwr-r-
reserve com.apple.system.clock_set 0 501 rwrwr-
reserve com.apple.system.clock_set 0 266 rwrwr-
monitor com.apple.system.timezone /var/db/timezone/localtime
set com.apple.system.batterysavermode
set com.apple.system.batterysavermode.discretionary

View File

@ -1 +0,0 @@
../notify_ipc.defs

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -24,25 +24,35 @@
#ifndef _NOTIFY_DAEMON_H_
#define _NOTIFY_DAEMON_H_
#define DISPATCH_MACH_SPI 1
#include <libnotify.h>
#include <mach/mach.h>
#include <launch.h>
#include <dispatch/dispatch.h>
#include <dispatch/private.h>
#define STATUS_REQUEST_SHORT 0
#define STATUS_REQUEST_LONG 1
#define NOTIFY_STATE_ENTITLEMENT "com.apple.private.libnotify.statecapture"
#define NOTIFY_IPC_VERSION 2
struct global_s
{
notify_state_t notify_state;
dispatch_mach_t mach_notifs_channel;
mach_port_t mach_notify_port;
mach_port_t server_port;
launch_data_t launch_dict;
notify_state_t *notify_state;
dispatch_queue_t work_q;
dispatch_source_t mach_src;
void **service_info_list;
dispatch_workloop_t workloop;
dispatch_mach_t mach_channel;
dispatch_source_t sig_usr1_src;
dispatch_source_t sig_usr2_src;
dispatch_source_t sig_winch_src;
uint32_t request_size;
uint32_t reply_size;
dispatch_source_t stat_reset_src;
time_t last_reset_time;
uint32_t nslots;
uint32_t slot_id;
uint32_t *shared_memory_base;
@ -50,8 +60,11 @@ struct global_s
uint32_t *last_shm_base;
uint32_t log_cutoff;
uint32_t log_default;
uint16_t service_info_count;
char *log_path;
} global;
};
extern struct global_s global;
struct call_statistics_s
{
@ -80,22 +93,27 @@ struct call_statistics_s
uint64_t set_state_by_client;
uint64_t set_state_by_id;
uint64_t set_state_by_client_and_fetch_id;
uint64_t get_owner;
uint64_t set_owner;
uint64_t get_access;
uint64_t set_access;
uint64_t monitor_file;
uint64_t service_timer;
uint64_t service_path;
uint64_t cleanup;
uint64_t regenerate;
} call_statistics;
uint64_t checkin;
};
extern void log_message(int priority, const char *str, ...);
extern struct call_statistics_s call_statistics;
extern void log_message(int priority, const char *str, ...) __printflike(2, 3);
extern uint32_t daemon_post(const char *name, uint32_t u, uint32_t g);
extern uint32_t daemon_post_nid(uint64_t nid, uint32_t u, uint32_t g);
extern void daemon_post_client(uint64_t cid);
extern void daemon_set_state(const char *name, uint64_t val);
extern void dump_status(uint32_t level);
extern void dump_status(uint32_t level, int fd);
extern bool has_entitlement(audit_token_t audit, const char *entitlement);
extern bool has_root_entitlement(audit_token_t audit);
dispatch_queue_t get_notifyd_workloop(void);
#endif /* _NOTIFY_DAEMON_H_ */

View File

@ -55,6 +55,10 @@
*
* path_node_releases() releases a path_node_t object and all of the vnode_t objects
* that were monitoring components of its target path.
*
* All of the code in this file is to be run on the workloop in order to maintain internal
* datastructures. This is asserted in every non-static function and thus can be safely
* assumed by all static functions.
*/
#include <stdio.h>
@ -69,7 +73,10 @@
#include <fcntl.h>
#include <assert.h>
#include <tzfile.h>
#include <sandbox.h>
#include <bsm/libbsm.h>
#include "pathwatch.h"
#include "notifyd.h"
#define forever for(;;)
#define streq(A,B) (strcmp(A,B)==0)
@ -110,7 +117,6 @@ typedef struct
static struct
{
dispatch_once_t pathwatch_init;
dispatch_queue_t pathwatch_queue;
uint32_t vnode_count;
vnode_t **vnode;
char *tzdir;
@ -206,7 +212,7 @@ _path_stat(const char *path, int link, uid_t uid, gid_t gid)
* Sets ftype output parameter if it is non-NULL.
*/
static int
_path_stat_check_access(const char *path, uid_t uid, gid_t gid, uint32_t *ftype)
_path_stat_check_access(const char *path, audit_token_t audit, bool client_is_notifyd, uint32_t *ftype)
{
struct stat sb;
char buf[MAXPATHLEN + 1];
@ -226,6 +232,11 @@ _path_stat_check_access(const char *path, uid_t uid, gid_t gid, uint32_t *ftype)
return PATH_STAT_OK;
}
/* Don't perform stat if sandbox won't allow it. (15907527) */
if (!client_is_notifyd && (sandbox_check_by_audit_token(audit, "file-read-metadata", SANDBOX_FILTER_PATH | SANDBOX_CHECK_NO_REPORT, path) != 0)) {
return PATH_STAT_ACCESS;
}
memset(&sb, 0, sizeof(struct stat));
status = lstat(path, &sb);
@ -239,8 +250,8 @@ _path_stat_check_access(const char *path, uid_t uid, gid_t gid, uint32_t *ftype)
if (t == PATH_NODE_TYPE_OTHER) return PATH_STAT_FAILED;
/* skip access control check if uid is zero */
if (uid == 0) return 0;
/* skip access control check if uid is zero or if the client is notifyd */
if (client_is_notifyd || audit_token_to_euid(audit) == 0) return 0;
/* special case: anything in the timezone directory is OK */
memset(buf, 0, sizeof(buf));
@ -253,20 +264,20 @@ _path_stat_check_access(const char *path, uid_t uid, gid_t gid, uint32_t *ftype)
/* call _path_stat to check access as the user/group provided */
if (t == PATH_NODE_TYPE_FILE)
{
status = _path_stat(path, 0, uid, gid);
status = _path_stat(path, 0, audit_token_to_euid(audit), audit_token_to_egid(audit));
if ((status == PATH_STAT_ACCESS) && (ftype != NULL)) *ftype = PATH_NODE_TYPE_GHOST;
return status;
}
else if (t == PATH_NODE_TYPE_LINK)
{
status = _path_stat(path, 1, uid, gid);
status = _path_stat(path, 1, audit_token_to_euid(audit), audit_token_to_egid(audit));
if ((status == PATH_STAT_ACCESS) && (ftype != NULL)) *ftype = PATH_NODE_TYPE_GHOST;
return status;
}
else if (t == PATH_NODE_TYPE_DIR)
{
snprintf(buf, MAXPATHLEN, "%s/.", path);
status = _path_stat(buf, 0, uid, gid);
status = _path_stat(buf, 0, audit_token_to_euid(audit), audit_token_to_egid(audit));
if ((status == PATH_STAT_ACCESS) && (ftype != NULL)) *ftype = PATH_NODE_TYPE_GHOST;
return status;
}
@ -319,12 +330,7 @@ _vnode_free(vnode_t *vnode)
{
dispatch_source_cancel(vnode->src);
/*
* Actually free the vnode on the pathwatch queue. This allows any
* enqueued _vnode_event operations to complete before the vnode disappears.
* _vnode_event() quietly returns if the source has been cancelled.
*/
dispatch_async(_global.pathwatch_queue, ^{
dispatch_async(get_notifyd_workloop(), ^{
dispatch_release(vnode->src);
free(vnode->path);
free(vnode->path_node);
@ -347,7 +353,7 @@ _vnode_event(vnode_t *vnode)
if ((vnode->src != NULL) && (dispatch_source_testcancel(vnode->src))) return;
ulf = dispatch_source_get_data(vnode->src);
flags = ulf;
flags = (uint32_t)ulf;
memset(&sb, 0, sizeof(struct stat));
if (fstat(vnode->fd, &sb) == 0)
@ -414,7 +420,7 @@ _vnode_create(const char *path, uint32_t type, path_node_t *pnode)
fd = open(path, flags, 0);
if (fd < 0) return NULL;
src = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, (uintptr_t)fd, DISPATCH_VNODE_ALL, _global.pathwatch_queue);
src = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, (uintptr_t)fd, DISPATCH_VNODE_ALL, get_notifyd_workloop());
if (src == NULL)
{
close(fd);
@ -596,7 +602,6 @@ _vnode_release_for_node(path_node_t *pnode)
/*
* Retain a path_node_t object.
* Dispatched on _global.pathwatch_queue.
*/
static void
_path_node_retain(path_node_t *pnode)
@ -607,7 +612,6 @@ _path_node_retain(path_node_t *pnode)
/*
* Free a path_node_t object.
* Dispatched on _global.pathwatch_queue.
*/
static void
_path_node_free(path_node_t *pnode)
@ -641,7 +645,6 @@ _path_node_free(path_node_t *pnode)
free(pnode->contextp);
dispatch_release(pnode->src);
dispatch_release(pnode->src_queue);
memset(pnode, 0, sizeof(path_node_t));
free(pnode);
@ -655,28 +658,19 @@ _path_node_release(path_node_t *pnode)
{
if (pnode == NULL) return;
/*
* We need to make sure that the node's event handler isn't currently
* executing before freeing the node. We dispatch on the src_queue, so
* that when the block executes there will be no more events in the queue.
* From there, we dispatch async back to the pathwatch_queue to do the
* data structure cleanup.
*/
dispatch_async(pnode->src_queue, ^{
dispatch_async(_global.pathwatch_queue, ^{
if (pnode->refcount > 0) pnode->refcount--;
if (pnode->refcount == 0) _path_node_free(pnode);
});
});
if (pnode->refcount > 0) pnode->refcount--;
if (pnode->refcount == 0) _path_node_free(pnode);
}
/*
* Frees a path_node_t object.
* The work is actually done on the global pathwatch_queue to make this safe.
*/
void
path_node_close(path_node_t *pnode)
{
dispatch_assert_queue(get_notifyd_workloop());
if (pnode == NULL) return;
if (pnode->src != NULL) dispatch_source_cancel(pnode->src);
@ -687,9 +681,6 @@ static void
_pathwatch_init()
{
char buf[MAXPATHLEN];
/* Create serial queue for node creation / deletion operations */
_global.pathwatch_queue = dispatch_queue_create("pathwatch", NULL);
_global.tzdir = NULL;
_global.tzdir_len = 0;
@ -795,7 +786,6 @@ _path_node_init(const char *path)
return pnode;
}
/* dispatched on _global.pathwatch_queue */
static void
_path_node_update(path_node_t *pnode, uint32_t flags, vnode_t *vnode)
{
@ -810,7 +800,7 @@ _path_node_update(path_node_t *pnode, uint32_t flags, vnode_t *vnode)
old_type = pnode->type;
status = _path_stat_check_access(pnode->path, pnode->uid, pnode->gid, &(pnode->type));
status = _path_stat_check_access(pnode->path, pnode->audit, pnode->flags & PATH_NODE_CLIENT_NOTIFYD, &(pnode->type));
if (status == PATH_STAT_ACCESS) flags |= DISPATCH_VNODE_REVOKE;
data = 0;
@ -862,7 +852,7 @@ _path_node_update(path_node_t *pnode, uint32_t flags, vnode_t *vnode)
dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, PNODE_COALESCE_TIME);
_path_node_retain(pnode);
dispatch_after(delay, _global.pathwatch_queue, ^{
dispatch_after(delay, get_notifyd_workloop(), ^{
pnode->flags &= ~PATH_SRC_SUSPENDED;
dispatch_resume(pnode->src);
_path_node_release(pnode);
@ -874,7 +864,7 @@ _path_node_update(path_node_t *pnode, uint32_t flags, vnode_t *vnode)
}
buf = NULL;
if (pnode->plen < MAXPATHLEN) buf = fixed;
if (pnode->plen > MAXPATHLEN) buf = fixed;
else buf = malloc(pnode->plen);
assert(buf != NULL);
@ -928,9 +918,12 @@ _path_node_update(path_node_t *pnode, uint32_t flags, vnode_t *vnode)
* be shared with other path_node_t structures.
*/
path_node_t *
path_node_create(const char *path, uid_t uid, gid_t gid, uint32_t mask, dispatch_queue_t queue)
path_node_create(const char *path, audit_token_t audit, bool is_notifyd, uint32_t mask)
{
path_node_t *pnode;
dispatch_queue_t queue = get_notifyd_workloop();
dispatch_assert_queue(queue);
dispatch_once(&(_global.pathwatch_init), ^{ _pathwatch_init(); });
@ -938,16 +931,17 @@ path_node_create(const char *path, uid_t uid, gid_t gid, uint32_t mask, dispatch
if (pnode == NULL) return NULL;
pnode->refcount = 1;
pnode->uid = uid;
pnode->gid = gid;
pnode->audit = audit;
dispatch_sync(_global.pathwatch_queue, ^{ _path_node_update(pnode, 0, NULL); });
_path_node_update(pnode, 0, NULL);
dispatch_retain(queue);
pnode->src = dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_OR, 0, 0, queue);
pnode->src_queue = queue;
pnode->flags = mask & PATH_NODE_ALL;
if (is_notifyd)
{
pnode->flags |= PATH_NODE_CLIENT_NOTIFYD;
}
return pnode;
}

View File

@ -53,6 +53,8 @@ enum
#define PATH_NODE_ALL 0x000003ff
/* src is suspended */
#define PATH_SRC_SUSPENDED 0x10000000
/* the client is notifyd */
#define PATH_NODE_CLIENT_NOTIFYD 0x20000000
/* Path changes coalesce for 100 milliseconds */
#define PNODE_COALESCE_TIME 100000000
@ -64,21 +66,19 @@ typedef struct
{
char *path;
size_t plen;
uid_t uid;
gid_t gid;
audit_token_t audit;
uint32_t pname_count;
char **pname;
uint32_t type;
uint32_t flags;
dispatch_source_t src;
dispatch_queue_t src_queue;
void *contextp;
uint32_t context32;
uint64_t context64;
uint32_t refcount;
} path_node_t;
path_node_t *path_node_create(const char *path, uid_t uid, gid_t gid, uint32_t mask, dispatch_queue_t queue);
path_node_t *path_node_create(const char *path, audit_token_t audit, bool is_notifyd, uint32_t mask);
void path_node_close(path_node_t *pnode);
#endif /* _PATHWATCH_H_ */

View File

@ -32,6 +32,7 @@
#include "service.h"
#include "pathwatch.h"
#include "timer.h"
#include "notify_internal.h"
#define NOTIFY_PATH_SERVICE "path:"
#define NOTIFY_PATH_SERVICE_LEN 5
@ -81,7 +82,7 @@ service_open_path(const char *name, const char *path, uid_t uid, gid_t gid)
if (path == NULL) return NOTIFY_STATUS_INVALID_REQUEST;
n = (name_info_t *)_nc_table_find(global.notify_state->name_table, name);
n = _nc_table_find(&global.notify_state.name_table, name);
if (n == NULL) return NOTIFY_STATUS_INVALID_NAME;
if (n->private != NULL)
@ -98,8 +99,13 @@ service_open_path(const char *name, const char *path, uid_t uid, gid_t gid)
return NOTIFY_STATUS_OK;
}
node = path_node_create(path, uid, gid, PATH_NODE_ALL, dispatch_get_main_queue());
if (node == NULL) return NOTIFY_STATUS_FAILED;
{
audit_token_t audit;
memset(&audit, 0, sizeof(audit_token_t));
node = path_node_create(path, audit, true, PATH_NODE_ALL);
}
if (node == NULL) return NOTIFY_STATUS_PATH_NODE_CREATE_FAILED;
node->contextp = strdup(name);
@ -111,24 +117,72 @@ service_open_path(const char *name, const char *path, uid_t uid, gid_t gid)
n->private = info;
dispatch_source_set_event_handler(node->src, ^{
dispatch_async(global.work_q, ^{
if (0 == dispatch_source_testcancel(node->src))
{
daemon_post((const char *)node->contextp, uid, gid);
}
});
daemon_post((const char *)node->contextp, uid, gid);
});
dispatch_resume(node->src);
dispatch_activate(node->src);
return NOTIFY_STATUS_OK;
}
static uint16_t service_info_add(void *info)
{
assert(global.service_info_count != UINT16_MAX);
for(int i = 0; i < global.service_info_count; i++)
{
if(global.service_info_list[i] == NULL){
global.service_info_list[i] = info;
return i + 1;
}
}
if(global.service_info_count == 0){
global.service_info_count = 1;
global.service_info_list = malloc(sizeof(void *));
} else {
global.service_info_count++;
global.service_info_list = realloc(global.service_info_list, global.service_info_count * sizeof(void *));
}
global.service_info_list[global.service_info_count - 1] = info;
return global.service_info_count;
}
void *service_info_get(uint16_t index)
{
if(index == 0)
{
return NULL;
}
return global.service_info_list[index - 1];
}
static void *service_info_remove(uint16_t index)
{
if(index == 0)
{
return NULL;
}
void *ret = global.service_info_list[index - 1];
global.service_info_list[index - 1] = NULL;
return ret;
}
/*
* The private (per-client) path watch service.
* Must be callled on global.workloop if it is initialized
*/
int
service_open_path_private(const char *name, client_t *c, const char *path, uid_t uid, gid_t gid, uint32_t flags)
service_open_path_private(const char *name, client_t *c, const char *path, audit_token_t audit, uint32_t flags)
{
name_info_t *n;
svc_info_t *info;
@ -138,14 +192,14 @@ service_open_path_private(const char *name, client_t *c, const char *path, uid_t
if (path == NULL) return NOTIFY_STATUS_INVALID_REQUEST;
n = (name_info_t *)_nc_table_find(global.notify_state->name_table, name);
n = _nc_table_find(&global.notify_state.name_table, name);
if (n == NULL) return NOTIFY_STATUS_INVALID_NAME;
if (c == NULL) return NOTIFY_STATUS_FAILED;
if (c == NULL) return NOTIFY_STATUS_NULL_INPUT;
if (c->private != NULL)
if (c->service_index != 0)
{
/* a client may only have one service */
info = (svc_info_t *)c->private;
info = (svc_info_t *)service_info_get(c->service_index);
if (info->type != SERVICE_TYPE_PATH_PRIVATE) return NOTIFY_STATUS_INVALID_REQUEST;
/* the client must be asking for the same path that is being monitored */
@ -158,28 +212,23 @@ service_open_path_private(const char *name, client_t *c, const char *path, uid_t
if (flags == 0) flags = PATH_NODE_ALL;
node = path_node_create(path, uid, gid, flags, dispatch_get_main_queue());
if (node == NULL) return NOTIFY_STATUS_FAILED;
node = path_node_create(path, audit, false, flags);
if (node == NULL) return NOTIFY_STATUS_PATH_NODE_CREATE_FAILED;
node->context64 = c->client_id;
node->context64 = c->cid.hash_key;
info = (svc_info_t *)calloc(1, sizeof(svc_info_t));
assert(info != NULL);
info->type = SERVICE_TYPE_PATH_PRIVATE;
info->private = node;
c->private = info;
c->service_index = service_info_add(info);
dispatch_source_set_event_handler(node->src, ^{
dispatch_async(global.work_q, ^{
if (0 == dispatch_source_testcancel(node->src))
{
daemon_post_client(node->context64);
}
});
daemon_post_client(node->context64);
});
dispatch_resume(node->src);
dispatch_activate(node->src);
return NOTIFY_STATUS_OK;
}
@ -296,7 +345,7 @@ service_open_timer(const char *name, const char *args)
call_statistics.service_timer++;
n = (name_info_t *)_nc_table_find(global.notify_state->name_table, name);
n = _nc_table_find(&global.notify_state.name_table, name);
if (n == NULL) return NOTIFY_STATUS_INVALID_NAME;
s = f = e = 0;
@ -323,26 +372,26 @@ service_open_timer(const char *name, const char *args)
{
case TIME_EVENT_ONESHOT:
{
timer = timer_oneshot(s, dispatch_get_main_queue());
timer = timer_oneshot(s, global.workloop);
break;
}
case TIME_EVENT_CLOCK:
{
timer = timer_clock(s, f, e, dispatch_get_main_queue());
timer = timer_clock(s, f, e, global.workloop);
break;
}
case TIME_EVENT_CAL:
{
timer = timer_calendar(s, f, d, e, dispatch_get_main_queue());
timer = timer_calendar(s, f, e, d, global.workloop);
break;
}
default:
{
return NOTIFY_STATUS_FAILED;
return NOTIFY_STATUS_INVALID_TIME_EVENT;
}
}
if (timer == NULL) return NOTIFY_STATUS_FAILED;
if (timer == NULL) return NOTIFY_STATUS_TIMER_FAILED;
timer->contextp = strdup(name);
info = (svc_info_t *)calloc(1, sizeof(svc_info_t));
@ -353,15 +402,10 @@ service_open_timer(const char *name, const char *args)
n->private = info;
dispatch_source_set_event_handler(timer->src, ^{
dispatch_async(global.work_q, ^{
if (0 == dispatch_source_testcancel(timer->src))
{
daemon_post((const char *)timer->contextp, 0, 0);
}
});
daemon_post((const char *)timer->contextp, 0, 0);
});
dispatch_resume(timer->src);
dispatch_activate(timer->src);
return NOTIFY_STATUS_OK;
}
@ -378,9 +422,9 @@ service_open_timer_private(const char *name, client_t *c, const char *args)
call_statistics.service_timer++;
n = (name_info_t *)_nc_table_find(global.notify_state->name_table, name);
n = _nc_table_find(&global.notify_state.name_table, name);
if (n == NULL) return NOTIFY_STATUS_INVALID_NAME;
if (c == NULL) return NOTIFY_STATUS_FAILED;
if (c == NULL) return NOTIFY_STATUS_NULL_INPUT;
s = f = e = 0;
d = 0;
@ -388,10 +432,10 @@ service_open_timer_private(const char *name, client_t *c, const char *args)
t = parse_timer_args(args, &s, &f, &e, &d);
if (t == TIME_EVENT_NONE) return NOTIFY_STATUS_INVALID_REQUEST;
if (c->private != NULL)
if (c->service_index != 0)
{
/* a client may only have one service */
info = (svc_info_t *)c->private;
info = (svc_info_t *)service_info_get(c->service_index);
if (info->type != SERVICE_TYPE_TIMER_PRIVATE) return NOTIFY_STATUS_INVALID_REQUEST;
/* the client must be asking for the same timer that is active */
@ -406,52 +450,47 @@ service_open_timer_private(const char *name, client_t *c, const char *args)
{
case TIME_EVENT_ONESHOT:
{
timer = timer_oneshot(s, dispatch_get_main_queue());
timer = timer_oneshot(s, global.workloop);
break;
}
case TIME_EVENT_CLOCK:
{
timer = timer_clock(s, f, e, dispatch_get_main_queue());
timer = timer_clock(s, f, e, global.workloop);
break;
}
case TIME_EVENT_CAL:
{
timer = timer_calendar(s, f, d, e, dispatch_get_main_queue());
timer = timer_calendar(s, f, e, d, global.workloop);
break;
}
default:
{
return NOTIFY_STATUS_FAILED;
return NOTIFY_STATUS_INVALID_TIME_EVENT;
}
}
if (timer == NULL) return NOTIFY_STATUS_FAILED;
timer->context64 = c->client_id;
if (timer == NULL) return NOTIFY_STATUS_TIMER_FAILED;
timer->context64 = c->cid.hash_key;
info = (svc_info_t *)calloc(1, sizeof(svc_info_t));
assert(info != NULL);
info->type = SERVICE_TYPE_TIMER_PRIVATE;
info->private = timer;
c->private = info;
c->service_index = service_info_add(info);
dispatch_source_set_event_handler(timer->src, ^{
dispatch_async(global.work_q, ^{
if (0 == dispatch_source_testcancel(timer->src))
{
daemon_post_client(timer->context64);
}
});
daemon_post_client(timer->context64);
});
dispatch_resume(timer->src);
dispatch_activate(timer->src);
return NOTIFY_STATUS_OK;
}
/* called from server-side routines in notify_proc - services are private to the client */
int
service_open(const char *name, client_t *client, uint32_t uid, uint32_t gid)
service_open(const char *name, client_t *client, audit_token_t audit)
{
uint32_t t, flags;
char *p, *q;
@ -474,11 +513,11 @@ service_open(const char *name, client_t *client, uint32_t uid, uint32_t gid)
q = strchr(p, ':');
if (q != NULL)
{
flags = strtol(p, NULL, 0);
flags = (uint32_t)strtol(p, NULL, 0);
p = q + 1;
}
return service_open_path_private(name, client, p, uid, gid, flags);
return service_open_path_private(name, client, p, audit, flags);
}
case SERVICE_TYPE_TIMER_PRIVATE:
{
@ -496,9 +535,11 @@ service_open(const char *name, client_t *client, uint32_t uid, uint32_t gid)
}
void
service_close(svc_info_t *info)
service_close(uint16_t service_index)
{
if (info == NULL) return;
if (service_index == 0) return;
svc_info_t *info = service_info_remove(service_index);
switch (info->type)
{

View File

@ -39,11 +39,12 @@ typedef struct
void *private;
} svc_info_t;
int service_open(const char *name, client_t *client, uint32_t uid, uint32_t gid);
int service_open(const char *name, client_t *client, audit_token_t audit);
int service_open_path(const char *name, const char *path, uid_t uid, gid_t gid);
int service_open_path_private(const char *name, client_t *client, const char *path, uid_t uid, gid_t gid, uint32_t flags);
int service_open_path_private(const char *name, client_t *client, const char *path, audit_token_t audit, uint32_t flags);
int service_open_timer(const char *name, const char *args);
int service_open_timer_private(const char *name, client_t *client, const char *args);
void service_close(svc_info_t *info);
void service_close(uint16_t service_index);
void *service_info_get(uint16_t index);
#endif /* _NOTIFY_SERVICE_H_ */

View File

@ -1,86 +0,0 @@
/*
* Copyright (c) 2003-2011 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 _NOTIFY_TABLE_H_
#define _NOTIFY_TABLE_H_
#include <stdint.h>
typedef struct __table_private table_t;
typedef struct __list_private list_t;
extern table_t *_nc_table_new(uint32_t n);
extern void _nc_table_insert(table_t *t, const char *key, void *datum);
extern void _nc_table_insert_no_copy(table_t *t, const char *key, void *datum);
extern void _nc_table_insert_n(table_t *t, uint32_t key, void *datum);
extern void _nc_table_insert_64(table_t *t, uint64_t key, void *datum);
extern void *_nc_table_find(table_t *t, const char *key);
extern void *_nc_table_find_n(table_t *t, uint32_t key);
extern void *_nc_table_find_64(table_t *t, uint64_t key);
extern void _nc_table_delete(table_t *t, const char *key);
extern void _nc_table_delete_n(table_t *t, uint32_t key);
extern void _nc_table_delete_64(table_t *t, uint64_t key);
extern void *_nc_table_traverse_start(table_t *tin);
extern void *_nc_table_traverse(table_t *tin, void *ttin);
extern void _nc_table_traverse_end(table_t *tin, void *ttin);
extern void _nc_table_free(table_t *tin);
extern list_t *_nc_list_new(void *d);
extern list_t *_nc_list_retain(list_t *l);
extern list_t *_nc_list_retain_list(list_t *l);
extern void _nc_list_release(list_t *l);
extern void _nc_list_release_list(list_t *l);
extern list_t *_nc_list_prev(list_t *l);
extern list_t *_nc_list_next(list_t *l);
extern void _nc_list_set_next(list_t *l, list_t *n);
extern void _nc_list_set_prev(list_t *l, list_t *p);
extern list_t *_nc_list_head(list_t *l);
extern list_t *_nc_list_tail(list_t *l);
extern list_t *_nc_list_prepend(list_t *l, list_t *n);
extern list_t *_nc_list_append(list_t *l, list_t *n);
extern list_t *_nc_list_concat(list_t *a, list_t *b);
extern void *_nc_list_data(list_t *l);
extern void _nc_list_set_data(list_t *l, void *d);
extern list_t *_nc_list_find(list_t *l, void *d);
extern list_t *_nc_list_find_release(list_t *l, void *d);
extern list_t * _nc_list_reverse(list_t *l);
extern uint32_t _nc_list_count(list_t *l);
extern list_t *_nc_list_extract(list_t *n);
extern list_t *_nc_list_chop(list_t *l);
#endif /* _NOTIFY_TABLE_H_ */

View File

@ -78,7 +78,7 @@ timer_next(timer_t *t, time_t now)
/* shouldn't happen, as TIME_EVENT_CLOCK should always recur */
if (t->freq == 0) return 0;
x = ((t->freq - 1) + now - t->start) / t->freq;
x = (int32_t)(((t->freq - 1) + now - t->start) / t->freq);
next = t->start + (x * t->freq);
return next;
}
@ -236,7 +236,6 @@ timer_next(timer_t *t, time_t now)
}
}
return 0;
}
/*
@ -247,7 +246,6 @@ static void
timer_free(timer_t *t)
{
if (t == NULL) return;
if (t->deactivation_handler != NULL) Block_release(t->deactivation_handler);
if (t->contextp != NULL) free(t->contextp);
dispatch_release(t->t_src);
@ -300,25 +298,12 @@ timer_oneshot(time_t when, dispatch_queue_t queue)
dispatch_source_set_event_handler(t->t_src, ^{
dispatch_source_merge_data(t->src, 1);
dispatch_source_cancel(t->t_src);
if (t->deactivation_handler != NULL)
{
dispatch_async(t->t_queue, ^{ t->deactivation_handler(); });
}
});
dispatch_resume(t->t_src);
dispatch_activate(t->t_src);
return t;
}
void
timer_set_deactivation_handler(timer_t *t, void(^handler)())
{
if (t == NULL) return;
if (t->deactivation_handler != NULL) Block_release(t->deactivation_handler);
t->deactivation_handler = Block_copy(handler);
}
timer_t *
timer_clock(time_t first, time_t freq_sec, time_t end, dispatch_queue_t queue)
{
@ -347,7 +332,7 @@ timer_clock(time_t first, time_t freq_sec, time_t end, dispatch_queue_t queue)
}
t->end = end;
t->freq = freq_sec;
t->freq = (uint32_t)freq_sec;
t->t_queue = queue;
t->t_src = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
@ -364,14 +349,10 @@ timer_clock(time_t first, time_t freq_sec, time_t end, dispatch_queue_t queue)
if ((t->end > 0) && (t->end < (time(0) + freq_sec)))
{
dispatch_source_cancel(t->t_src);
if (t->deactivation_handler != NULL)
{
dispatch_async(t->t_queue, ^{ t->deactivation_handler(); });
}
}
});
dispatch_resume(t->t_src);
dispatch_activate(t->t_src);
return t;
}
@ -394,7 +375,7 @@ timer_calendar(time_t first, time_t freq_mth, time_t end, int day, dispatch_queu
t->start = first;
t->day = day;
t->end = end;
t->freq = freq_mth;
t->freq = (uint32_t)freq_mth;
t->t_queue = queue;
t->t_src = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
@ -415,10 +396,6 @@ timer_calendar(time_t first, time_t freq_mth, time_t end, int day, dispatch_queu
if (x == 0)
{
dispatch_source_cancel(t->t_src);
if (t->deactivation_handler != NULL)
{
dispatch_async(t->t_queue, ^{ t->deactivation_handler(); });
}
}
else
{
@ -426,40 +403,7 @@ timer_calendar(time_t first, time_t freq_mth, time_t end, int day, dispatch_queu
}
});
dispatch_resume(t->t_src);
dispatch_activate(t->t_src);
return t;
}
timer_t *
timer_calendar_long(uint32_t start_year, uint32_t start_month, uint32_t start_day, uint32_t start_hour, uint32_t start_min, uint32_t start_sec, time_t freq, int day, uint32_t end_year, uint32_t end_month, uint32_t end_day, uint32_t end_hour, uint32_t end_min, uint32_t end_sec, dispatch_queue_t queue)
{
struct tm tmp;
time_t first, last;
memset(&tmp, 0, sizeof(struct tm));
tmp.tm_year = start_year - 1900;
tmp.tm_mon = start_month;
tmp.tm_mday = start_day;
tmp.tm_isdst = -1;
tmp.tm_hour = start_hour;
tmp.tm_min = start_min;
tmp.tm_sec = start_sec;
first = mktime(&tmp);
if (freq == 0) return timer_oneshot(first, queue);
memset(&tmp, 0, sizeof(struct tm));
tmp.tm_year = end_year;
tmp.tm_mon = end_month;
tmp.tm_mday = end_day;
tmp.tm_isdst = -1;
tmp.tm_hour = end_hour;
tmp.tm_min = end_min;
tmp.tm_sec = end_sec;
last = mktime(&tmp);
return timer_calendar(first, freq, day, last, queue);
}

View File

@ -35,25 +35,22 @@
*/
typedef struct
{
uint32_t type;
int64_t start;
int64_t end;
uint32_t freq;
int32_t day;
int64_t next;
void (^deactivation_handler)();
dispatch_source_t src;
dispatch_source_t t_src;
dispatch_queue_t t_queue;
void *contextp;
uint32_t context32;
int64_t start;
int64_t end;
int64_t next;
uint64_t context64;
uint32_t freq;
uint32_t type;
int32_t day;
uint32_t context32;
} timer_t;
timer_t *timer_oneshot(time_t when, dispatch_queue_t queue);
timer_t *timer_clock(time_t first, time_t freq_sec, time_t end, dispatch_queue_t queue);
timer_t *timer_calendar(time_t first, time_t freq_mth, time_t end, int day, dispatch_queue_t queue);
timer_t *timer_calendar_long(uint32_t yf, uint32_t mf, uint32_t df, uint32_t hf, uint32_t nf, uint32_t sf, time_t fm, int d, uint32_t ye, uint32_t me, uint32_t de, uint32_t he, uint32_t ne, uint32_t se, dispatch_queue_t queue);
void timer_set_deactivation_handler(timer_t *t, void(^handler)());
void timer_close(timer_t *t);

2
src/libnotify/notifyd/xcodescripts/mk_notify_conf.sh Executable file → Normal file
View File

@ -1,5 +1,5 @@
set -e -x
ETCDIR="$DSTROOT$INSTALL_PATH_PREFIX"/private/etc
ETCDIR="$DSTROOT"/private/etc
install -d -o root -g wheel -m 0755 "$ETCDIR"
install -c -o root -g wheel -m 0644 \
"$SRCROOT"/notifyd/"$NOTIFY_CONFIG" \

View File

@ -33,6 +33,7 @@
#include <notify_private.h>
#include <signal.h>
#include <dispatch/dispatch.h>
#include <os/variant_private.h>
#define forever for(;;)
#define IndexNull ((uint32_t)-1)
@ -42,6 +43,7 @@
#define PRINT_STATE 0x00000002
#define PRINT_TIME 0x00000004
#define PRINT_TYPE 0x00000008
#define PRINT_TOKEN 0x00000010
#define PRINT_VERBOSE 0xffffffff
#ifndef USEC_PER_SEC
@ -67,8 +69,6 @@ static const char *typename[] =
"plain"
};
extern uint32_t notify_register_plain(const char *name, int *out_token);
typedef struct
{
uint32_t token;
@ -86,11 +86,11 @@ static int port_flag;
static int file_flag;
static int watch_file;
static mach_port_t watch_port;
dispatch_source_t timer_src;
dispatch_source_t port_src;
dispatch_source_t file_src;
dispatch_source_t sig_src[__DARWIN_NSIG];
dispatch_queue_t watch_queue;
static dispatch_source_t timer_src;
static dispatch_source_t port_src;
static dispatch_source_t file_src;
static dispatch_source_t sig_src[__DARWIN_NSIG];
static dispatch_queue_t watch_queue;
static void
usage(const char *name)
@ -108,29 +108,33 @@ usage(const char *name)
fprintf(stderr, " -signal [#] switch to signal [#] for subsequent registrations\n");
fprintf(stderr, " initial default for signal is 1 (SIGHUP)\n");
fprintf(stderr, " -dispatch switch to dispatch for subsequent registrations\n");
fprintf(stderr, " -p key post a notifcation for key\n");
fprintf(stderr, " -p key post a notification for key\n");
fprintf(stderr, " -w key register for key and report notifications\n");
fprintf(stderr, " -# key (# is an integer value, eg \"-1\") register for key and report # notifications\n");
fprintf(stderr, " -g key get state value for key\n");
fprintf(stderr, " -s key val set state value for key\n");
if(os_variant_has_internal_diagnostics(NULL))
{
fprintf(stderr, " --dump dumps metadata to a file in /var/run/\n");
}
}
static const char *
notify_status_strerror(int status)
// Triggers a notifyd dump
static void
notifyutil_dump()
{
switch (status)
int ret;
ret = notify_dump_status("/var/run/notifyd.status");
if(ret == NOTIFY_STATUS_OK)
{
case NOTIFY_STATUS_OK: return("OK");
case NOTIFY_STATUS_INVALID_NAME: return "Invalid Name";
case NOTIFY_STATUS_INVALID_TOKEN: return "Invalid Token";
case NOTIFY_STATUS_INVALID_PORT: return "Invalid Port";
case NOTIFY_STATUS_INVALID_FILE: return "Invalid File";
case NOTIFY_STATUS_INVALID_SIGNAL: return "Invalid Signal";
case NOTIFY_STATUS_INVALID_REQUEST: return "Invalid Request";
case NOTIFY_STATUS_NOT_AUTHORIZED: return "Not Authorized";
case NOTIFY_STATUS_FAILED:
default: return "Failed";
fprintf(stdout, "Notifyd dump success! New file created at /var/run/notifyd.status\n");
} else {
fprintf(stdout, "Notifyd dump failed with %x\n", ret);
}
}
static void
@ -191,15 +195,6 @@ reg_delete(uint32_t index)
}
}
static uint32_t
reg_find_name(const char *name)
{
uint32_t i;
for (i = 0; i < reg_count; i++) if (!strcmp(reg[i].name, name)) return i;
return IndexNull;
}
static uint32_t
reg_find_token(uint32_t tid)
{
@ -224,8 +219,15 @@ process_event(int tid)
needspace = 0;
if (printopt & PRINT_TOKEN)
{
printf("[%d]", tid);
needspace = 1;
}
if (printopt & PRINT_TIME)
{
if (needspace) printf(" ");
snprintf(tstr, sizeof(tstr), "%llu", now.tv_usec + USEC_PER_SEC + 500);
tstr[4] = '\0';
printf("%d.%s", (int)now.tv_sec, tstr+1);
@ -245,7 +247,7 @@ process_event(int tid)
state = 0;
status = notify_get_state(tid, &state);
if (status == NOTIFY_STATUS_OK) printf("%llu",(unsigned long long)state);
else printf(": %s", notify_status_strerror(status));
else printf(": Failed with code %d", status);
needspace = 1;
}
@ -264,6 +266,9 @@ process_event(int tid)
status = notify_cancel(tid);
reg_delete(index);
}
fflush(stdout);
if (reg_count == 0) exit(0);
}
static void
@ -323,9 +328,9 @@ signal_handler(uint32_t sig)
}
static void
dispatch_handler(const char *name)
dispatch_handler(int x)
{
uint32_t index = reg_find_name(name);
uint32_t index = reg_find_token(x);
if (index == IndexNull) return;
process_event(reg[index].token);
@ -417,7 +422,7 @@ do_register(const char *name, uint32_t type, uint32_t signum, uint32_t count)
case TYPE_DISPATCH:
{
status = notify_register_dispatch(name, &tid, watch_queue, ^(int x){ dispatch_handler(name); });
status = notify_register_dispatch(name, &tid, watch_queue, ^(int x){ dispatch_handler(x); });
if (status != NOTIFY_STATUS_OK) return status;
break;
}
@ -473,7 +478,7 @@ int
main(int argc, const char *argv[])
{
const char *name;
uint32_t i, n, index, signum, ntype, status, opts, nap;
uint32_t i, n, signum, ntype, status, opts, nap;
int tid;
uint64_t state;
@ -510,7 +515,7 @@ main(int argc, const char *argv[])
}
else if (!strcmp(argv[i], "-M"))
{
opts |= NOTIFY_OPT_DEMUX;
opts |= NOTIFY_OPT_DISPATCH;
}
else if (!strcmp(argv[i], "-R"))
{
@ -620,6 +625,12 @@ main(int argc, const char *argv[])
fprintf(stderr, "value following -s name must be a 64-bit integer\n");
}
}
else if (!strcmp(argv[i], "--dump") && os_variant_has_internal_diagnostics(NULL))
{
notifyutil_dump();
exit(0);
}
else
{
fprintf(stderr, "unrecognized option: %s\n", argv[i]);
@ -673,7 +684,7 @@ main(int argc, const char *argv[])
i++;
status = notify_post(argv[i]);
if (status != NOTIFY_STATUS_OK) printf("%s: %s\n", argv[i], notify_status_strerror(status));
if (status != NOTIFY_STATUS_OK) printf("%s: Failed with code %d\n", argv[i], status);
else if (nap > 0) usleep(nap);
}
else if ((argv[i][0] == '-') && ((argv[i][1] == 'w') || ((argv[i][1] >= '0') && (argv[i][1] <= '9'))))
@ -690,15 +701,8 @@ main(int argc, const char *argv[])
i++;
tid = IndexNull;
index = reg_find_name(argv[i]);
if (index != IndexNull)
{
fprintf(stderr, "Already watching for %s\n", argv[i]);
continue;
}
status = do_register(argv[i], ntype, signum, n);
if (status != NOTIFY_STATUS_OK) printf("%s: %s\n", argv[i], notify_status_strerror(status));
if (status != NOTIFY_STATUS_OK) printf("%s: Failed with code %d\n", argv[i], status);
}
else if (!strcmp(argv[i], "-g"))
{
@ -720,7 +724,7 @@ main(int argc, const char *argv[])
}
if (status == NOTIFY_STATUS_OK) printf("%s %llu\n", argv[i], (unsigned long long)state);
else printf("%s: %s\n", argv[i], notify_status_strerror(status));
else printf("%s: Failed with code %d\n", argv[i], status);
}
else if (!strcmp(argv[i], "-s"))
{
@ -740,7 +744,7 @@ main(int argc, const char *argv[])
notify_cancel(tid);
}
if (status != NOTIFY_STATUS_OK) printf("%s: %s\n", argv[i], notify_status_strerror(status));
if (status != NOTIFY_STATUS_OK) printf("%s: Failed with code %d\n", argv[i], status);
i++;
}
}

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.private.libnotify.statecapture</key>
<true/>
</dict>
</plist>

View File

@ -1 +0,0 @@
../libc/gen/

View File

@ -1,4 +1,3 @@
// Modified by Lubos Dolezel for Darling build
/*
* Copyright (c) 2003-2011 Apple Inc. All rights reserved.
*
@ -22,747 +21,104 @@
* @APPLE_LICENSE_HEADER_END@
*/
#include <os/base.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <sys/types.h>
#include <sys/param.h>
#include <os/assumes.h>
#include "table.h"
#include "notify_internal.h"
#ifndef os_assumes
# define os_assumes(x) (x)
#endif
#define TABLE_TOMBSTONE ((void *)~0)
#define TABLE_MINSHIFT 5
#define TABLE_MINSIZE (1 << TABLE_MINSHIFT)
#define KEY_UNKNOWN 0
#define KEY_INT 1
#define KEY_STR_MINE 2
#define KEY_STR_SHARED 3
#define DEFAULT_SIZE 256
typedef struct table_node_s
OS_ALWAYS_INLINE
static inline uint32_t
table_next(uint32_t i, uint32_t size)
{
union
{
char *string;
const char *const_string;
uint64_t uint64;
} key;
void *datum;
struct table_node_s *next;
} table_node_t;
i++;
return i >= size ? 0 : i;
}
typedef struct __table_private
OS_ALWAYS_INLINE
static inline uint32_t
table_prev(uint32_t i, uint32_t size)
{
uint32_t type;
uint32_t bucket_count;
table_node_t **bucket;
} table_private_t;
return (i ? i : size) - 1;
}
typedef struct
static inline bool
string_equals(const char *a, const char *b)
{
uint32_t bucket_index;
table_node_t *node;
} table_traverse_t;
typedef struct __list_private
{
struct __list_private *prev;
struct __list_private *next;
uint32_t refcount;
void *data;
} list_private_t;
table_t *
_nc_table_new(uint32_t n)
{
table_private_t *t;
t = (table_t *)malloc(sizeof(table_t));
if (t == NULL) return NULL;
if (n == 0) n = DEFAULT_SIZE;
t->type = KEY_UNKNOWN;
t->bucket_count = n;
t->bucket = (table_node_t **)calloc(t->bucket_count, sizeof(table_node_t *));
if (t->bucket == NULL)
{
free(t);
return NULL;
}
return (table_t *)t;
return a == b || strcmp(a, b) == 0;
}
static uint32_t
hash_key(int size, const char *key)
string_hash(const char *key)
{
uint32_t v;
char *p;
uint32_t hash = 0;
if (key == NULL) return 0;
for (; *key; key++) {
hash += (unsigned char)(*key);
hash += (hash << 10);
hash ^= (hash >> 6);
}
v = 0;
for (p = (char *)key; *p != '\0'; p++)
{
v = (v << 1) ^ (v ^ *p);
}
hash += (hash << 3);
hash ^= (hash >> 11);
hash += (hash << 15);
v %= size;
return v;
return hash;
}
static uint32_t
hash_nkey(uint32_t size, uint64_t key)
static inline bool
uint32_equals(uint32_t a, uint32_t b)
{
uint32_t x = key;
uint32_t y = key >> 32;
return ((x ^ y) % size);
return a == b;
}
void *
_nc_table_find_get_key(table_t *tin, const char *key, const char **shared_key)
static inline uint32_t
uint32_hash(uint32_t x)
{
table_private_t *t;
table_node_t *n;
uint32_t b;
if (tin == NULL) return NULL;
if (key == NULL) return NULL;
if (shared_key != NULL) *shared_key = NULL;
t = (table_private_t *)tin;
b = hash_key(t->bucket_count, key);
for (n = t->bucket[b]; n != NULL; n = n->next)
{
if ((n->key.string != NULL) && (!strcmp(key, n->key.string)))
{
if (shared_key != NULL) *shared_key = n->key.const_string;
return n->datum;
}
}
return NULL;
x = ((x >> 16) ^ x) * 0x45d9f3b;
x = ((x >> 16) ^ x) * 0x45d9f3b;
x = (x >> 16) ^ x;
return x;
}
void *
_nc_table_find(table_t *tin, const char *key)
static inline bool
uint64_equals(uint64_t a, uint64_t b)
{
return _nc_table_find_get_key(tin, key, NULL);
return a == b;
}
void *
_nc_table_find_64(table_t *tin, uint64_t key)
static inline uint32_t
uint64_hash(uint64_t key)
{
table_private_t *t;
table_node_t *n;
uint32_t b;
if (tin == NULL) return NULL;
t = (table_private_t *)tin;
b = hash_nkey(t->bucket_count, key);
for (n = t->bucket[b]; n != NULL; n = n->next)
{
if ((n->key.uint64 != (uint64_t)-1) && (key == n->key.uint64)) return n->datum;
}
return NULL;
return uint32_hash((uint32_t)key ^ (uint32_t)(key >> 32));
}
void *
_nc_table_find_n(table_t *tin, uint32_t key)
{
uint64_t n64 = key;
return _nc_table_find_64(tin, n64);
}
static void
_nc_table_insert_type(table_t *tin, int type, char *key, const char *ckey, void *datum)
{
table_private_t *t;
table_node_t *n;
uint32_t b;
if (tin == NULL) return;
if ((key == NULL) && (ckey == NULL)) return;
if (datum == NULL) return;
t = (table_private_t *)tin;
if (t->type == KEY_UNKNOWN) t->type = type;
else os_assumes(t->type == type);
n = (table_node_t *)malloc(sizeof(table_node_t));
if (key != NULL)
{
b = hash_key(t->bucket_count, key);
n->key.string = key;
}
else
{
b = hash_key(t->bucket_count, ckey);
n->key.const_string = ckey;
}
n->datum = datum;
n->next = t->bucket[b];
t->bucket[b] = n;
}
void
_nc_table_insert(table_t *tin, const char *key, void *datum)
{
char *dup;
if (tin == NULL) return;
if (key == NULL) return;
if (datum == NULL) return;
dup = strdup(key);
if (dup == NULL) return;
_nc_table_insert_type(tin, KEY_STR_MINE, dup, NULL, datum);
}
void
_nc_table_insert_no_copy(table_t *tin, const char *key, void *datum)
{
if (tin == NULL) return;
if (key == NULL) return;
if (datum == NULL) return;
_nc_table_insert_type(tin, KEY_STR_SHARED, NULL, key, datum);
}
void
_nc_table_insert_pass(table_t *tin, char *key, void *datum)
{
if (tin == NULL) return;
if (key == NULL) return;
if (datum == NULL) return;
_nc_table_insert_type(tin, KEY_STR_MINE, key, NULL, datum);
}
void
_nc_table_insert_64(table_t *tin, uint64_t key, void *datum)
{
table_private_t *t;
table_node_t *n;
uint32_t b;
if (tin == NULL) return;
if (datum == NULL) return;
t = (table_private_t *)tin;
if (t->type == KEY_UNKNOWN) t->type = KEY_INT;
else os_assumes(t->type == KEY_INT);
b = hash_nkey(t->bucket_count, key);
n = (table_node_t *)malloc(sizeof(table_node_t));
n->key.uint64 = key;
n->datum = datum;
n->next = t->bucket[b];
t->bucket[b] = n;
}
void
_nc_table_insert_n(table_t *tin, uint32_t key, void *datum)
{
uint64_t n64 = key;
_nc_table_insert_64(tin, n64, datum);
}
void
_nc_table_delete(table_t *tin, const char *key)
{
table_private_t *t;
table_node_t *n, *p;
uint32_t b;
if (tin == NULL) return;
if (key == NULL) return;
t = (table_private_t *)tin;
os_assumes((t->type == KEY_STR_MINE) || (t->type == KEY_STR_SHARED));
b = hash_key(t->bucket_count, key);
p = NULL;
for (n = t->bucket[b]; n != NULL; n = n->next)
{
if ((n->key.string != NULL) && (!strcmp(key, n->key.string)))
{
if (p == NULL) t->bucket[b] = n->next;
else p->next = n->next;
if (t->type == KEY_STR_MINE) free(n->key.string);
free(n);
return;
}
p = n;
}
}
void
_nc_table_delete_64(table_t *tin, uint64_t key)
{
table_private_t *t;
table_node_t *n, *p;
uint32_t b;
if (tin == NULL) return;
t = (table_private_t *)tin;
os_assumes(t->type == KEY_INT);
b = hash_nkey(t->bucket_count, key);
p = NULL;
for (n = t->bucket[b]; n != NULL; n = n->next)
{
if ((n->key.uint64 != (uint64_t)-1) && (key == n->key.uint64))
{
if (p == NULL) t->bucket[b] = n->next;
else p->next = n->next;
free(n);
return;
}
p = n;
}
}
void
_nc_table_delete_n(table_t *tin, uint32_t key)
{
uint64_t n64 = key;
_nc_table_delete_64(tin, n64);
}
void *
_nc_table_traverse_start(table_t *tin)
{
table_traverse_t *tt;
table_private_t *t;
uint32_t b;
if (tin == NULL) return NULL;
t = (table_private_t *)tin;
if (t->bucket_count == 0) return NULL;
for (b = 0; b < t->bucket_count; b++)
{
if (t->bucket[b] != NULL)
{
tt = (table_traverse_t *)malloc(sizeof(table_traverse_t));
if (tt == NULL) return NULL;
tt->bucket_index = b;
tt->node = t->bucket[b];
return (void *)tt;
}
}
return NULL;
}
void *
_nc_table_traverse(table_t *tin, void *ttin)
{
table_private_t *t;
table_traverse_t *tt;
void *datum;
uint32_t b;
if (tin == NULL) return NULL;
if (ttin == NULL) return NULL;
t = (table_private_t *)tin;
tt = (table_traverse_t *)ttin;
if (tt->node == NULL) return NULL;
datum = tt->node->datum;
tt->node = tt->node->next;
if (tt->node != NULL) return datum;
for (b = tt->bucket_index + 1; b < t->bucket_count; b++)
{
if (t->bucket[b] != NULL)
{
tt->bucket_index = b;
tt->node = t->bucket[b];
return datum;
}
}
tt->bucket_index = b;
tt->node = NULL;
return datum;
}
void
_nc_table_traverse_end(table_t *tin, void *ttin)
{
if (ttin == NULL) return;
free(ttin);
}
void
_nc_table_free(table_t *tin)
{
table_private_t *t;
table_node_t *n, *x;
uint32_t b;
if (tin == NULL) return;
t = (table_private_t *)tin;
for (b = 0; b < t->bucket_count; b++)
{
x = NULL;
for (n = t->bucket[b]; n != NULL; n = x)
{
x = n->next;
if (t->type == KEY_STR_MINE) free(n->key.string);
free(n);
}
}
free(t->bucket);
free(t);
}
/* Linked List */
/*
* Make a new node
*/
list_t *
_nc_list_new(void *d)
{
list_t *n;
n = (list_t *)calloc(1, sizeof(list_t));
if (n == NULL) return NULL;
n->refcount = 1;
n->data = d;
return n;
}
/*
* Release a node
*/
void
_nc_list_release(list_t *l)
{
if (l == NULL) return;
l->refcount--;
if (l->refcount > 0) return;
free(l);
}
/*
* Retain a node
*/
list_t *
_nc_list_retain(list_t *l)
{
if (l == NULL) return NULL;
l->refcount++;
return l;
}
/*
* Retain a list
*/
list_t *
_nc_list_retain_list(list_t *l)
{
list_t *n;
for (n = l; n != NULL; n = n->next) n->refcount++;
return l;
}
/*
* Get previous node
*/
list_t *
_nc_list_prev(list_t *l)
{
if (l == NULL) return NULL;
return l->prev;
}
/*
* Get next node
*/
list_t *
_nc_list_next(list_t *l)
{
if (l == NULL) return NULL;
return l->next;
}
/*
* Get head (first node) of list
*/
list_t *
_nc_list_head(list_t *l)
{
list_t *p;
if (l == NULL) return NULL;
for (p = l; p->prev != NULL; p = p->prev);
return p;
}
/*
* Get tail (last node) of list
*/
list_t *
_nc_list_tail(list_t *l)
{
list_t *p;
if (l == NULL) return NULL;
for (p = l; p->next != NULL; p = p->next);
return p;
}
/*
* Insert a node in front of another node.
* Cuts list if n is NULL.
*/
list_t *
_nc_list_prepend(list_t *l, list_t *n)
{
if (l == NULL) return n;
if (n != NULL)
{
n->next = l;
n->prev = l->prev;
}
if (l->prev != NULL) l->prev->next = n;
l->prev = n;
return n;
}
/*
* Append a node after another node.
* Cuts list if n is NULL.
*/
list_t *
_nc_list_append(list_t *l, list_t *n)
{
if (l == NULL) return n;
if (n != NULL)
{
n->prev = l;
n->next = l->next;
}
if (l->next != NULL) n->next->prev = n;
l->next = n;
return n;
}
/*
* Set next pointer - use with care.
*/
void
_nc_list_set_next(list_t *l, list_t *n)
{
if (l == NULL) return;
l->next = n;
}
/*
* Set prev pointer - use with care.
*/
void
_nc_list_set_prev(list_t *l, list_t *p)
{
if (l == NULL) return;
l->prev = p;
}
/*
* Concatenate two lists.
* Returns new head.
*/
list_t *
_nc_list_concat(list_t *a, list_t *b)
{
list_t *p;
if (a == NULL) return b;
if (b == NULL) return a;
for (p = a; p->next != NULL; p = p->next);
p->next = b;
b->prev = p;
for (p = a; p->prev != NULL; p = p->prev);
return p;
}
uint32_t
_nc_list_count(list_t *l)
{
uint32_t n;
list_t *p;
n = 0;
for (p = l; p != NULL; p = p->next) n++;
return n;
}
void *
_nc_list_data(list_t *l)
{
if (l == NULL) return NULL;
return l->data;
}
void
_nc_list_set_data(list_t *l, void *d)
{
if (l != NULL) l->data = d;
}
list_t *
_nc_list_find(list_t *l, void *d)
{
list_t *p;
if (l == NULL) return NULL;
for (p = l; p != NULL; p = p->next)
{
if (p->data == d) return p;
}
return NULL;
}
list_t *
_nc_list_find_release(list_t *l, void *d)
{
list_t *p;
if (l == NULL) return NULL;
if (l->data == d)
{
p = l->next;
if (p != NULL) p->prev = NULL;
_nc_list_release(l);
return p;
}
for (p = l->next; p != NULL; p = p->next)
{
if (p->data == d)
{
p->prev->next = p->next;
if (p->next != NULL) p->next->prev = p->prev;
_nc_list_release(p);
return l;
}
}
return l;
}
list_t *
_nc_list_reverse(list_t *l)
{
list_t *x, *s, *r;
if (l == NULL) return NULL;
x = l->prev;
r = l;
s = l->next;
while (s != NULL)
{
s = r->next;
r->next = r->prev;
r->prev = s;
if (s != NULL) r = s;
}
if (x != NULL)
{
x->next = r;
r->prev = x;
}
return r;
}
list_t *
_nc_list_extract(list_t *n)
{
if (n == NULL) return NULL;
if (n->prev != NULL) n->prev->next = n->next;
if (n->next != NULL) n->next->prev = n->prev;
n->prev = NULL;
n->next = NULL;
return n;
}
list_t *
_nc_list_chop(list_t *l)
{
list_t *p;
if (l == NULL) return NULL;
p = l->next;
if (p != NULL) p->prev = NULL;
_nc_list_release(l);
return p;
}
void
_nc_list_release_list(list_t *l)
{
list_t *p, *n;
if (l == NULL) return;
if (l->prev != NULL) l->prev->next = NULL;
p = l;
while (p != NULL)
{
n = p->next;
_nc_list_release(p);
p = n;
}
}
#define ns(n) _nc_table##n
#define key_t char *
#define ckey_t const char *
#define key_hash string_hash
#define key_equals string_equals
#include "table.in.c"
#define ns(n) _nc_table##n##_n
#define key_t uint32_t
#define ckey_t uint32_t
#define key_hash uint32_hash
#define key_equals uint32_equals
#include "table.in.c"
#define ns(n) _nc_table##n##_64
#define key_t uint64_t
#define ckey_t uint64_t
#define key_hash uint64_hash
#define key_equals uint64_equals
#include "table.in.c"

View File

@ -24,65 +24,45 @@
#ifndef _NOTIFY_TABLE_H_
#define _NOTIFY_TABLE_H_
#include <os/base.h>
#include <stdint.h>
typedef struct __table_private table_t;
typedef struct __list_private list_t;
#define _nc_table(key_t, _ns) \
struct _nc_table##_ns { \
uint32_t count; \
uint32_t tombstones; \
uint32_t size; \
uint16_t grow_shift; \
uint16_t key_offset; \
key_t **keys; \
}
extern table_t *_nc_table_new(uint32_t n);
typedef _nc_table(char *, ) table_t;
typedef _nc_table(uint32_t, _n) table_n_t;
typedef _nc_table(uint64_t, _64) table_64_t;
extern void _nc_table_insert(table_t *t, const char *key, void *datum);
extern void _nc_table_insert_no_copy(table_t *t, const char *key, void *datum);
extern void _nc_table_insert_pass(table_t *t, char *key, void *datum);
extern void _nc_table_insert_n(table_t *t, uint32_t key, void *datum);
extern void _nc_table_insert_64(table_t *t, uint64_t key, void *datum);
__BEGIN_DECLS
extern void _nc_table_init(table_t *t, size_t key_offset);
extern void _nc_table_init_n(table_n_t *t, size_t key_offset);
extern void _nc_table_init_64(table_64_t *t, size_t key_offset);
extern void _nc_table_insert(table_t *t, char **key);
extern void _nc_table_insert_n(table_n_t *t, uint32_t *key);
extern void _nc_table_insert_64(table_64_t *t, uint64_t *key);
extern void *_nc_table_find(table_t *t, const char *key);
extern void *_nc_table_find_get_key(table_t *tin, const char *key, const char **shared_key);
extern void *_nc_table_find_n(table_t *t, uint32_t key);
extern void *_nc_table_find_64(table_t *t, uint64_t key);
extern void *_nc_table_find_n(table_n_t *t, uint32_t key);
extern void *_nc_table_find_64(table_64_t *t, uint64_t key);
extern void _nc_table_delete(table_t *t, const char *key);
extern void _nc_table_delete_n(table_t *t, uint32_t key);
extern void _nc_table_delete_64(table_t *t, uint64_t key);
extern void _nc_table_delete_n(table_n_t *t, uint32_t key);
extern void _nc_table_delete_64(table_64_t *t, uint64_t key);
extern void *_nc_table_traverse_start(table_t *tin);
extern void *_nc_table_traverse(table_t *tin, void *ttin);
extern void _nc_table_traverse_end(table_t *tin, void *ttin);
extern void _nc_table_foreach(table_t *t, OS_NOESCAPE bool (^)(void *));
extern void _nc_table_foreach_n(table_n_t *t, OS_NOESCAPE bool (^)(void *));
extern void _nc_table_foreach_64(table_64_t *t, OS_NOESCAPE bool (^)(void *));
extern void _nc_table_free(table_t *tin);
extern list_t *_nc_list_new(void *d);
extern list_t *_nc_list_retain(list_t *l);
extern list_t *_nc_list_retain_list(list_t *l);
extern void _nc_list_release(list_t *l);
extern void _nc_list_release_list(list_t *l);
extern list_t *_nc_list_prev(list_t *l);
extern list_t *_nc_list_next(list_t *l);
extern void _nc_list_set_next(list_t *l, list_t *n);
extern void _nc_list_set_prev(list_t *l, list_t *p);
extern list_t *_nc_list_head(list_t *l);
extern list_t *_nc_list_tail(list_t *l);
extern list_t *_nc_list_prepend(list_t *l, list_t *n);
extern list_t *_nc_list_append(list_t *l, list_t *n);
extern list_t *_nc_list_concat(list_t *a, list_t *b);
extern void *_nc_list_data(list_t *l);
extern void _nc_list_set_data(list_t *l, void *d);
extern list_t *_nc_list_find(list_t *l, void *d);
extern list_t *_nc_list_find_release(list_t *l, void *d);
extern list_t * _nc_list_reverse(list_t *l);
extern uint32_t _nc_list_count(list_t *l);
extern list_t *_nc_list_extract(list_t *n);
extern list_t *_nc_list_chop(list_t *l);
__END_DECLS
#endif /* _NOTIFY_TABLE_H_ */

209
src/libnotify/table.in.c Normal file
View File

@ -0,0 +1,209 @@
/*
* Copyright (c) 2018 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@
*/
static inline void *
ns(_value)(struct ns() *t, uint32_t i)
{
return (void *)((uintptr_t)t->keys[i] - t->key_offset);
}
static inline void
ns(_clear)(struct ns() *t)
{
free(t->keys);
ns(_init)(t, t->key_offset);
}
void
ns(_init)(struct ns() *t, size_t offset)
{
*t = (struct ns()){
.grow_shift = TABLE_MINSHIFT,
.key_offset = (uint16_t)offset,
};
}
OS_NOINLINE
static void
ns(_rehash)(struct ns() *t, int direction)
{
struct ns() old = *t;
if (direction > 0) {
t->size += (1 << t->grow_shift);
if (t->size == (8 << t->grow_shift)) {
t->grow_shift++;
}
} else if (direction < 0) {
if (t->grow_shift > TABLE_MINSHIFT) {
t->grow_shift--;
}
t->size = roundup(t->size / 2, (1 << t->grow_shift));
}
t->count = 0;
t->tombstones = 0;
t->keys = calloc(t->size, sizeof(key_t *));
if (t->keys == NULL) {
NOTIFY_INTERNAL_CRASH(0, "Unable to grow table: registration leak?");
}
for (uint32_t i = 0; i < old.size; i++) {
if (old.keys[i] == NULL || old.keys[i] == TABLE_TOMBSTONE) {
continue;
}
ns(_insert)(t, old.keys[i]);
}
free(old.keys);
}
void *
ns(_find)(struct ns() *t, ckey_t key)
{
if (t->count == 0) {
return NULL;
}
uint32_t size = t->size, loop_limit = t->size;
uint32_t i = key_hash(key) % size;
for (;;) {
if (os_unlikely(loop_limit-- == 0)) {
NOTIFY_INTERNAL_CRASH(0, "Corrupt hash table");
}
if (t->keys[i] != TABLE_TOMBSTONE) {
if (t->keys[i] == NULL) {
return NULL;
}
if (key_equals(key, *t->keys[i])) {
return ns(_value)(t, i);
}
}
i = table_next(i, size);
}
}
void
ns(_insert)(struct ns() *t, key_t *key)
{
/*
* Our algorithm relies on having enough NULLS to end loops.
* Make sure their density is never below 25%.
*
* When it drops too low, if the ratio of tombstones is low,
* assume we're on a growth codepath.
*
* Else, we just rehash in place to prune tombstones.
*/
if (os_unlikely(t->count + t->tombstones >= 3 * t->size / 4)) {
if (t->count >= 4 * t->tombstones) {
ns(_rehash)(t, 1);
} else {
ns(_rehash)(t, 0);
}
}
uint32_t size = t->size, loop_limit = t->size;
uint32_t i = key_hash(*key) % size;
for (;;) {
if (os_unlikely(loop_limit-- == 0)) {
NOTIFY_INTERNAL_CRASH(0, "Corrupt hash table");
}
if (t->keys[i] == NULL) {
break;
}
if (t->keys[i] == TABLE_TOMBSTONE) {
t->tombstones--;
break;
}
i = table_next(i, size);
}
t->keys[i] = key;
t->count++;
}
void
ns(_delete)(struct ns() *t, ckey_t key)
{
if (t->count == 0) {
return;
}
uint32_t size = t->size, loop_limit = t->size;
uint32_t i = key_hash(key) % size;
for (;;) {
if (os_unlikely(loop_limit-- == 0)) {
NOTIFY_INTERNAL_CRASH(0, "Corrupt hash table");
}
if (t->keys[i] != TABLE_TOMBSTONE) {
if (t->keys[i] == NULL) {
return;
}
if (key_equals(key, *t->keys[i])) {
break;
}
}
i = table_next(i, size);
}
t->keys[i] = TABLE_TOMBSTONE;
t->tombstones++;
t->count--;
if (t->keys[table_next(i, size)] == NULL) {
do {
t->tombstones--;
t->keys[i] = NULL;
i = table_prev(i, size);
} while (t->keys[i] == TABLE_TOMBSTONE);
}
if (t->count == 0) {
/* if the table is empty, free all its resources */
ns(_clear)(t);
} else if (t->size >= TABLE_MINSIZE * 2 && t->count < t->size / 8) {
/* if the table density drops below 12%, shrink it */
ns(_rehash)(t, -1);
}
}
void
ns(_foreach)(struct ns() *t, bool (^handler)(void *))
{
for (uint32_t i = 0; i < t->size; i++) {
if (t->keys[i] != NULL && t->keys[i] != TABLE_TOMBSTONE) {
if (!handler(ns(_value)(t, i))) break;
}
}
}
#undef ns
#undef key_t
#undef ckey_t
#undef key_hash
#undef key_equals
#undef make_map

View File

@ -1,7 +1,7 @@
#include "<DEVELOPER_DIR>/Makefiles/CoreOS/Xcode/BSD.xcconfig"
#include "<DEVELOPER_DIR>/AppleInternal/XcodeConfig/SimulatorSupport.xcconfig"
INSTALL_PATH[sdk=macosx*] = $(INSTALL_PATH_ACTUAL)
// Architectures
SDKROOT = macosx.internal
ALWAYS_SEARCH_USER_PATHS = YES
HEADER_SEARCH_PATHS = $(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders $(PROJECT_DIR)
@ -12,18 +12,22 @@ GCC_ENABLE_CPP_EXCEPTIONS = NO
GCC_ENABLE_CPP_RTTI = NO
GCC_ENABLE_OBJC_EXCEPTIONS = NO
GCC_PREPROCESSOR_DEFINITIONS = __DARWIN_NON_CANCELABLE=1
GCC_C_LANGUAGE_STANDARD = gnu99
GCC_C_LANGUAGE_STANDARD = gnu11
GCC_WARN_ABOUT_RETURN_TYPE = YES
GCC_WARN_UNUSED_VARIABLE = YES
//GCC_WARN_64_TO_32_BIT_CONVERSION = YES
//GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES
//GCC_WARN_ABOUT_RETURN_TYPE = YES
OTHER_CFLAGS = -fno-exceptions
OTHER_CFLAGS = -fno-exceptions -Weverything -Wno-reserved-id-macro -Wno-padded -Wno-sign-compare -Wno-used-but-marked-unused -Wno-undef -Wno-cast-qual -Wno-documentation -Wno-unused-macros -Wno-gnu
OTHER_CFLAGS_debug = -O0
CURRENT_PROJECT_VERSION =
CURRENT_PROJECT_VERSION = $(RC_ProjectSourceVersion)
VERSION_INFO_PREFIX = __
VERSIONING_SYSTEM = apple-generic
PREBINDING = NO
LLVM_LTO = YES
NOTIFY_CONFIG = notify.conf.MacOSX
NOTIFY_CONFIG[sdk=iphoneos*] = notify.conf.iPhone
NOTIFY_CONFIG[sdk=tvos*] = notify.conf.iPhone
NOTIFY_CONFIG[sdk=*simulator*] = notify.conf.iOSSimulator

View File

@ -1,19 +1,22 @@
#include "base.xcconfig"
PRODUCT_NAME = libsystem_notify
INSTALL_PATH_ACTUAL = /usr/lib/system
PRIVATE_HEADERS_FOLDER_PATH = $(INSTALL_PATH_PREFIX)/usr/local/include
PUBLIC_HEADERS_FOLDER_PATH = $(INSTALL_PATH_PREFIX)/usr/include
INSTALL_PATH = /usr/lib/system
PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include
PUBLIC_HEADERS_FOLDER_PATH = /usr/include
DYLIB_CURRENT_VERSION = $(CURRENT_PROJECT_VERSION)
EXECUTABLE_PREFIX =
BUILD_VARIANTS = normal
CURRENT_PROJECT_VERSION = $(RC_ProjectSourceVersion)
VERSION_INFO_PREFIX = __
VERSIONING_SYSTEM = apple-generic
GCC_SYMBOLS_PRIVATE_EXTERN = YES
STRIP_STYLE = non-global
SUPPORTS_TEXT_BASED_API = YES
TAPI_VERIFY_MODE = Pedantic
LINK_WITH_STANDARD_LIBRARIES = NO
OTHER_LDFLAGS = -umbrella System -L/usr/lib/system $(LDFLAGS_DYLD) $(LDFLAGS_COMPILER_RT) $(LDFLAGS_SYSCALL) $(LDFLAGS_PLATFORM) $(LDFLAGS_PTHREAD) $(LDFLAGS_MALLOC) $(LDFLAGS_C) $(LDFLAGS_BLOCKS) $(LDFLAGS_DISPATCH) $(LDFLAGS_XPC)
OTHER_LDFLAGS = -umbrella System -L/usr/lib/system $(LDFLAGS_DYLD) $(LDFLAGS_COMPILER_RT) $(LDFLAGS_SYSCALL) $(LDFLAGS_PLATFORM) $(LDFLAGS_PTHREAD) $(LDFLAGS_MALLOC) $(LDFLAGS_C) $(LDFLAGS_BLOCKS) $(LDFLAGS_DISPATCH) $(LDFLAGS_XPC) $(LDFLAGS_DARWIN)
LDFLAGS_DYLD = -ldyld
LDFLAGS_COMPILER_RT = -lcompiler_rt
LDFLAGS_SYSCALL = -lsystem_kernel
@ -24,8 +27,9 @@ LDFLAGS_PTHREAD = -lsystem_pthread
LDFLAGS_PTHREAD[sdk=iphonesimulator*] = -lsystem_sim_pthread
LDFLAGS_MALLOC = -lsystem_malloc
LDFLAGS_C = -lsystem_c
LDFLAGS_C[sdk=iphonesimulator*] = -lsystem_sim_c
LDFLAGS_BLOCKS = -lsystem_blocks
LDFLAGS_BLOCKS[sdk=iphonesimulator*] = -lsystem_sim_blocks
LDFLAGS_DISPATCH = -ldispatch
LDFLAGS_XPC = -lxpc
LDFLAGS_DARWIN = -lsystem_darwin
IS_ZIPPERED=YES

View File

@ -1,5 +1,11 @@
#include "base.xcconfig"
INSTALL_PATH_ACTUAL = /usr/sbin
INSTALL_PATH = /usr/sbin
// Sandbox settings
SANDBOX_PATH = /System/Library/Sandbox/Profiles
SANDBOX_PATH[sdk=iphone*] =
SANDBOX_NAME = com.apple.notifyd
SANDBOX_PROFILE = com.apple.notifyd.sb
OTHER_MIGFLAGS = -DMACH_NOTIFY_SEND_POSSIBLE_EXPECTED=1
OTHER_LDFLAGS = -lCrashReporterClient

View File

@ -1,4 +1,4 @@
#include "base.xcconfig"
INSTALL_PATH_ACTUAL = /usr/bin
INSTALL_PATH = /usr/bin

2
src/libnotify/xcodescripts/no-sim-man.sh Executable file → Normal file
View File

@ -1,5 +1,5 @@
#!/bin/bash -ex
if [[ "${PLATFORM_NAME}" =~ "simulator" ]]; then
rm -rf ${DSTROOT}${INSTALL_PATH_PREFIX}/usr/share/man
rm -rf ${DSTROOT}/usr/share/man
fi

0
src/libnotify/xcodescripts/sim-compat-symlink.sh Executable file → Normal file
View File

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>

View File

@ -0,0 +1,162 @@
//
// xctests.m
// xctests
//
#include <dispatch/dispatch.h>
#include <notify.h>
#include <stdatomic.h>
#include <unistd.h>
#include "notify_internal.h"
#import <XCTest/XCTest.h>
@interface RegisterTests : XCTestCase
@end
@implementation RegisterTests
static dispatch_queue_t noteQueue;
+ (void)setUp
{
noteQueue = dispatch_queue_create("noteQ", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL);
}
+ (void)tearDown
{
noteQueue = nil;
}
- (void)tearDown
{
[super tearDown];
}
- (void)test00RegisterSimple
{
static int token;
XCTAssert(notify_register_dispatch("com.example.test.simple", &token, noteQueue, ^(int i){}) == NOTIFY_STATUS_OK, @"notify_register_dispatch failed");
XCTAssert(notify_cancel(token) == NOTIFY_STATUS_OK, @"notify_cancel failed");
}
- (void)test01RegisterNested
{
for (int i = 0; i < 100000; i++) {
static int token1, token2;
XCTAssert(notify_register_dispatch("com.example.test.multiple", &token1, noteQueue, ^(int i){}) == NOTIFY_STATUS_OK, @"notify_register_dispatch failed");
XCTAssert(notify_register_dispatch("com.example.test.multiple", &token2, noteQueue, ^(int i){}) == NOTIFY_STATUS_OK, @"notify_register_dispatch failed");
XCTAssert(notify_cancel(token1) == NOTIFY_STATUS_OK, @"notify_cancel failed");
XCTAssert(notify_cancel(token2) == NOTIFY_STATUS_OK, @"notify_cancel failed");
}
}
- (void)test02RegisterInterleaved
{
for (int i = 0; i < 100000; i++) {
static int token1, token2;
XCTAssert(notify_register_dispatch("com.example.test.interleaved", &token1, noteQueue, ^(int i){}) == NOTIFY_STATUS_OK, @"notify_register_dispatch failed");
XCTAssert(notify_cancel(token1) == NOTIFY_STATUS_OK, @"notify_cancel failed");
XCTAssert(notify_register_dispatch("com.example.test.interleaved", &token2, noteQueue, ^(int i){}) == NOTIFY_STATUS_OK, @"notify_register_dispatch failed");
XCTAssert(notify_cancel(token2) == NOTIFY_STATUS_OK, @"notify_cancel failed");
}
}
- (void)test03RegisterRaceWithDealloc
{
static int tokens[1000000];
dispatch_apply(1000000, DISPATCH_APPLY_AUTO, ^(size_t i) {
XCTAssert(notify_register_check("com.example.test.race", &tokens[i]) == NOTIFY_STATUS_OK, @"notify_register_check failed");
XCTAssert(notify_cancel(tokens[i]) == NOTIFY_STATUS_OK, @"notify_cancel failed");
XCTAssert(notify_register_dispatch("com.example.test.race", &tokens[i], noteQueue, ^(int i){}) == NOTIFY_STATUS_OK, @"notify_register_dispatch failed");
XCTAssert(notify_cancel(tokens[i]) == NOTIFY_STATUS_OK, @"notify_cancel failed");
XCTAssert(notify_post("com.example.test.race") == NOTIFY_STATUS_OK, @"notify_post failed");
});
}
- (void)test04RegisterManyTokens
{
static int tokens[100000];
dispatch_apply(100000, DISPATCH_APPLY_AUTO, ^(size_t i) {
XCTAssert(notify_register_dispatch("com.example.test.many", &tokens[i], noteQueue, ^(int i){}) == NOTIFY_STATUS_OK, @"notify_register_dispatch failed");
XCTAssert(notify_cancel(tokens[i]) == NOTIFY_STATUS_OK, @"notify_cancel failed");
});
}
- (void)test05RegisterBulkCancel
{
static int tokens[100000];
dispatch_apply(100000, DISPATCH_APPLY_AUTO, ^(size_t i) {
XCTAssert(notify_register_dispatch("com.example.test.bulk", &tokens[i], noteQueue, ^(int i){}) == NOTIFY_STATUS_OK, @"notify_register_dispatch failed");
});
dispatch_apply(100000, DISPATCH_APPLY_AUTO, ^(size_t i) {
XCTAssert(notify_cancel(tokens[i]) == NOTIFY_STATUS_OK, @"notify_cancel failed");
});
}
- (void)test06RegisterSimpleSelf
{
static int token;
XCTAssert(notify_register_dispatch("self.example.test.simple", &token, noteQueue, ^(int i){}) == NOTIFY_STATUS_OK, @"notify_register_dispatch failed");
XCTAssert(notify_cancel(token) == NOTIFY_STATUS_OK, @"notify_cancel failed");
}
- (void)test07RegisterNestedSelf
{
for (int i = 0; i < 100000; i++) {
static int token1, token2;
XCTAssert(notify_register_dispatch("self.example.test.multiple", &token1, noteQueue, ^(int i){}) == NOTIFY_STATUS_OK, @"notify_register_dispatch failed");
XCTAssert(notify_register_dispatch("self.example.test.multiple", &token2, noteQueue, ^(int i){}) == NOTIFY_STATUS_OK, @"notify_register_dispatch failed");
XCTAssert(notify_cancel(token1) == NOTIFY_STATUS_OK, @"notify_cancel failed");
XCTAssert(notify_cancel(token2) == NOTIFY_STATUS_OK, @"notify_cancel failed");
}
}
- (void)test08RegisterInterleavedSelf
{
for (int i = 0; i < 100000; i++) {
static int token1, token2;
XCTAssert(notify_register_dispatch("self.example.test.interleaved", &token1, noteQueue, ^(int i){}) == NOTIFY_STATUS_OK, @"notify_register_dispatch failed");
XCTAssert(notify_cancel(token1) == NOTIFY_STATUS_OK, @"notify_cancel failed");
XCTAssert(notify_register_dispatch("self.example.test.interleaved", &token2, noteQueue, ^(int i){}) == NOTIFY_STATUS_OK, @"notify_register_dispatch failed");
XCTAssert(notify_cancel(token2) == NOTIFY_STATUS_OK, @"notify_cancel failed");
}
}
- (void)test09RegisterRaceWithDeallocSelf
{
static int tokens[1000000];
dispatch_apply(1000000, DISPATCH_APPLY_AUTO, ^(size_t i) {
XCTAssert(notify_register_check("self.example.test.race", &tokens[i]) == NOTIFY_STATUS_OK, @"notify_register_check failed");
XCTAssert(notify_cancel(tokens[i]) == NOTIFY_STATUS_OK, @"notify_cancel failed");
XCTAssert(notify_register_dispatch("self.example.test.race", &tokens[i], noteQueue, ^(int i){}) == NOTIFY_STATUS_OK, @"notify_register_dispatch failed");
XCTAssert(notify_cancel(tokens[i]) == NOTIFY_STATUS_OK, @"notify_cancel failed");
XCTAssert(notify_post("com.example.test.race") == NOTIFY_STATUS_OK, @"notify_post failed");
});
}
- (void)test10RegisterManyTokensSelf
{
static int tokens[100000];
dispatch_apply(100000, DISPATCH_APPLY_AUTO, ^(size_t i) {
XCTAssert(notify_register_dispatch("self.example.test.many", &tokens[i], noteQueue, ^(int i){}) == NOTIFY_STATUS_OK, @"notify_register_dispatch failed");
XCTAssert(notify_cancel(tokens[i]) == NOTIFY_STATUS_OK, @"notify_cancel failed");
});
}
- (void)test11RegisterBulkCancelSelf
{
static int tokens[100000];
dispatch_apply(100000, DISPATCH_APPLY_AUTO, ^(size_t i) {
XCTAssert(notify_register_dispatch("self.example.test.bulk", &tokens[i], noteQueue, ^(int i){}) == NOTIFY_STATUS_OK, @"notify_register_dispatch failed");
});
dispatch_apply(100000, DISPATCH_APPLY_AUTO, ^(size_t i) {
XCTAssert(notify_cancel(tokens[i]) == NOTIFY_STATUS_OK, @"notify_cancel failed");
});
}
@end