Why is it that I can open a symbolic link, but can't read it? I am aware that I can get the contents of a symlink file using the readlink function, but still, it seems like this ought to work. Here's example code:
#include <iostream>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, const char * argv[])
{
// Make sure there is not already a file where we will create the link
unlink( "/tmp/ReadSymLink-test" );
// Create a symlink
int result = symlink( "../usr", "/tmp/ReadSymLink-test");
int err;
if (result == 0)
{
std::cout << "created file /tmp/ReadSymLink-test\n";
}
else
{
err = errno;
std::cerr << "symlink failed with error " << err << "\n";
return 1;
}
// Open it for reading
int fd = open( "/tmp/ReadSymLink-test", O_RDONLY | O_SYMLINK );
if (fd < 0)
{
err = errno;
std::cerr << "open failed with error " << err << "\n";
return 2;
}
std::cout << "open succeeded\n";
// and read it
char buffer[200];
ssize_t bytesRead = read( fd, buffer, sizeof(buffer) );
if (bytesRead < 0)
{
err = errno;
std::cerr << "read failed with error " << err << "\n";
return 2;
}
else
{
buffer[ bytesRead ] = '\0';
std::cout << "read of symlink result: " << buffer << "\n";
}
return 0;
}
The result, running under Sonoma 14.2 (beta) is
created file /tmp/ReadSymLink-test
open succeeded
read failed with error 1
Files and Storage
RSS for tagAsk questions about file systems and block storage.
Posts under Files and Storage tag
200 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
It seems that whenever I scan the contents of ~/Library/Containers with my app, I get the warning [App] would like to access data from other apps, regardless of how often I have already allowed it. When the warning appears, the last scanned file is ~/Library/Containers/com.apple.CloudPhotosConfiguration/Data.
My sample code:
let openPanel = NSOpenPanel()
openPanel.canChooseDirectories = true
openPanel.runModal()
let url = openPanel.urls[0]
let enumerator = FileManager.default.enumerator(at: url, includingPropertiesForKeys: nil)
while let url = enumerator?.nextObject() as? URL {
print(url.path)
}
Is it expected that one has to allow this warning every time the app is run?
I have a problem with Xcode version 15.0.1:
I have programmed a DocumentPicker in Swift UI to load a document from my own cloud into the app. When I run the app, it works fantastic with the simulator, but it doesn't work with my device. I always get the following error message:
file is not reachable. Ensure file URL is not a directory, symbolic link, or invalid url. As I said, when I run the code in the simulator, it works fine. I am using IOS 17.2
Here is the code.
import SwiftUI
import MobileCoreServices
import Firebase
import FirebaseStorage
import CoreData
import UniformTypeIdentifiers
struct DocumentPickerView: UIViewControllerRepresentable {
@Binding var fileContent : String
@Binding var nameContent : String
@Binding var showqr : Bool
@Binding var documentURL: URL?
@Binding var alert: Bool
// @Binding var webViewURL : URL
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func makeUIViewController(context: Context) -> UIDocumentPickerViewController {
// let picker = UIDocumentPickerViewController(documentTypes: ["public.item"], in: .import)
let types: [UTType] = [UTType.content]
let picker = UIDocumentPickerViewController(forOpeningContentTypes:types)
picker.allowsMultipleSelection = false
picker.delegate = context.coordinator
return picker
}
func updateUIViewController(_ uiViewController: UIDocumentPickerViewController, context: Context) {}
class Coordinator: NSObject, UIDocumentPickerDelegate {
var parent: DocumentPickerView
init(_ parent: DocumentPickerView) {
self.parent = parent
}
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
if let selectedURL = urls.first {
parent.documentURL = selectedURL
parent.uploadToFirebase(selectedURL)
}
}
}
func uploadToFirebase(_ fileURL: URL) {
let storage = Storage.storage()
let storageRef = storage.reference()
let fileRef = storageRef.child(fileURL.lastPathComponent)
// if FileManager.default.fileExists(atPath: fileURL.path){
// print("File Existiert:\(fileURL)")
// } else {
// print("File Existiert nicht")
// }
_ = fileRef.putFile(from: fileURL, metadata: nil){ (metadata, error) in
if let error = error {
print("Fehler beim Hochladen der Datei: \(error.localizedDescription)")
} else {
print("Datei erfolgreich hochgeladen!")
// Rufen Sie die Download-URL für die hochgeladene Datei ab
fileRef.downloadURL { (url, error) in
if let error = error {
alert = true
print("Fehler beim Abrufen der Download-URL: \(error.localizedDescription)")
} else {
if let downloadURL = url {
print("Download-URL: \(downloadURL)")
self.fileContent = "\(downloadURL)"
self.showqr = true
}
}
}
}
}
}
}
I am using UIDocumentPickerViewController for transferring folder in export mode. The transferring of folder is working on selected folders. Now I want to restrict some target folders.
But didPickDocumentsAtURLs is getting called after actual transfer. Any idea how can we restrict it?
hi,i want to create a NSFileProviderExtension , need add file for storage, but, i create a folder, xocde show a error :
[ERROR] List of user interactions is not an array
Hello!
I'm in the process of creating an app for iOS. A part of the app relies on data that is collected as the user uses the app. This data is then stored in a .CSV file for easy storage, retrieval, and a small size even if it grows larger than expected.
The data is really simple and easy to traverse, however it won't be stored on a remote database, and only locally on the user's device. I've read that updating the app doesn't overwrite the data of the current version, but instead places the new version of the app in a new directory entirely while the other, older version is then deleted.
Is it possible to mark certain files to be transferred and not replaced entirely? I'd like to know if it's possible or not before I make the mistake and learn the hard way 😅
Also I'm open to any alternative ways to store such data that people may suggest!
Thanks a lot in advance! Help is much appreciated
Jack
On a real iOS device, I am unable to write data to overwrite a file in my bundle. I am getting an error You don't have permission to save the file "CU_config.js" in folder "2023".
Here is the code that tries to write the file.
func configure() {
let picker = UIDocumentPickerViewController(forOpeningContentTypes: [.javaScript], asCopy: true)
picker.delegate = self
present(picker, animated: true)
}
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
controller.dismiss(animated: true, completion: nil)
urls.forEach { url in
let sourceURL:URL
if(isMatch){
sourceURL = Bundle.main.bundleURL.appendingPathComponent("www/2023/CU_config").appendingPathExtension("js")
}else{
sourceURL = Bundle.main.bundleURL.appendingPathComponent("www/2023/CU_Pit_config").appendingPathExtension("js")
}
let destURL = url
let incoming:Data?
do {
incoming = try Data(contentsOf: destURL)
}catch{
incoming = nil
print("Unable to find file")
let alert = UIAlertController(title: "Error", message: "Unable to find file", preferredStyle: UIAlertController.Style.alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertAction.Style.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
do {
sourceURL.startAccessingSecurityScopedResource()
try incoming!.write(to: sourceURL)
sourceURL.stopAccessingSecurityScopedResource()
}catch{
let alert = UIAlertController(title: "Error", message: "Unable to write file"+error.localizedDescription, preferredStyle: UIAlertController.Style.alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertAction.Style.default, handler: nil))
self.present(alert, animated: true, completion: nil)
print("Unable to write file")
}
webview.reload()
}
}
I tried giving it permission in the info.plist by using "Application supports iTunes file sharing" but that didn't work.
It works perfectly in simulation.
Hello,
I know this is not a good practice but i want to make a test.
I would like to write a file into /System folder on macOS Sonoma.
I have tried to reboot in recovery mode. I have disabled SIP. But i can't write into /System. This folder is mounted as read only.
How can i write into this folder ?
I know there is a kind of checksum mechanism to check if something has been modified in /System folder and i want to see what happens if this checksum does not match.
Thanks
Our updating process is a launchd daemon that will download zipped bundle directories that contain resources to be used for updating.
One of the bundles is an app that has a tool that is executed to perform the updating after all of the bundles have been downloaded.
We are finding that on Sonoma starting in version 14.1 the zip extraction of the bundle containing the executable now is blocked on about 1 in 7 computers when the bundle directory itself is being created.
&lt;redacted&gt;Updater &lt;subsystem&gt; Error during Extract state: Error Domain=&lt;our error domain&gt; Code=2001 "filesystem error: in create_directories: Operation not permitted ["/Library/Caches/&lt;reverse-DNS name&gt;/&lt;redacted&gt;Installer.bundle"]" UserInfo={NSLocalizedDescription=filesystem error: in create_directories: Operation not permitted ["/Library/Caches/&lt;reverse-DNS name&gt;/&lt;redacted&gt;Installer.bundle"]}
We have seen the following error just preceding the above on some of these failures:
&lt;date&gt; Error 0x45c755 184 0 sandboxd: tcc_server_message_request_authorization(kTCCServiceSystemPolicyAppBundles) failed: Error Domain=kTCCErrorDomain Code=2 "missing 'auth_value' in reply message" UserInfo={NSDescription=missing 'auth_value' in reply message}
&lt;date&gt; Error 0x0 184 0 sandboxd: [com.apple.sandbox.reporting:violation] System Policy: &lt;redacted&gt;Updater(1431) deny(1) file-write-create /Library/Caches/&lt;reverse-DNS name&gt;/&lt;redacted&gt;Installer.bundle
Violation: deny(1) file-write-create /Library/Caches/&lt;reverse-DNS name&gt;/&lt;redacted&gt;Installer.bundle
I believe that the kTCCServiceSystemPolicyAppBundles failure occurs because TCC has determined that our Updater does not have permission to modify the Installer.bundle.
Both the Updater and Installer.bundle have been signed by the same Apple Developer certificate (with the same team id).
The Updater has been using this same procedure successfully but starts failing after the update to Sonoma v14.1.
When this failure occurs, the updater has been able to extract the other resource-only bundles (no executables) that precede it.
Computers that have this failure show the updater in the System Settings &gt; Privacy &amp; Security &gt; Full Disk Access list as disabled. The computers that do not see this failure, do not have the updater listed in Full Disk Access.
This has been raised as Feedback #FB13359407
What is the recommended way that an updater is supposed to create a new copy of an application without running into these TCC errors?
Would extracting the app bundle as a directory without the .bundle extension and then renaming the directory to add the .bundle extension be a reasonable approach?
BTW: The above approach does seem to work on Sonoma v 14.1
At what point does an app become subject to kTCCServiceSystemPolicyAppBundles?
Is it is just a directory with a .app or .bundle extension or when a bundle structure exists that a signing check can validate?
Hello,
I don't understand what is /System/Applications/ folder (macOS Sonoma).
It is not an (hard)link to /Applications/.
/Applications/ is not a (hard)link to /System/Applications/
Can anyone explain me what is /System/Applications/ ?
Isn't it redundant to /Applications/ ?
Thanks
I like to find a way to identify network volumes, and whether they're run by certain servers, e.g. specifically whether they're on a Synology NAS.
Reason is that Synology, while apparently supporting the Spotlight-over-SMB API, comes with a lot of bugs, requiring me to work around them when searching on those volumes with the macOS Spotlight API.
I could, of course, ask the user to "configure" each mounted volume in my software, but I'd rather do this automagically, if possible, as it's less prone to user mistakes.
So, my question is: Is there a way to learn a bit more about the server of a mounted network volume? E.g., if I could learn its IP address, I could try to connect to it via http protocol and then maybe get a useful response that identifies it as being from Synology.
Or, alternatively, can I tell which SMB volumes are served by a Mac, so that I can at least assume that those handle Spotlight calls correctly, while I assume anything else is buggy (so far, AFAIK, Synology is the only other SMB server that supports Spotlight search).
I've tried to find some data in the IORegistry, but that doesn't seem to store anything about network vols. The statfs function doesn't seem to give me anything for that either, nor do the various fcntl calls as far as I could tell.
I also checked with the DA apis, e.g.:
DASessionRef daSession = DASessionCreate (NULL);
CFURLRef furl = CFURLCreateWithFileSystemPath(NULL, CFSTR("/Volumes/TheNAS"), kCFURLPOSIXPathStyle, true);
DADiskRef daDisk = DADiskCreateFromVolumePath (NULL, daSession, furl);
if (daDisk) {
CFDictionaryRef daInfo = DADiskCopyDescription (daDisk);
NSLog(@"%@", daInfo);
}
However, this only prints basic information:
DAVolumeKind = smbfs;
DAVolumeMountable = 1;
DAVolumeName = TheNAS;
DAVolumeNetwork = 1;
DAVolumePath = "file:///Volumes/TheNAS/";
Where, then, does Finder's "Get Info" get the smb path from, for example?
Hi,
I have created an macOS uninstaller application to delete folder /Library/Containers/{YourApplicationFolder} everything inside the folder gets deleted only the .com.apple.containermanagerd.metadata.plist is not getting deleted.
please give a solution for this.
I want to import a csv-file to my app. It works when I use the Simulator but when I try to import the same file on my iPad, the follwowing message occurs:
UserInfo={NSFilePath=/private/var/mobile/Containers/Shared/AppGroup/4C49BACA-5490-45A4-A8DF-6D47711CFC34/File Provider Storage/LUSD 3.csv, NSUnderlyingError=0x2812068e0 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}}. Where do I find the right settings to enable the import of this csv-file?
I'm using the filecopy function to copy many files and I noticed that it always takes longer than similar tools like cp or a Finder copy (I already did a comparison in my other post). What I didn't know before was that I can set the block size which apparently can have a big influence on how fast the file copy operation is.
The question now is: what should I consider before manually setting the block size? Does it make sense to have a block size that is not a power of 2? Can certain block sizes cause an error, such as a value that is too large (for the Mac the code is running on, or for the source and target devices)? When should or shouldn't I deviate from the default? Is there a way to find out the optimal block size for given source and target devices, or at least one that performs better than the default?
In the following sample code I tried to measure the average time for varying block sizes, but I'm not sure it's the best way to measure it, since each loop iteration can have wildly different durations.
class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ aNotification: Notification) {
let openPanel = NSOpenPanel()
openPanel.runModal()
let source = openPanel.urls[0]
openPanel.canChooseDirectories = true
openPanel.canChooseFiles = false
openPanel.runModal()
let destination = openPanel.urls[0].appendingPathComponent(source.lastPathComponent)
let date = Date()
let count = 10
for _ in 0..<count {
try? FileManager.default.removeItem(at: destination)
do {
try copy(source: source, destination: destination)
} catch {
preconditionFailure(error.localizedDescription)
}
}
print(-date.timeIntervalSinceNow / Double(count))
}
func copy(source: URL, destination: URL) throws {
try source.withUnsafeFileSystemRepresentation { sourcePath in
try destination.withUnsafeFileSystemRepresentation { destinationPath in
let state = copyfile_state_alloc()
defer {
copyfile_state_free(state)
}
// var bsize = Int32(16_777_216)
var bsize = Int32(1_048_576)
if copyfile_state_set(state, UInt32(COPYFILE_STATE_BSIZE), &bsize) != 0 || copyfile_state_set(state, UInt32(COPYFILE_STATE_STATUS_CB), unsafeBitCast(copyfileCallback, to: UnsafeRawPointer.self)) != 0 || copyfile_state_set(state, UInt32(COPYFILE_STATE_STATUS_CTX), unsafeBitCast(self, to: UnsafeRawPointer.self)) != 0 || copyfile(sourcePath, destinationPath, state, copyfile_flags_t(COPYFILE_ALL | COPYFILE_NOFOLLOW | COPYFILE_EXCL)) != 0 {
throw NSError(domain: NSPOSIXErrorDomain, code: Int(errno))
}
}
}
}
private let copyfileCallback: copyfile_callback_t = { what, stage, state, src, dst, ctx in
if what == COPYFILE_COPY_DATA {
if stage == COPYFILE_ERR {
return COPYFILE_QUIT
}
var size: off_t = 0
copyfile_state_get(state, UInt32(COPYFILE_STATE_COPIED), &size)
let appDelegate = unsafeBitCast(ctx, to: AppDelegate.self)
if !appDelegate.setCopyFileProgress(Int64(size)) {
return COPYFILE_QUIT
}
}
return COPYFILE_CONTINUE
}
private func setCopyFileProgress(_ progress: Int64) -> Bool {
return true
}
}
In my Iphone app, I want to open json files that I have earlier saved. The function I mention below to open the file is not firing when I share a file to my app.
I have implemented this in the info.plist file and this seems to work, because in Files I can share a .json file to may app.
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeName</key>
<string>JSON Document</string>
<key>LSHandlerRank</key>
<string>Alternate</string>
<key>LSItemContentTypes</key>
<array>
<string>public.json</string>
</array>
</dict>
</array>
I have added the function to open the file in my AppDelegate file.
func application(_ application: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
// Handle the file at the given URL
// You can perform actions based on the file type or content
print("Opening file!")
}
(the implementation is actually longer to work on the file).
When I share a file to my app, the app itself is opening but this method 'application' is never called.
I'm not sure whether I'm overlooking something. I have searched quite a while to see what I'm missing.
Any help is greatly appreciated!
Emile
Hello,
Anyone know of relevant documentation that captures the difference between
vfsStruct.f_fsid and fstat.st_ino ?
sys/stat.h declares:
ino_t st_ino; /* [XSI] File serial number */
AND
sys/statvfs.h declares:
unsigned long f_fsid; /* Filesystem ID */
Based on some tests, it seems that the st_ino is the number/inode_number that the filesystem identifies the file-resource by ? I observed that this number gets a unique value when I copy a file even when the Finder/FS utilizes the Space-Saver feature of MacOS. This value is identical to the results returned by the command ls "-i" . When copying via Finder, I am seeing distinct st_ino values for source and destination files.
f_fsid seems to be identifying the File differently though, perhaps taking into account what Data/attributes objects the file resource points to ? I observed that this number gets an identical value when I copy a file even when the Finder/FS utilizes the Space-Saver feature of MacOS. So, the value of f_fsid seems to be copied over to the destination file record. Also, I could not find a way to display f_fsid via the ls command.
On a related note, Any documentation regarding MacOS Finder/FS's Space-Saver feature or how it is implemented ?
Thanks,
Vikram.S.Warraich
I have a need to optimize reading strategy, based on if the file is on hard disk or SSD. Does macOS provide any low-level API so that I can query such information?
I learned that I can't have a file inside the bundle if I want it to be able to be changed while the app is running. If I have a file stored outside, how could I let an HTML website access that JS file? I'm using WKWebView to run a local website. The JS would need to be accessible by the website before it loads, because it is a configuration file that is needed on load.
Hi!
I've got an application that can handle json (export/import).
To achieve that I created a new Document Type in the info.plist, filed the imported and exported Type Identifiers, and created a new UTType.
At first I was trying on the simulator and everything worked fine. I was able to created files and store them in the File app, and then read them back. I also implemented the func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) to handle documents opened from outside the application.
Now when I moved on onto a real device, I noticed that I had to test the access with
guard url.startAccessingSecurityScopedResource() else {
throw ImportError.accessDenied
}
defer { url.stopAccessingSecurityScopedResource() }
but I get a weird behavior : when opening a file from File app with my app launched, everything works fine.
But if I try to launch my application (previously killed) from a file in the File app, startAccessingSecurityScopedResource always returns false
I tried to add the NSFileCoordinator().coordinate(readingItemAt: url, error: &error) { (url) in but I get the same behavior.
I guess my files and UTType are correctly declared as I only see them from inside the `UIDocumentPickerViewController``
and from the File app, I see my application in the share sheet
What am I missing here ?
Thanks
Hey all,
I'm using .NET MAUI's FilePicker to open a custom binary (assume a MIME type of application/octet-stream, with a .bin extension). FilePicker.Default.PickAsync works fine on all platforms (in my case, Windows, Android, MacCatalyst and iOS). I subsequently create a FileStream with the returned path (with FileMode.Open, FileAccess.Read). This works fine on Windows, Android, and MacCatalyst, but fails on iOS (for my Mac setup, I'm running VS Code on my MacBook and debugging my app on my iPhone 14 Pro attached via USB). On iOS, I wind up with an UnauthorizedAccessException whenever I try and create said FileStream object with the path to the binary file.
Now, if I select a known filetype (say, an XML file) with FilePicker, then the FileStream object gets created successfully on all platforms. Obviously my binary is an unknown type, and I came to understand that, on iOS, I have to explicitly identify unknown file types in Platforms/iOS/Info.plist in order to open them. So I did that as follows:
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeName</key>
<string>CustomBinary</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSHandlerRank</key>
<string>Owner</string>
<key>LSItemContentTypes</key>
<array>
<string>com.mycompanyname.myappname.bin</string>
</array>
</dict>
</array>
<key>UTImportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeDescription</key>
<string>CustomBinary</string>
<key>UTTypeIconFiles</key>
<array/>
<key>UTTypeIdentifier</key>
<string>com.mycompanyname.myappname.bin</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>bin</string>
<string>BIN</string>
</array>
<key>public.mime-type</key>
<array>
<string>application/octet-stream</string>
</array>
</dict>
</dict>
</array>
Unfortunately, I still get the same exception. I've been spinning my wheels for several days now, and so just wanted to reach out to see if anyone with more iOS insight than I had an idea of how to solve this problem. The binary file itself is on my iPhone itself (i.e., it's in "Files->On My Phone"). Any help is appreciated!
Wes