CreateResFile.

This commit is contained in:
Kelvin Sherlock 2016-08-11 22:36:17 -04:00
parent c5df52edb8
commit 46e01b8b0a

View File

@ -38,6 +38,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/stat.h>
#include <cpu/defs.h> #include <cpu/defs.h>
#include <cpu/CpuModule.h> #include <cpu/CpuModule.h>
@ -696,13 +697,69 @@ namespace Native {
/*
* CreateResFile returns an error if the file already exists. others do not...
*/
tool_return<void> CreateResFile(const std::string &path, uint32_t creator, uint32_t fileType) tool_return<void> CreateResFile(const std::string &path, uint32_t creator, uint32_t fileType)
{ {
if (path.empty()) return MacOS::paramErr;
fprintf(stderr, "%s : not yet implemented!\n", __func__); uint8_t empty_resource_fork[] = {
exit(1); 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
return noErr; 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x1e, 0xff, 0xff
};
if (path.empty()) return SetResError(MacOS::bdNamErr);
struct stat st;
int fd = native::open_fork(path, 1, O_WRONLY, 0666);
if (fd < 0) return SetResError(macos_error_from_errno());
// need to check if resource fork size > 0 -- don't clobber an existing fork.
if (fstat(fd, &st) < 0) {
auto rv = macos_error_from_errno();
close(fd);
return SetResError(rv);
}
if (st.st_size > 0) {
close(fd);
return SetResError(noErr);
}
ssize_t ok = write(fd, empty_resource_fork, sizeof(empty_resource_fork));
if (ok != sizeof(empty_resource_fork)) {
auto rv = macos_error_from_errno();
close(fd);
return SetResError(rv);
}
close(fd);
return SetResError(noErr);
} }
@ -1264,12 +1321,14 @@ namespace Native {
std::string sname = ToolBox::ReadPString(fileName, true); std::string sname = ToolBox::ReadPString(fileName, true);
Log("%04x CreateResFile(%s)\n", trap, sname.c_str()); Log("%04x CreateResFile(%s)\n", trap, sname.c_str());
if (!sname.length()) return SetResError(MacOS::paramErr); if (!sname.length()) return SetResError(MacOS::bdNamErr);
/* check if file exists ... */
int fd = open(sname.c_str(), O_CREAT|O_EXCL|O_WRONLY, 0666);
if (fd < 0 && errno == EEXIST) return SetResError(dupFNErr);
if (fd >= 0) close(fd);
auto rv = Native::CreateResFile(sname); return Native::CreateResFile(sname).error();
return rv.error();
} }
uint16_t HCreateResFile(uint16_t trap) uint16_t HCreateResFile(uint16_t trap)
@ -1291,13 +1350,9 @@ namespace Native {
sname = OS::FSSpecManager::ExpandPath(sname, dirID); sname = OS::FSSpecManager::ExpandPath(sname, dirID);
if (sname.empty()) if (sname.empty())
{
return SetResError(MacOS::dirNFErr); return SetResError(MacOS::dirNFErr);
}
auto rv = Native::CreateResFile(sname); return Native::CreateResFile(sname).error();
return SetResError(rv.error() == MacOS::dupFNErr ? 0 : rv.error());
} }
@ -1329,13 +1384,9 @@ namespace Native {
sname = OS::FSSpecManager::ExpandPath(sname, parentID); sname = OS::FSSpecManager::ExpandPath(sname, parentID);
if (sname.empty()) if (sname.empty())
{
return SetResError(MacOS::dirNFErr); return SetResError(MacOS::dirNFErr);
}
auto rv = Native::CreateResFile(sname, creator, fileType); return Native::CreateResFile(sname, creator, fileType).error();
return SetResError(rv.error() == MacOS::dupFNErr ? 0 : rv.error());
} }