3 Replies
      Latest reply on Dec 6, 2019 12:54 AM by eskimo
      johndyalog Level 1 Level 1 (0 points)

        Hello all,

         

        I have a large application written in C that needs to be able to scan the contents of the user's Documents (and other) folder(s). I'm aware that this permision mechanism has changed in Catalina, but I'm totally unable to get it to work.

         

        The underlying symptom is that opendir fails and errno is EPERM.

         

        Note, that I CAN read and write files in ~/Documents, and I'm able to do that without ever having prompted the user.

        Note also, that the bash "find" command, when called via Terminal, CAN scan the directory, AFTER it has prompted the user, (and I guess it uses a similar opendir/readdir mechanism),

         

        I've tried a number of things:

         

        • NSDocumentsFolderUsageDescription
          • I've added the following to Info.plist

                       <key>NSDocumentsFolderUsageDescription</key>

                       <string>application needs Documents access</string>

                to make sure that the bundle is properly notarized.

         

        None of these things allow opendir to succeed (and none them result in a dialog containging "<app> Would like to access files in your Documents folder").

         

        Is there an API I should be calling to provoke the dialog and to grant the requred permissions?

         

        Many Thanks,

        John.

        • Re: How do I ask for permission (from C) to scan a user's Documents Folder on Catalina
          eskimo Apple Staff Apple Staff (12,425 points)

          I have a large application written in C

          I’d like to start by clarifying the above.  It’s not possible to write an macOS app in C.  You will need at least some Objective-C (or Swift) for the outer shell.  So I suspect that either:

          • Your app has a C core with an Objective-C outer shell

          • You’re not talking about a GUI app, but instead using the term “application” in a more general sense

          So, is this a GUI app?  Or something else, like a command-line tool, that’s not a GUI app but is an application in the general sense?


          In terms of GUI apps, there should be nothing to stop you from enumerating the Documents directory using C APIs.  I tried this here in my office today and it worked just fine.  Here’s what I did:

          1. Using Xcode 11.2 on macOS 10.15, I created a new app from the macOS > App template, selecting Objective-C for the language and Storyboard for the user interface.

          2. In the Signing & Capabilities editor, I removed the App Sandbox slice.  I’m presuming that your app is not sandboxed.  If it is, that’s a whole different kettle of fish.

          3. I added an NSDocumentsFolderUsageDescription entry to the Info.plist.

          4. I added the following method to the ViewController class:

            - (IBAction)testAction:(id)sender {
                #pragma unused(sender)
                NSURL * docDirURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:false error:NULL];
                assert(docDirURL != nil);
                DIR * dir = opendir(docDirURL.fileSystemRepresentation);
                do {
                    struct dirent * ent = readdir(dir);
                    if (ent == NULL) {
                        break;
                    }
                    NSLog(@"%s\n", ent->d_name);
                } while (1);
                int err = closedir(dir);
                assert(err == 0);
            }

            .

          5. In the storyboard, I added a button and wired it up to that method.

          6. I ran the app and clicked my button.  The system put up the expected approval alert and, once I approved the access, the app printed a listing of the Documents directory.

          Share and Enjoy

          Quinn “The Eskimo!”
          Apple Developer Relations, Developer Technical Support, Core OS/Hardware
          let myEmail = "eskimo" + "1" + "@apple.com"

            • Re: How do I ask for permission (from C) to scan a user's Documents Folder on Catalina
              johndyalog Level 1 Level 1 (0 points)

              Hello Eskimo,  Thanks for responding.

               

              As you suspected, the configuration is more complicated than I implied in my first post - perhaps I oversimplified.

               

              The "failing" process is a tty application (called "dyalog") that can run in a number of ways, including as an interactive session in a tty/Terminal window, or as a TCPIP server, communicating with a parent GUI Application (called "Dyalog 18.0")

               

              When running interactively inside Termimal, and "dyalog" calls opendir, Terminal pops up with "Teminal eould like to access files in your Documents folder"). I can click "OK" and the call succeeds.

               

              The GUI application (Dyalog 18.0)  is developed using electron and packaged using electron-packager. I've been able to notarize the .pkg using the process described in the link in my first message

               

              When the GUI application ("Dyalog 18.0") is launched it:

                1. starts the TCP server using the “net” module of electron
                2. spawns a "dyalog" process (via a bash shell) using the “child_process” module in electron. The "dyalog" process then connects back to the GUI app via TCP/IP.

               

              So, there is a  deeper process hierarchy: (There's supposed to be an image here, but it appears to have disappered from the post).

               

               

              I've drag-dropped ALL of the processes between "Dyalog 18.0" and "dyalog" (inclusive) to "Full Disk Access" in "Security &  Privacy" but I still can't get opendir to succeed in the "dyalog" process.

               

              There doesn't appear to be a way (as a user) to add Applications to the "Files and Folders" section of "Security & Privacy", (the + button is permanently inactive).

               

              I've added NSDocumentsFolderUsageDescription to the info.plist for "Dyalog 18.0" (is it OK to do that AFTER installation, or does it need to be in the .pkg'd version of info.plist?), and that hasn't helped.

               

               

              Many Thanks.

              John.

                • Re: How do I ask for permission (from C) to scan a user's Documents Folder on Catalina
                  eskimo Apple Staff Apple Staff (12,425 points)

                  Oi vey!

                  There’s two potential gotchas here:

                  • macOS has a complex subsystem to track process responsibility, that is, the user-visible process that’s responsible for various background actions.

                  • There’s also complex logic to determine whether a process is allowed to display UI.

                  It’s likely that something being done by these various Electron modules is confusing one or both of these subsystems.  It’s hard to offer any concrete advice on that topic because I’ve no idea what they’re doing behind the scenes.  My best suggestion is to start with your known broken state and remove complexity until things start working, and then investigate what’s going at that inflexion point.

                  Share and Enjoy

                  Quinn “The Eskimo!”
                  Apple Developer Relations, Developer Technical Support, Core OS/Hardware
                  let myEmail = "eskimo" + "1" + "@apple.com"