Inter-process communication

RSS for tag

Share data through Handoff, support universal links to your app's content, and display activity-based services to the user using inter-process communication.

Posts under Inter-process communication tag

85 Posts

Post

Replies

Boosts

Views

Activity

Unable to use "launchctl asuser" in a fast user switching loginwindow
Background Alright, so there's a lot of voodoo and undocumented stuff going on here but hopefully somebody can help me out. I've reverse engineered how stuff might work based on: https://opensource.apple.com/source/launchd/launchd-442.21/support/launchctl.c.auto.html https://developer.apple.com/library/archive/technotes/tn2083/_index.html#//apple_ref/doc/uid/DTS10003794-CH1-SUBSECTION10 I've got a launchdaemon running that spawns another process in the /dev/console bootstrap context in order to act as a remote desktop server. What I'm trying to accomplish here, is to run one of my processes as root in the current gui bootstrap context which is attached to the console. There are several guesswork states in MacOS (11.6, M1) that I've discovered. When you boot a machine, the loginwindow process is run in the bootstrap context of 88 (_windowserver). This makes sense because this process is created by WindowServer. The current console UID is discoverable by running: echo "show State:/Users/ConsoleUser" | scutil You can also introspect loginwindow using launchctl procinfo and friends. Note that, this is before any login has ever happened on the machine. In this state I can do anything in the gui bootstrap context by running this from the launchdaemon: launchctl asuser 88 myprogram In my case, I'm taking a screenshot using AppKit/CoreGraphics and checking some permissions. Once a user logs in, that loginwindow gets blessed by the OS and ownership is transferred to the logged in user. If you lock the machine, you're still in the same bootstrap context and everything works as expected. You can also log out and log into another user and everything works as I expect it to in terms of who controls loginwindow. However, as soon as you hit the "Switch user" button from the lock screen the following happens: A new loginwindow is spawned with the bootstrap context of root (UID of 0) launchctl asuser 0 myprog seems not to properly execute within the bootstrap context of root. My guess is that: 1 is a bug(?), the fast user switching bootstrap context should probably run as 88 rather than 0. A "fix" is running pkill loginwindow which nukes all gui sessions and restarts one loginwindow running in the bootstrap context of 88. This is of course not an acceptable solution. Doing the same thing using launchctl bootstrap gui/0 doesn't work either. I understand that the concept of "bootstrap gui/0" and "asuser 0" sounds nonsensical and it probably is. I'm just trying to find a working solution here. Is there a more proper way of being able run as root in the bootstrap context of a logged in/not yet logged in loginwindow? In case anyone is curious, I'm porting this to MacOS: https://fleetdeck.io
4
0
3.0k
Oct ’21
Why is applicationDidFinishLaunching not called when using an ssh connection to the MacOS machine
Hello, We created a sample app delegate to test whether applicationDidFinishLaunching runs as expected or not (code as follows). The observed behavior was that the executable prints both applicationWillFinishLaunching and applicationDidFinishLaunching in the case when we're using an RDP connection to the mac prints only applicationWillFinishLaunching in case of ssh connection to the mac Why is this behavior different and how can I ensure it runs correctly with ssh? Kindly help. #include <unistd.h> #include <sys/types.h> #include <Foundation/Foundation.h> #import <Cocoa/Cocoa.h> #import <SystemConfiguration/SystemConfiguration.h> #import <SystemConfiguration/SCDynamicStore.h> @interface TWAppKitAppDelegate : NSObject <NSApplicationDelegate> @end @implementation TWAppKitAppDelegate // Launching Applications - (void) applicationWillFinishLaunching: (NSNotification *) pNotification { NSLog(@"applicationWillFinishLaunching"); } - (void) applicationDidFinishLaunching: (NSNotification *) pNotification { NSLog(@"applicationDidFinishLaunching"); } // Managing Active Status - (void) applicationWillBecomeActive: (NSNotification *) pNotification { } - (void) applicationDidBecomeActive: (NSNotification *) pNotification { } - (void) applicationWillResignActive: (NSNotification *) pNotification { } - (void) applicationDidResignActive: (NSNotification *) pNotification { } // Terminating Applications #if 0 - (NSApplicationTerminateReply) applicationShouldTerminate:(NSNotification *) pNotification { return NSApplicationTerminateReply::NSTerminateNow; } #endif - (BOOL) applicationShouldTerminateAfterLastWindowClosed:(NSNotification *) pNotification { return NO; } - (void) applicationWillTerminate:(NSNotification *) pNotification { } - (BOOL) application:(NSApplication *) pSender openFile: (NSString *) pFileName { return YES; } - (void) application:(NSApplication *) pSender openFiles: (NSArray<NSString *> *) pFileNames { } @end int main (int pArgc, char ** pArgv) { NSApplication * app; TWAppKitAppDelegate * appdelegate; app = [NSApplication sharedApplication]; appdelegate = [[TWAppKitAppDelegate alloc] init]; [app setDelegate:appdelegate]; [NSApp run]; //NOTE: Apple never 'returns' from here NSLog(@"Function main called \n"); return 0; }
1
0
1.5k
Oct ’21
Shared-memory pthread condition variable not working
I’m trying to implement a simple cross-process notify/observe system, using a pthread mutex and condition variable in shared (mapped) memory. It seems to be working fine (on macOS 11.6) if one process calls pthread_cond_wait and then another calls pthread_cond_broadcast — the waiting process indeed wakes up. However, if two processes try to observe at the same time, the second one's call to pthread_cond_wait fails with EINVAL. I’m wondering if I’m just doing something wrong in my setup, or if this sort of usage isn’t supported. Basically I create and mmap a file, initialize a pthread mutex and condition in the mapped memory using the setpshared attributes, then lock the mutex and notify or wait on the condition. Actual source code here: Here’s the code that does the pthreads stuff Here’s the outer code that opens and mmaps the file I’m aware that there are a few dozen 🙄 Apple IPC APIs that are probably preferred over these POSIX ones. I’ve used some in the past. I’m doing it this way because: (a) this is in a cross-platform project and it would be nice to share code between Unix platforms, at least Darwin and Linux; (b) the thing I’m notifying/observing about is a database file, so tying the notifications to a side file next to the database provides ideal scoping; (c) it’s similar in principle to the usage of shared memory for locking in SQLite and LMDB. (The difference is, I’m doing notification not locking.) Any advice? —Jens
1
1
1.4k
Oct ’21
Setting shared memory in Catalina
I have written C software that makes extensive use of shared memory (200MB using shmget, etc.), which compiled and ran on Mojave and Linux. Using this shared memory required /etc/sysctl.conf to increase the buffer sizes during OSX boot. It appears that Catalina no longer uses my /etc/sysctl.conf file, whether SIP is enabled or disabled. Now the software compiles but fails to run, because the default shared memory size (4MB) is too small on Catalina. How do I specify the shared memory parameters to increase above the default in Catalina? kern.sysv.shmmax=268435456 kern.sysv.shmmin=1 #kern.sysv.shmmni=128 kern.sysv.shmseg=32 kern.sysv.shmall=65536
4
0
5.3k
Oct ’21
swift Process() return values
How do I access a returned value from a Process(), in this case 'which'... var sips_path : String? //MARK: locate sips on local machine let which_sips = Process() which_sips.executableURL = URL(fileURLWithPath: "which") which_sips.arguments = ["sips"] do { sips_path = try which_sips.run() } catch let error as NSError { sips_path = "/usr/bin/sips"; print("Failed to execute which_sips", error) }line 8. gets compiler error "Cannot assign value of type '()' to type 'String?'" I believe, but cannot prove, 'which' returns a string. .run() throws and throws are for errors only, right? So where is the result of calling which?It seems I should use a closure to use $0 but it's already in one...line 9. intends to assign a default path.
13
1
8.1k
Oct ’21
Unable to use "launchctl asuser" in a fast user switching loginwindow
Background Alright, so there's a lot of voodoo and undocumented stuff going on here but hopefully somebody can help me out. I've reverse engineered how stuff might work based on: https://opensource.apple.com/source/launchd/launchd-442.21/support/launchctl.c.auto.html https://developer.apple.com/library/archive/technotes/tn2083/_index.html#//apple_ref/doc/uid/DTS10003794-CH1-SUBSECTION10 I've got a launchdaemon running that spawns another process in the /dev/console bootstrap context in order to act as a remote desktop server. What I'm trying to accomplish here, is to run one of my processes as root in the current gui bootstrap context which is attached to the console. There are several guesswork states in MacOS (11.6, M1) that I've discovered. When you boot a machine, the loginwindow process is run in the bootstrap context of 88 (_windowserver). This makes sense because this process is created by WindowServer. The current console UID is discoverable by running: echo "show State:/Users/ConsoleUser" | scutil You can also introspect loginwindow using launchctl procinfo and friends. Note that, this is before any login has ever happened on the machine. In this state I can do anything in the gui bootstrap context by running this from the launchdaemon: launchctl asuser 88 myprogram In my case, I'm taking a screenshot using AppKit/CoreGraphics and checking some permissions. Once a user logs in, that loginwindow gets blessed by the OS and ownership is transferred to the logged in user. If you lock the machine, you're still in the same bootstrap context and everything works as expected. You can also log out and log into another user and everything works as I expect it to in terms of who controls loginwindow. However, as soon as you hit the "Switch user" button from the lock screen the following happens: A new loginwindow is spawned with the bootstrap context of root (UID of 0) launchctl asuser 0 myprog seems not to properly execute within the bootstrap context of root. My guess is that: 1 is a bug(?), the fast user switching bootstrap context should probably run as 88 rather than 0. A "fix" is running pkill loginwindow which nukes all gui sessions and restarts one loginwindow running in the bootstrap context of 88. This is of course not an acceptable solution. Doing the same thing using launchctl bootstrap gui/0 doesn't work either. I understand that the concept of "bootstrap gui/0" and "asuser 0" sounds nonsensical and it probably is. I'm just trying to find a working solution here. Is there a more proper way of being able run as root in the bootstrap context of a logged in/not yet logged in loginwindow? In case anyone is curious, I'm porting this to MacOS: https://fleetdeck.io
Replies
4
Boosts
0
Views
3.0k
Activity
Oct ’21
Why is applicationDidFinishLaunching not called when using an ssh connection to the MacOS machine
Hello, We created a sample app delegate to test whether applicationDidFinishLaunching runs as expected or not (code as follows). The observed behavior was that the executable prints both applicationWillFinishLaunching and applicationDidFinishLaunching in the case when we're using an RDP connection to the mac prints only applicationWillFinishLaunching in case of ssh connection to the mac Why is this behavior different and how can I ensure it runs correctly with ssh? Kindly help. #include <unistd.h> #include <sys/types.h> #include <Foundation/Foundation.h> #import <Cocoa/Cocoa.h> #import <SystemConfiguration/SystemConfiguration.h> #import <SystemConfiguration/SCDynamicStore.h> @interface TWAppKitAppDelegate : NSObject <NSApplicationDelegate> @end @implementation TWAppKitAppDelegate // Launching Applications - (void) applicationWillFinishLaunching: (NSNotification *) pNotification { NSLog(@"applicationWillFinishLaunching"); } - (void) applicationDidFinishLaunching: (NSNotification *) pNotification { NSLog(@"applicationDidFinishLaunching"); } // Managing Active Status - (void) applicationWillBecomeActive: (NSNotification *) pNotification { } - (void) applicationDidBecomeActive: (NSNotification *) pNotification { } - (void) applicationWillResignActive: (NSNotification *) pNotification { } - (void) applicationDidResignActive: (NSNotification *) pNotification { } // Terminating Applications #if 0 - (NSApplicationTerminateReply) applicationShouldTerminate:(NSNotification *) pNotification { return NSApplicationTerminateReply::NSTerminateNow; } #endif - (BOOL) applicationShouldTerminateAfterLastWindowClosed:(NSNotification *) pNotification { return NO; } - (void) applicationWillTerminate:(NSNotification *) pNotification { } - (BOOL) application:(NSApplication *) pSender openFile: (NSString *) pFileName { return YES; } - (void) application:(NSApplication *) pSender openFiles: (NSArray<NSString *> *) pFileNames { } @end int main (int pArgc, char ** pArgv) { NSApplication * app; TWAppKitAppDelegate * appdelegate; app = [NSApplication sharedApplication]; appdelegate = [[TWAppKitAppDelegate alloc] init]; [app setDelegate:appdelegate]; [NSApp run]; //NOTE: Apple never 'returns' from here NSLog(@"Function main called \n"); return 0; }
Replies
1
Boosts
0
Views
1.5k
Activity
Oct ’21
Shared-memory pthread condition variable not working
I’m trying to implement a simple cross-process notify/observe system, using a pthread mutex and condition variable in shared (mapped) memory. It seems to be working fine (on macOS 11.6) if one process calls pthread_cond_wait and then another calls pthread_cond_broadcast — the waiting process indeed wakes up. However, if two processes try to observe at the same time, the second one's call to pthread_cond_wait fails with EINVAL. I’m wondering if I’m just doing something wrong in my setup, or if this sort of usage isn’t supported. Basically I create and mmap a file, initialize a pthread mutex and condition in the mapped memory using the setpshared attributes, then lock the mutex and notify or wait on the condition. Actual source code here: Here’s the code that does the pthreads stuff Here’s the outer code that opens and mmaps the file I’m aware that there are a few dozen 🙄 Apple IPC APIs that are probably preferred over these POSIX ones. I’ve used some in the past. I’m doing it this way because: (a) this is in a cross-platform project and it would be nice to share code between Unix platforms, at least Darwin and Linux; (b) the thing I’m notifying/observing about is a database file, so tying the notifications to a side file next to the database provides ideal scoping; (c) it’s similar in principle to the usage of shared memory for locking in SQLite and LMDB. (The difference is, I’m doing notification not locking.) Any advice? —Jens
Replies
1
Boosts
1
Views
1.4k
Activity
Oct ’21
Setting shared memory in Catalina
I have written C software that makes extensive use of shared memory (200MB using shmget, etc.), which compiled and ran on Mojave and Linux. Using this shared memory required /etc/sysctl.conf to increase the buffer sizes during OSX boot. It appears that Catalina no longer uses my /etc/sysctl.conf file, whether SIP is enabled or disabled. Now the software compiles but fails to run, because the default shared memory size (4MB) is too small on Catalina. How do I specify the shared memory parameters to increase above the default in Catalina? kern.sysv.shmmax=268435456 kern.sysv.shmmin=1 #kern.sysv.shmmni=128 kern.sysv.shmseg=32 kern.sysv.shmall=65536
Replies
4
Boosts
0
Views
5.3k
Activity
Oct ’21
swift Process() return values
How do I access a returned value from a Process(), in this case 'which'... var sips_path : String? //MARK: locate sips on local machine let which_sips = Process() which_sips.executableURL = URL(fileURLWithPath: "which") which_sips.arguments = ["sips"] do { sips_path = try which_sips.run() } catch let error as NSError { sips_path = "/usr/bin/sips"; print("Failed to execute which_sips", error) }line 8. gets compiler error "Cannot assign value of type '()' to type 'String?'" I believe, but cannot prove, 'which' returns a string. .run() throws and throws are for errors only, right? So where is the result of calling which?It seems I should use a closure to use $0 but it's already in one...line 9. intends to assign a default path.
Replies
13
Boosts
1
Views
8.1k
Activity
Oct ’21