more native::get_file_info

This commit is contained in:
Kelvin Sherlock 2016-07-31 13:36:29 -04:00
parent d27d0aae59
commit 62224b9c1d
2 changed files with 77 additions and 179 deletions

View File

@ -54,42 +54,92 @@
#include "stackframe.h"
#include "fs_spec.h"
#include <native/native.h>
using ToolBox::Log;
using MacOS::macos_error_from_errno;
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1050
#define st_birthtime st_mtime
#endif
namespace {
uint32_t rforksize(const std::string &path)
{
ssize_t rv;
rv = getxattr(path.c_str(), XATTR_RESOURCEFORK_NAME, nullptr, 0, 0, 0);
if (rv < 0) return 0;
return rv;
}
uint32_t rforksize(int fd)
{
ssize_t rv;
rv = fgetxattr(fd, XATTR_RESOURCEFORK_NAME, nullptr, 0, 0, 0);
if (rv < 0) return 0;
return rv;
}
}
namespace OS {
static uint16_t FileInfoByName(const std::string &sname, uint32_t parm) {
enum { // FileParam
_qLink = 0,
_qType = 4,
_ioTrap = 6,
_ioCmdAddr = 8,
_ioCompletion = 12,
_ioResult = 16,
_ioNamePtr = 18,
_ioVRefNum = 22,
_ioFRefNum = 24,
_ioFVersNum = 26,
_filler1 = 27,
_ioFDirIndex = 28,
_ioFlAttrib = 30,
_ioFlVersNum = 31,
_ioFlFndrInfo = 32,
_ioFlNum = 48, // ioDirID in other
_ioFlStBlk = 52,
_ioFlLgLen = 54,
_ioFlPyLen = 58,
_ioFlRStBlk = 62,
_ioFlRLgLen = 64,
_ioFlRPyLen = 68,
_ioFlCrDat = 72,
_ioFlMdDat = 76,
_ioDirID = 48,
};
using namespace native;
file_info fi;
auto err = native::get_file_info(sname, fi);
if (err) return err;
// if this is not a file, error out?
std::memcpy(memoryPointer(parm + _ioFlFndrInfo), fi.finder_info, 16);
// file reference number
memoryWriteWord(0, parm + _ioFRefNum);
// file attributes
memoryWriteByte(0, parm + _ioFlAttrib);
// version (unused)
memoryWriteByte(0, parm + _ioFlVersNum);
// file id
memoryWriteLong(0, parm + _ioFlNum);
// file size
memoryWriteWord(0, parm + _ioFlStBlk);
memoryWriteLong(fi.data_logical_size, parm + _ioFlLgLen);
memoryWriteLong(fi.data_physical_size, parm + _ioFlPyLen);
// create date.
memoryWriteLong(fi.create_date, parm + _ioFlCrDat);
memoryWriteLong(fi.modify_date, parm + _ioFlMdDat);
// res fork...
memoryWriteWord(0, parm + _ioFlRStBlk);
memoryWriteLong(fi.resource_logical_size, parm + _ioFlRLgLen);
memoryWriteLong(fi.resource_physical_size, parm + _ioFlRPyLen);
return 0;
}
uint16_t GetFileInfo(uint16_t trap)
{
@ -159,52 +209,10 @@ namespace OS {
Log(" GetFileInfo(%s)\n", sname.c_str());
d0 = FileInfoByName(sname, parm);
memoryWriteWord(d0, parm + _ioResult);
return d0;
struct stat st;
if (::stat(sname.c_str(), &st) < 0)
{
d0 = macos_error_from_errno();
memoryWriteWord(d0, parm + _ioResult);
return d0;
}
Internal::GetFinderInfo(sname, memoryPointer(parm + _ioFlFndrInfo), false);
// file reference number
memoryWriteWord(0, parm + _ioFRefNum);
// file attributes
memoryWriteByte(0, parm + _ioFlAttrib);
// version (unused)
memoryWriteByte(0, parm + _ioFlVersNum);
// file id
memoryWriteLong(0, parm + _ioFlNum);
// file size
memoryWriteWord(0, parm + _ioFlStBlk);
memoryWriteLong(st.st_size, parm + _ioFlLgLen);
memoryWriteLong(st.st_size, parm + _ioFlPyLen);
// create date.
memoryWriteLong(UnixToMac(st.st_birthtime), parm + _ioFlCrDat);
memoryWriteLong(UnixToMac(st.st_mtime), parm + _ioFlMdDat);
// res fork...
uint32_t rf = rforksize(sname);
memoryWriteWord(0, parm + _ioFlRStBlk);
memoryWriteLong(rf, parm + _ioFlRLgLen);
memoryWriteLong(rf, parm + _ioFlRPyLen);
// no error.
memoryWriteWord(0, parm + _ioResult);
}
else
{

View File

@ -41,6 +41,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <sys/param.h>
#include <strings.h>
@ -230,117 +231,6 @@ namespace OS {
}
return 0;
#if 0
struct stat st;
if (::stat(sname.c_str(), &st) < 0)
{
return macos_error_from_errno();
}
if (S_ISDIR(st.st_mode))
{
// bit 4 - is a directory.
memoryWriteByte(1 << 4, parm + _ioFlAttrib);
memoryWriteByte(0, parm + _ioACUser);
std::memset(memoryPointer(parm + _ioDrUsrWds), 0, 16); // DInfo
// cw68k expects the directory ID to be set.
uint32_t dirID = FSSpecManager::IDForPath(sname);
memoryWriteLong(dirID, parm + _ioDrDirID);
// the links count should be ~= number of dirents ( +2 for . and ..)
int links = st.st_nlink - 2;
if (links < 0) links = 0;
if (links > 65535) links = 65535;
memoryWriteWord(links, parm + _ioDrNmFls); // ioDrNmFls - # of files in dir
memoryWriteLong(UnixToMac(st.st_birthtime), parm + _ioDrCrDat); // create
memoryWriteLong(UnixToMac(st.st_mtime), parm + _ioDrMdDat); // modify
memoryWriteLong(UnixToMac(st.st_mtime), parm + _ioDrBkDat); // backup
std::memset(memoryPointer(parm + _ioDrFndrInfo), 0, 16); // DXInfo
memoryWriteLong(0, parm + _ioDrParID);
}
else
{
// st_blksize is the optimal block read size. st_blocks is the number of 512-byte blocks. I think.
// st_blocks seems to include both data and resource blocks. grrr....
memoryWriteByte(0, parm + _ioFlAttrib);
memoryWriteByte(0, parm + _ioACUser);
Internal::GetFinderInfo(sname, memoryPointer(parm + _ioFlFndrInfo), false); // finder info
memoryWriteLong(0, parm + _ioDirID);
memoryWriteWord(0, parm + _ioFlStBlk);
memoryWriteWord(0, parm + _ioFlRStBlk);
memoryWriteLong(st.st_size, parm + _ioFlLgLen);
memoryWriteLong(st.st_blocks * 512, parm + _ioFlPyLen);
// resource info... below
memoryWriteLong(UnixToMac(st.st_birthtime), parm + _ioFlCrDat); // create
memoryWriteLong(UnixToMac(st.st_mtime), parm + _ioFlMdDat); // modify
memoryWriteLong(UnixToMac(st.st_mtime), parm + _ioFlBkDat); // backup
std::memset(memoryPointer(parm + _ioFlXFndrInfo), 0, 16); // FXInfo
memoryWriteWord(0, parm + _ioFlParID);
memoryWriteWord(0, parm + _ioFlClpSiz);
struct {
uint32_t length;
off_t data_logical_size;
off_t data_physical_size;
off_t resource_logical_size;
off_t resource_physical_size;
} __attribute__((aligned(4), packed)) buffer;
struct attrlist at;
memset(&buffer, 0, sizeof(buffer));
memset(&at, 0, sizeof(at));
at.bitmapcount = ATTR_BIT_MAP_COUNT;
at.commonattr = 0 ;
at.fileattr = ATTR_FILE_DATALENGTH | ATTR_FILE_DATAALLOCSIZE | ATTR_FILE_RSRCLENGTH | ATTR_FILE_RSRCALLOCSIZE;
int ok = getattrlist(sname.c_str(), &at, &buffer, sizeof(buffer), 0);
if (ok == 0 && buffer.length == sizeof(buffer)) {
memoryWriteLong(buffer.data_logical_size, parm + _ioFlLgLen);
memoryWriteLong(buffer.data_physical_size, parm + _ioFlPyLen);
memoryWriteLong(buffer.resource_logical_size, parm + _ioFlRLgLen);
memoryWriteLong(buffer.resource_physical_size, parm + _ioFlRPyLen);
} else {
sname.append(_PATH_RSRCFORKSPEC);
if (::stat(sname.c_str(), &st) >= 0)
{
memoryWriteWord(0, parm + _ioFlRStBlk);
memoryWriteLong(st.st_size, parm + _ioFlRLgLen);
memoryWriteLong(0/* st.st_blocks * 512*/, parm + _ioFlRPyLen);
}
else
{
memoryWriteLong(0, parm + _ioFlRLgLen);
memoryWriteLong(0, parm + _ioFlRPyLen);
}
}
}
return 0;
#endif
}
uint16_t PBGetCatInfo(uint32_t parm)