MacOS Process not writing files

Hi Apple Developers, I have my question posted already on Stack Overflow, I hope it's okay to just link to my question here:

https://stackoverflow.com/questions/62208878/macos-process-not-writing-files


If not I'll copy the question content here.


Thank you 🙇-1F3FB;♂

Replies

Running a command-line tool from a macOS app can be a bit tricky. First things first, are you planning to deploy via the Mac App Store?

This matters because Mac App Store apps must be sandboxed, so if you ultimately plan to deploy that way then you should start out sandboxed in order to avoid nasty surprises later on. OTOH, if you play to deploy independently, you can simplify your life by not worrying about the sandbox.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Hi @eskimo, when I sandbox the app, I have the "User selected files/folders" permission set, and in my UI I have the user select folders where files will be copied to. I pass those same selected folders into my Rust executable to do the copying and other processing but this gets blocked when sandboxed. Is this a limitation of a sanboxed app that it doesn't check that the parent process' user selected folders are the same ones being modied in a child process (my Rust executable). This is what I assume is the case and is 😔.

Presumably your helper tool is signed with

com.apple.security.inherit
so that it inherits its sandbox from its parent. If so, you’re running into a limitation of sandbox inheritance, namely that it only inherits the static sandbox. To quote the docs:

Note: This property causes the child process to inherit only the static rights defined in the main app’s entitlements file, not any rights added to your sandbox after launch (such as PowerBox access to files).

If you need to provide access to files opened after launch, you must either pass the data to the helper or pass a bookmark to the child process. The bookmark need not be a security-scoped bookmark, but it can be, if desired.

In situations like this I generally have the helper work entirely within my app’s container and then, when it’s done, have the main app move (or copy) the results to where they need to be.

ps If you respond back again, please answer my question about whether you plan to deploy via the Mac App Store or not.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Hi Quinn, I'd like to be able to release it on the Apple Store but if I run into more issues I'll just have to release it independantly for now.


I found the issue, when I ran it as an XPC process, I saw more of the logs from the Rust executable:


Metal API Validation Enabled
thread 'main' panicked at '     failed to create_dir_all in make_date_dir(): 
  Os { code: 30, kind: Other, message: "Read-only file system" }', src/lib.rs:373:5


UPDATE*


Yeah looks like Sandboxing won't work for my app as it read `/Volumes` to see when something new becomes mounted.


Metal API Validation Enabled
thread 'main' panicked at '     failed read_dir() in has_record:
 Os { code: 1, kind: PermissionDenied, message: "Operation not permitted" }', src/lib.rs:239:22


The MacOS library can tell you when a new drive mounts (see https://stackoverflow.com/questions/12409458/detect-when-a-volume-is-mounted-on-os-x ) but in a sandboxed app, my Rust executrable won't be able to read `/Volumes`.