NSFileManager & NSFilePosixPermissions
Asked Answered
R

3

7

I want to use the octal permissions (used for chmod) for NSFilePosixPermissions. Here is what I did now:

NSFileManager *manager = [NSFileManager defaultManager];
NSDictionary *attributes;

[attributes setValue:[NSString stringWithFormat:@"%d", 0777] 
             forKey:@"NSFilePosixPermissions"]; // chmod permissions 777
[manager setAttributes:attributes ofItemAtPath:@"/Users/lucky/Desktop/script" error:nil];

I get no error, but when I check the result with "ls -o" the permission are't -rwxrwxrwx.

What's wrong? Thanks for help.

Ruben answered 11/3, 2012 at 13:6 Comment(0)
D
19

First, NSFilePosixPermissions is the name of a constant. Its value may also be the same, but that’s not guaranteed. The value of the NSFilePosixPermissions constant could change between framework releases, e. g. from @"NSFilePosixPermissions" to @"posixPermisions". This would break your code. The right way is to use the constant as NSFilePosixPermissions, not @"NSFilePosixPermissions".

Also, the NSFilePosixPermissions reference says about NSFilePosixPermisions:

The corresponding value is an NSNumber object. Use the shortValue method to retrieve the integer value for the permissions.

The proper way to set POSIX permissions is:

// chmod permissions 777

// Swift
attributes[NSFilePosixPermissions] = 0o777

// Objective-C
[attributes setValue:[NSNumber numberWithShort:0777] 
             forKey:NSFilePosixPermissions];
Despairing answered 11/3, 2012 at 14:32 Comment(8)
Thanks! Only set the NSFilePermissions value don't work I did it so: NSMutableDictionary *attributes = [NSMutableDictionary dictionaryWithDictionary:[manager attributesOfItemAtPath:@"file..." error:nil]];Next step I set the permissions and it worked!Ruben
You can also use literal notation to pass an NSNumber (and NSDictionary): @{NSFilePosixPermissions: @0777}Gliwice
Note that the leading zero here is critical. That tells the C compiler that your constant is in Octal. Octal 0777 is 511 in decimal, not the same number!Hilaria
You say a short. What if the octal I want is 0100640 instead of 0640? That's a perfectly valid octal for C's version of chmod(). However, a C short can only store a number up to 32767 if signed, and 65535 if unsigned. That's not enough to store 0100640.Strother
No, it’s not me who’s saying that. Apple is.. Also, this attribute is about the file permissions. 0100000 isn’t a permission bit, however. It’s part of the mode. The permissions are a subset of the mode only.Despairing
For anyone revisiting this with Swift, a leading 0 is not sufficient to indicate a number is octal, you must lead with 0o. NSFileManager.defaultManager.setAttributes([NSFilePosixPermissions: NSNumber(short: 0o777)], ofItemAtPath: "/tmp/foo")Joule
Added a Swift example. Note that you don’t need to explicitly wrap the value in an NSNumber. Swift-Objective-C bridging will do that automatically.Despairing
Has now been updated to posixPermissions in swift 3 developer.apple.com/reference/foundation/fileattributekey/…Planogamete
P
5

Solution in Swift 3

let fm = FileManager.default

var attributes = [FileAttributeKey : Any]()
attributes[.posixPermissions] = 0o777
do {
    try fm.setAttributes(attributes, ofItemAtPath: path.path)
}catch let error {
    print("Permissions error: ", error)
}
Planogamete answered 19/11, 2016 at 21:17 Comment(0)
H
1

There is now a FilePermissions type that can make this easier.

You can add an extension:

extension FileManager {

  func setUnixPermissions(_ permissions: FilePermissions, atPath: String) throws {
    try FileManager.default.setAttributes(
      [.posixPermissions: permissions.rawValue],
      ofItemAtPath: atPath
    )
  }

}

Example usage:

  let fm = FileManager.default
  let path = "/path/to/something"

  // FilePermissions.
  try fm.setUnixPermissions([.ownerRead, .groupRead], atPath: path)

  // Octal permissions.
  try fm.setUnixPermissions(FilePermissions(rawValue: 0x777), atPath: path)

Haematoid answered 1/3, 2022 at 17:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.