mirror of
https://github.com/ksherlock/mpw.git
synced 2024-11-22 15:31:50 +00:00
better create support for resource fork files.
This commit is contained in:
parent
9d16456b80
commit
93bb259471
@ -366,8 +366,37 @@ namespace native {
|
||||
// todo -- verify behavior on non-hfs volume.
|
||||
//if ((oflag & O_ACCMODE) & O_WRONLY) oflag |= O_CREAT;
|
||||
|
||||
// under apfs, resource fork needs to be specifically created.
|
||||
// (if 0-length, it doesn't actually exist...)
|
||||
|
||||
// apfs -- zero-length resource fork
|
||||
|
||||
int parent;
|
||||
if (oflag & O_CREAT) {
|
||||
int excl = oflag & O_EXCL;
|
||||
parent = open(path_name.c_str(), O_RDONLY | O_CREAT | excl, 0666);
|
||||
} else {
|
||||
parent = open(path_name.c_str(), O_RDONLY);
|
||||
}
|
||||
|
||||
if (parent < 0) return macos_error_from_errno();
|
||||
close(parent);
|
||||
|
||||
oflag &= ~(O_CREAT | O_EXCL);
|
||||
int mode = oflag & O_ACCMODE;
|
||||
if (mode == O_WRONLY || mode == O_RDWR) oflag |= O_CREAT;
|
||||
|
||||
int fd = open(rname.c_str(), oflag, 0666);
|
||||
if (fd < 0) return macos_error_from_errno();
|
||||
if (fd < 0) {
|
||||
auto e = macos_error_from_errno();
|
||||
|
||||
if (errno == ENOENT && mode == O_RDONLY) {
|
||||
auto tmp = new empty_file(path_name);
|
||||
tmp->resource = true;
|
||||
return file_ptr(tmp);
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
auto tmp = new fd_file(path_name, fd);
|
||||
tmp->resource = true;
|
||||
|
@ -47,7 +47,7 @@ namespace {
|
||||
|
||||
class xattr_file final : public file {
|
||||
public:
|
||||
xattr_file(int fd): _fd(fd);
|
||||
xattr_file(const std::string &path, int fd, bool readonly): file(path), _fd(fd), _readonly(readonly);
|
||||
~xattr_file();
|
||||
|
||||
|
||||
@ -65,7 +65,7 @@ namespace {
|
||||
|
||||
int _fd = -1;
|
||||
off_t _displacement = 0;
|
||||
|
||||
bool _readonly = false;
|
||||
};
|
||||
|
||||
xattr_file::~xattr_file() {
|
||||
@ -101,6 +101,8 @@ namespace {
|
||||
|
||||
|
||||
tool_return<size_t> xattr_file::write(const void *in_buffer, size_t count) {
|
||||
if (_readonly) return MacOS::wrPermErr;
|
||||
|
||||
std::vector<uint8_t> buffer;
|
||||
ssize_t size;
|
||||
size = read_rfork(buffer);
|
||||
@ -140,6 +142,8 @@ namespace {
|
||||
|
||||
tool_return<void> xattr_file::set_eof(ssize_t new_eof) {
|
||||
|
||||
if (_readonly) return MacOS::wrPermErr;
|
||||
|
||||
if (new_eof < 0) return paramErr;
|
||||
|
||||
std::vector<uint8_t> buffer;
|
||||
@ -159,11 +163,26 @@ namespace {
|
||||
|
||||
namespace native {
|
||||
|
||||
tool_return<file_ptr> open_resource_fork(const std::string &path_name, int oflag) {
|
||||
tool_return<file_ptr> open_resource_fork(const std::string &path_name, int oflag) {
|
||||
|
||||
int fd = open(rname.c_str(), oflag);
|
||||
if (fd < 0) return macos_error_from_errno();
|
||||
return std::make_shared<file>(fd);
|
||||
/* under HFS, every file has a resource fork.
|
||||
* Therefore, create it if opening for O_RDWR or O_WRONLY
|
||||
*/
|
||||
|
||||
int parent;
|
||||
if (oflag & O_CREAT) {
|
||||
int excl = oflag & O_EXCL;
|
||||
parent = open(path_name.c_str(), O_RDONLY | O_CREAT | excl, 0666);
|
||||
} else {
|
||||
parent = open(path_name.c_str(), O_RDONLY);
|
||||
}
|
||||
if (parent < 0) return macos_error_from_errno();
|
||||
|
||||
int mode = oflag & O_ACCMODE;
|
||||
|
||||
auto tmp = new xattr_file(path_name, parent, oflags == O_RDONLY);
|
||||
tmp->resource = true;
|
||||
return file_ptr(tmp);
|
||||
}
|
||||
|
||||
|
||||
|
@ -206,14 +206,35 @@ namespace native {
|
||||
/* under HFS, every file has a resource fork.
|
||||
* Therefore, create it if opening for O_RDWR or O_WRONLY
|
||||
*/
|
||||
|
||||
int parent;
|
||||
if (oflag & O_CREAT) {
|
||||
int excl = oflag & O_EXCL;
|
||||
parent = open(path_name.c_str(), O_RDONLY | O_CREAT | excl, 0666);
|
||||
} else {
|
||||
parent = open(path_name.c_str(), O_RDONLY);
|
||||
}
|
||||
if (parent < 0) return macos_error_from_errno();
|
||||
|
||||
oflag &= ~(O_CREAT | O_EXCL);
|
||||
int mode = oflag & O_ACCMODE;
|
||||
if (mode == O_WRONLY || mode == O_RDWR) oflag |= O_CREAT;
|
||||
int fd = attropen(path_name.c_str(), XATTR_RESOURCEFORK_NAME, oflag, 0666);
|
||||
if (fd < 0) return macos_error_from_errno();
|
||||
//int fd = attropen(path_name.c_str(), XATTR_RESOURCEFORK_NAME, oflag, 0666);
|
||||
int fd = openat(parent, XATTR_RESOURCEFORK_NAME, oflag | O_XATTR, 0666);
|
||||
if (fd < 0) {
|
||||
int e = macos_error_from_errno();
|
||||
close(parent);
|
||||
if (e == ENOENT && mode == O_RDONLY) {
|
||||
auto tmp = new empty_file(path_name);
|
||||
tmp->resource = true;
|
||||
return file_ptr(tmp);
|
||||
}
|
||||
return e;
|
||||
}
|
||||
close(parent);
|
||||
|
||||
auto tmp = new fd_file(path_name, fd);
|
||||
tmp->resource = true;
|
||||
|
||||
return file_ptr(tmp);
|
||||
}
|
||||
|
||||
|
@ -328,25 +328,17 @@ namespace native {
|
||||
|
||||
}
|
||||
|
||||
tool_return<file_ptr> open_fork(const std::string &path_name, int fork, int oflag, int perm) {
|
||||
tool_return<file_ptr> open_fork(const std::string &path_name, int fork, int oflag) {
|
||||
|
||||
if (!fork) {
|
||||
int fd = ::open(path_name.c_str(), oflag, perm);
|
||||
int fd = ::open(path_name.c_str(), oflag, 0666);
|
||||
if (fd < 0) return macos_error_from_errno();
|
||||
|
||||
return file_ptr(new fd_file(path_name, fd));
|
||||
}
|
||||
|
||||
// if O_CREAT or E_EXCL, may need to create the file
|
||||
|
||||
int tmp = oflag & (O_CREAT | O_EXCL);
|
||||
if (tmp) {
|
||||
int fd = ::open(path_name.c_str(), (oflag & O_ACCMODE) | tmp, perm);
|
||||
if (fd < 0) return macos_error_from_errno();
|
||||
::close(fd);
|
||||
oflag &= ~ (O_CREAT | O_EXCL);
|
||||
}
|
||||
return open_resource_fork(path_name, oflag);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -53,7 +53,7 @@ namespace native {
|
||||
|
||||
|
||||
|
||||
tool_return<file_ptr> open_fork(const std::string &path_name, int fork, int oflag, int perm = 0666);
|
||||
tool_return<file_ptr> open_fork(const std::string &path_name, int fork, int oflag);
|
||||
tool_return<file_ptr> open_resource_fork(const std::string &path_name, int oflag);
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user