mirror of
https://github.com/ksherlock/mpw.git
synced 2024-11-25 19:30: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.
|
// todo -- verify behavior on non-hfs volume.
|
||||||
//if ((oflag & O_ACCMODE) & O_WRONLY) oflag |= O_CREAT;
|
//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);
|
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);
|
auto tmp = new fd_file(path_name, fd);
|
||||||
tmp->resource = true;
|
tmp->resource = true;
|
||||||
|
@ -47,7 +47,7 @@ namespace {
|
|||||||
|
|
||||||
class xattr_file final : public file {
|
class xattr_file final : public file {
|
||||||
public:
|
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();
|
~xattr_file();
|
||||||
|
|
||||||
|
|
||||||
@ -65,7 +65,7 @@ namespace {
|
|||||||
|
|
||||||
int _fd = -1;
|
int _fd = -1;
|
||||||
off_t _displacement = 0;
|
off_t _displacement = 0;
|
||||||
|
bool _readonly = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
xattr_file::~xattr_file() {
|
xattr_file::~xattr_file() {
|
||||||
@ -101,6 +101,8 @@ namespace {
|
|||||||
|
|
||||||
|
|
||||||
tool_return<size_t> xattr_file::write(const void *in_buffer, size_t count) {
|
tool_return<size_t> xattr_file::write(const void *in_buffer, size_t count) {
|
||||||
|
if (_readonly) return MacOS::wrPermErr;
|
||||||
|
|
||||||
std::vector<uint8_t> buffer;
|
std::vector<uint8_t> buffer;
|
||||||
ssize_t size;
|
ssize_t size;
|
||||||
size = read_rfork(buffer);
|
size = read_rfork(buffer);
|
||||||
@ -140,6 +142,8 @@ namespace {
|
|||||||
|
|
||||||
tool_return<void> xattr_file::set_eof(ssize_t new_eof) {
|
tool_return<void> xattr_file::set_eof(ssize_t new_eof) {
|
||||||
|
|
||||||
|
if (_readonly) return MacOS::wrPermErr;
|
||||||
|
|
||||||
if (new_eof < 0) return paramErr;
|
if (new_eof < 0) return paramErr;
|
||||||
|
|
||||||
std::vector<uint8_t> buffer;
|
std::vector<uint8_t> buffer;
|
||||||
@ -159,11 +163,26 @@ namespace {
|
|||||||
|
|
||||||
namespace native {
|
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);
|
/* under HFS, every file has a resource fork.
|
||||||
if (fd < 0) return macos_error_from_errno();
|
* Therefore, create it if opening for O_RDWR or O_WRONLY
|
||||||
return std::make_shared<file>(fd);
|
*/
|
||||||
|
|
||||||
|
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.
|
/* under HFS, every file has a resource fork.
|
||||||
* Therefore, create it if opening for O_RDWR or O_WRONLY
|
* 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;
|
int mode = oflag & O_ACCMODE;
|
||||||
if (mode == O_WRONLY || mode == O_RDWR) oflag |= O_CREAT;
|
if (mode == O_WRONLY || mode == O_RDWR) oflag |= O_CREAT;
|
||||||
int fd = attropen(path_name.c_str(), XATTR_RESOURCEFORK_NAME, oflag, 0666);
|
//int fd = attropen(path_name.c_str(), XATTR_RESOURCEFORK_NAME, oflag, 0666);
|
||||||
if (fd < 0) return macos_error_from_errno();
|
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);
|
auto tmp = new fd_file(path_name, fd);
|
||||||
tmp->resource = true;
|
tmp->resource = true;
|
||||||
|
|
||||||
return file_ptr(tmp);
|
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) {
|
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();
|
if (fd < 0) return macos_error_from_errno();
|
||||||
|
|
||||||
return file_ptr(new fd_file(path_name, fd));
|
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);
|
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);
|
tool_return<file_ptr> open_resource_fork(const std::string &path_name, int oflag);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user