SetFileDates (create / mod / backup)

This commit is contained in:
Kelvin Sherlock 2014-12-26 16:31:58 -05:00
parent b7aa23f163
commit 2c3388f76a
5 changed files with 80 additions and 157 deletions

View File

@ -741,162 +741,6 @@ namespace OS
}
#if 0
uint16_t GetFileInfo(uint16_t trap)
{
uint16_t d0;
uint32_t parm = cpuGetAReg(0);
Log("%04x GetFileInfo(%08x)\n", trap, parm);
//uint32_t ioCompletion = memoryReadLong(parm + 12);
uint32_t ioNamePtr = memoryReadLong(parm + 18);
//uint16_t ioVRefNum = memoryReadWord(parm + 22);
//uint8_t ioFVersNum = memoryReadByte(parm + 26);
int16_t ioFDirIndex = memoryReadWord(parm + 28);
if (ioFDirIndex <= 0)
{
// based name
std::string sname;
if (!ioNamePtr)
{
memoryWriteWord(MacOS::bdNamErr, parm + 16);
return MacOS::bdNamErr;
}
sname = ToolBox::ReadPString(ioNamePtr, true);
Log(" GetFileInfo(%s)\n", sname.c_str());
// todo -- how are absolute, relative, etc paths handled...
struct stat st;
if (::stat(sname.c_str(), &st) < 0)
{
d0 = macos_error_from_errno();
memoryWriteWord(d0, parm + 16);
return d0;
}
Internal::GetFinderInfo(sname, memoryPointer(parm + 32), false);
// file reference number
memoryWriteWord(0, parm + 24);
// file attributes
memoryWriteByte(0, parm + 30);
// version (unused)
memoryWriteByte(0, parm + 31);
// file id
memoryWriteLong(0, parm + 48);
// file size
memoryWriteWord(0, parm + 52);
memoryWriteLong(st.st_size, parm + 54);
memoryWriteLong(st.st_size, parm + 58);
// create date.
memoryWriteLong(UnixToMac(st.st_birthtime), parm + 72);
memoryWriteLong(UnixToMac(st.st_mtime), parm + 76);
// res fork...
// do this last since it adjusts the name and the stat.
sname.append(_PATH_RSRCFORKSPEC);
if (::stat(sname.c_str(), &st) >= 0)
{
memoryWriteWord(0, parm + 62);
memoryWriteLong(st.st_size, parm + 64);
memoryWriteLong(st.st_size, parm + 68);
}
else
{
memoryWriteWord(0, parm + 62);
memoryWriteLong(0, parm + 64);
memoryWriteLong(0, parm + 68);
}
// no error.
memoryWriteWord(0, parm + 16);
}
else
{
fprintf(stderr, "GetFileInfo -- ioFDirIndex not yet supported\n");
exit(1);
}
// if iocompletion handler && asyn call....
return 0;
}
uint16_t SetFileInfo(uint16_t trap)
{
std::string sname;
uint16_t d0;
uint32_t parm = cpuGetAReg(0);
Log("%04x SetFileInfo(%08x)\n", trap, parm);
//uint32_t ioCompletion = memoryReadLong(parm + 12);
uint32_t ioNamePtr = memoryReadLong(parm + 18);
//uint16_t ioVRefNum = memoryReadWord(parm + 22);
//uint8_t ioFVersNum = memoryReadByte(parm + 26);
//int16_t ioFDirIndex = memoryReadWord(parm + 28);
// + 32 = finder data - 16 bytes.
//uint32_t ioFlCrDat = memoryReadLong(parm + 72);
//uint32_t ioFlMdDat = memoryReadLong(parm + 76);
// currently, only sets finder info.
if (!ioNamePtr)
{
memoryWriteWord(MacOS::bdNamErr, parm + 16);
return MacOS::bdNamErr;
}
sname = ToolBox::ReadPString(ioNamePtr, true);
Log(" SetFileInfo(%s)\n", sname.c_str());
// check if the file actually exists
{
struct stat st;
int ok;
ok = ::stat(sname.c_str(), &st);
if (ok < 0)
{
d0 = macos_error_from_errno();
memoryWriteWord(d0, parm + 16);
return d0;
}
}
d0 = Internal::SetFinderInfo(sname, memoryPointer(parm + 32), false);
memoryWriteWord(d0, parm + 16);
return d0;
}
#endif
#pragma mark - String Utilities
uint16_t CmpString(uint16_t trap)

View File

@ -288,7 +288,7 @@ namespace OS {
}
d0 = Internal::SetFinderInfo(sname, memoryPointer(parm + 32), false);
if (d0 == 0) d0 = Internal::SetFileDates(sname, memoryReadLong(parm + _ioFlCrDat), memoryReadLong(parm + _ioFlMdDat), 0);
memoryWriteWord(d0, parm + _ioResult);
return d0;
}

View File

@ -362,6 +362,12 @@ namespace OS {
if (S_ISDIR(st.st_mode))
{
d0 = 0;
d0 = Internal::SetFileDates(sname,
memoryReadLong(parm + _ioDrCrDat),
memoryReadLong(parm + _ioDrMdDat),
memoryReadLong(parm + _ioDrBkDat));
memoryWriteWord(d0, parm + _ioResult);
return d0;
}
@ -371,6 +377,12 @@ namespace OS {
// set the finder info. could also call utimes or setattrlist, I suppose.
d0 = Internal::SetFinderInfo(sname, memoryPointer(parm + _ioFlFndrInfo), false);
if (d0 == 0) d0 = Internal::SetFileDates(sname,
memoryReadLong(parm + _ioFlCrDat),
memoryReadLong(parm + _ioFlMdDat),
memoryReadLong(parm + _ioFlBkDat));
memoryWriteWord(d0, parm + _ioResult);
return d0;

View File

@ -36,6 +36,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <sys/xattr.h>
#include <sys/attr.h>
#include <sys/paths.h>
#include <machine/endian.h>
@ -288,6 +289,70 @@ namespace OS { namespace Internal {
}
uint16_t SetFileDates(const std::string &pathname, uint32_t createDate, uint32_t modificationDate, uint32_t backupDate)
{
// utimes(2) sets the access and mod times.
// setattrlist sets the create and mod times (among other things)
// this is kind of unfortunate in that a roundtrip will strip any nanoseconds, etc from the date/time.
int rv;
struct attrlist list;
unsigned i = 0;
timespec dates[3];
memset(&list, 0, sizeof(list));
memset(dates, 0, sizeof(dates));
list.bitmapcount = ATTR_BIT_MAP_COUNT;
list.commonattr = 0;
if (createDate)
{
dates[i++].tv_sec = MacToUnix(createDate);
list.commonattr |= ATTR_CMN_CRTIME;
}
if (modificationDate)
{
dates[i++].tv_sec = MacToUnix(modificationDate);
list.commonattr |= ATTR_CMN_MODTIME;
}
if (backupDate)
{
dates[i++].tv_sec = MacToUnix(backupDate);
list.commonattr |= ATTR_CMN_BKUPTIME;
}
if (!i) return 0;
rv = setattrlist(pathname.c_str(), &list, dates, i * sizeof(timespec), 0);
if (rv < 0 && errno == ENOTSUP)
{
// try utimes.
struct timeval tv[2];
memset(tv, 0, sizeof(tv));
if (modificationDate) {
tv[1].tv_sec = MacToUnix(modificationDate);
rv = utimes(pathname.c_str(), tv);
}
}
if (rv < 0) return macos_error_from_errno();
return 0;
}
int32_t mac_seek(uint16_t refNum, uint16_t mode, int32_t offset)
{
off_t rv;

View File

@ -11,6 +11,8 @@ namespace OS { namespace Internal {
uint16_t SetFinderInfo(const std::string &pathName, uint32_t fileType, uint32_t creator);
uint16_t SetFileDates(const std::string &pathname, uint32_t createDate, uint32_t modificationDate, uint32_t backupDate);
uint16_t GetFileType(const std::string &pathname, uint16_t *fileType, uint32_t *auxType);
int32_t mac_seek(uint16_t refNum, uint16_t mode, int32_t offset);