Reputation: 7343
I am trying to write some data (the length of the data is 367 bytes) in the header of a file using the following code:
const char *attrName = [kAttributeForKey UTF8String];
const char *path = [filePath fileSystemRepresentation];
const uint8_t *myDataBytes = (const uint8_t*)[myData bytes];
int result = setxattr(path, attrName, myDataBytes, sizeof(myDataBytes), 0, 0);
When I try to read it, the result is different:
const char *attrName = [kAttributeForKey UTF8String];
const char *path = [filePath fileSystemRepresentation];
int bufferLength = getxattr(path, attrName, NULL, 0, 0, 0);
char *buffer = malloc(bufferLength);
getxattr(path, attrName, buffer, bufferLength, 0, 0);
NSData *myData = [[NSData alloc] initWithBytes:buffer length:bufferLength];
free(buffer);
Could someone tell me how can I make this work? Thanks in advance.
Upvotes: 0
Views: 3412
Reputation: 2165
Here's a convenient NSFileManager category that gets and sets an NSString as a file's extended attribute.
+ (NSString *)xattrStringValueForKey:(NSString *)key atURL:(NSURL *)URL
{
NSString *value = nil;
const char *keyName = key.UTF8String;
const char *filePath = URL.fileSystemRepresentation;
ssize_t bufferSize = getxattr(filePath, keyName, NULL, 0, 0, 0);
if (bufferSize != -1) {
char *buffer = malloc(bufferSize+1);
if (buffer) {
getxattr(filePath, keyName, buffer, bufferSize, 0, 0);
buffer[bufferSize] = '\0';
value = [NSString stringWithUTF8String:buffer];
free(buffer);
}
}
return value;
}
+ (BOOL)setXAttrStringValue:(NSString *)value forKey:(NSString *)key atURL:(NSURL *)URL
{
int failed = setxattr(URL.fileSystemRepresentation, key.UTF8String, value.UTF8String, value.length, 0, 0);
return (failed == 0);
}
Upvotes: 5
Reputation: 318804
The problem is with your call to setxattr
. The sizeof
call can't be used. You want:
int result = setxattr(path, attrName, myDataBytes, [myData length], 0, 0);
The call to sizeof(myDataBytes)
will return the size of the pointer, not the length of the data.
Upvotes: 3
Reputation: 1645
Read the section "Getting and Setting attributes" here.
For your example here is some basic approach, maybe it'll help:
NSFileManager *fm = [NSFileManager defaultManager];
NSURL *path;
/*
* You can set the following attributes: NSFileBusy, NSFileCreationDate,
NSFileExtensionHidden, NSFileGroupOwnerAccountID, NSFileGroupOwnerAccountName,
NSFileHFSCreatorCode, NSFileHFSTypeCode, NSFileImmutable, NSFileModificationDate,
NSFileOwnerAccountID, NSFileOwnerAccountName, NSFilePosixPermissions
*/
[fm setAttributes:@{ NSFileOwnerAccountName : @"name" } ofItemAtPath:path error:nil];
Upvotes: 0