Semaphore issues

I am developing a desktop application on macOS X.
It is ok to use sem_open("name", O_CREAT, 0644, 0) under console application.
But if it is a desktop application, it would result into a SEM_FAILED. And the error is EPERM(Operation not permitted). Is there any way to use semaphore in this situation?
Cannot find any article to explain something about this. The os version is 10.15.7. Thx a lot.

Accepted Reply

But if it is a desktop application, it would result into a
SEM_FAILED. And the error is EPERM (Operation not permitted).

Is your app sandboxed?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"

Replies

But if it is a desktop application, it would result into a
SEM_FAILED. And the error is EPERM (Operation not permitted).

Is your app sandboxed?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"

Is your app sandboxed?

Yes, it is sandboxed.

Yes, it is sandboxed.

There are special rules for sandboxed app. See the IPC and POSIX Semaphores and Shared Memory section of the App Sandbox Design Guide.

Before you go down that path, can you explain what you’re using Posix semaphores for? They’re a rarely used API on our platforms because in most situations there are better alternatives.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
Thanks eskimo,

The semaphore & shared memory issue has been solved.
Could I ask one more related question in this thread? The app is sandboxed in this situation. I use posix_spawn to open another instance of the same application. I get the pid successfully, but i could not find the Window. It works when it is a non-sandboxed app. Find nothing about this in the page IPC and POSIX Semaphores and Shared Memory

Thanks again gracefully.

I get the pid successfully, but i could not find the Window.

“find the Window”? What do you mean by this? What API are you using? And where does it go wrong?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
When then user click button on the window, it would trigger posix_spawn(&pid, argv[0], NULL, NULL, argv, env) to start another process of the same program. In sandbox situation. The triggered window did not show up.

Best Regards
So, to be clear:
  1. You have a sandboxed app that presents a window.

  2. The user clicks a button on that window.

  3. You have code that runs in response to that button that calls posix_spawn to run another copy of the sandboxed app.

  4. That app should present UI but it does not.

Correct?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
Yeeees, totally correct.

Best Regards
Are you sure the second instance of the app is actually running? I suspect it won’t because it’s trying to re-initialise the sandbox.

To elaborate, your main app has entitlements that specify a new sandbox in which it runs. When it launches a child process via posix_spawn (or fork/exec, or NSTask, or whatever) the child process inherits its sandbox. You can explicitly denote that using the com.apple.security.inherit but it happens regardless of whether you have that entitlement set [1]. This inheritance incompatible with the app’s entitlements that set up a new app sandbox. The end result is that the system refuses to start the child process.

As to what you should do about this, that’s a complex question. Running a second instance of your app is, well, kinda weird. Why are you doing that?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"

[1] The entitlement exists for the benefit of App Review. When you submit to the Mac App Store, App Review requires that all executables be sandboxed. However, if you only set the com.apple.security.app-sandbox entitlement then you set up a new sandbox, which is problematic if your goal is to inherit your sandbox. So, you can add the combination of com.apple.security.app-sandbox and com.apple.security.inherit, which signals to App Review that you are sandboxed but still results in an inherited sandbox.
Thanks Eskimo,

I am working on a cross-platform infra project. We try to follow things we have done under linux.

One more details I forget to mention.
When the app is sandboxed, I can do the same thing using fork().




Thanks again.

I can do the same thing using fork.

The system attaches entitlements to a process when it execs, so a simple fork doesn’t trigger this issue. A posix_spawn is (by default) a fork/exec, and it’s the exec that’s causing you problems.

I am working on a cross-platform infra project. We try to follow
things we have done under linux.

macOS and Linux have very different architectures when it comes to GUI process management. For example, macOS works hard to prevent the user from running a second instance of an app, but instead expects a single instance of the app to do all of the app’s work.

So, why do you want to run multiple instances of your app? What’s the higher-level goal here?

My experience is that folks often run into problems like this when they’re working at the wrong level of abstraction. For example, let’s say you’re building an app and you want a helper process to be responsible for the content of one of its windows. Having the helper process display a window directly (using NSWindow) is definitely a mistake on macOS. For example, when the user clicks on the app in the Dock the system brings all of the app’s windows to the front but this won’t include the helper process’s window because it’s not part of the app. And let me stress that this is just an example; there are many other places where things will go wrong.

A better alternative is to have the helper process render to an IOSurface that it shares with the app. The app still owns the window, but the IOSurface allows it to efficiently display content generated by the helper.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Hi eskimo,

The system attaches entitlements to a process when it execs, so a simple fork doesn’t trigger this issue. A posix_spawn is (by default) a fork/exec, and it’s the exec that’s causing you problems.

macOS and Linux have very different architectures when it comes to GUI process management.

Thanks for your explaination. I think this thread could be closed.

Our target is to make the app one-progress-multiple-window. We use flutter, but it does not support this feature currently. So we must find the workaround.

Best Regards

Our target is to make the app one-progress-multiple-window. We use
flutter, but it does not support this feature currently.

Hmmm. You’ve set yourself goal A and then adopted tool B that doesn’t support goal A. Perhaps you should reconsider B.

Alternatively, you should work with your tool vendor to fix this properly. Right now you are ‘fighting the frameworks’, which rarely ends well.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"