File:  [Isaki's NoNo m68k/m88k emulator] / nono / host / diskimage_raw.cpp
Revision 1.1.1.5 (vendor branch): download - view: text, annotated - select for diffs
Wed Apr 29 17:05:30 2026 UTC (2 months, 3 weeks ago) by root
Branches: MAIN, Isaki
CVS tags: v026, v025, v024, v023, v022, v021, v020, HEAD
nono 1.0.0

//
// nono
// Copyright (C) 2021 nono project
// Licensed under nono-license.txt
//

//
// ディスクイメージ (生イメージ形式)
//

#include "diskimage_raw.h"
#include <fcntl.h>
#include <sys/stat.h>

// コンストラクタ
DiskImageRaw::DiskImageRaw(const std::string& pathname_)
	: inherited(pathname_)
{
}

// デストラクタ
DiskImageRaw::~DiskImageRaw()
{
}

// このディスクイメージが書き込み可能かどうかを返す。
// Open() 前でも動作する。
int
DiskImageRaw::IsWriteable() const
{
	int rv;

	// ファイルのパーミッション
	int r = access(pathname.c_str(), W_OK);
	if (r == 0) {
		rv = 1;
	} else if (errno == EACCES) {
		rv = 0;
	} else {
		if (errno == ENOENT) {
			warn("%s", pathname.c_str());
		} else {
			warn("%s: access failed", pathname.c_str());
		}
		rv = -1;
	}

	return rv;
}

// オープン
bool
DiskImageRaw::Open(bool read_only)
{
	int openmode;

	assert(pathname.empty() == false);

	if (read_only) {
		openmode = O_RDONLY;
	} else {
		openmode = O_RDWR;
	}

	fd = open(pathname.c_str(), openmode);
	if (fd < 0) {
		warn("%s", pathname.c_str());
		return false;
	}

	// ファイルサイズを取得
	struct stat st;
	if (fstat(fd, &st) < 0) {
		warn("%s: stat failed", pathname.c_str());
		fd.Close();
		return false;
	}
	filesize = st.st_size;

	return true;
}

void
DiskImageRaw::Close()
{
	fd.Close();
	filesize = 0;
}

bool
DiskImageRaw::Read(void *buf, off_t offset, size_t size)
{
	if (__predict_false(fd < 0)) {
		return false;
	}
	if (__predict_false(offset + size > GetSize())) {
		return false;
	}

	if (lseek(fd, offset, SEEK_SET) == (off_t)-1) {
		return false;
	}

	if (read(fd, buf, size) < 0) {
		return false;
	}
	return true;
}

bool
DiskImageRaw::Write(const void *buf, off_t offset, size_t size)
{
	if (__predict_false(fd < 0)) {
		return false;
	}
	if (__predict_false(offset + size > GetSize())) {
		return false;
	}

	if (lseek(fd, offset, SEEK_SET) == (off_t)-1) {
		return false;
	}

	if (write(fd, buf, size) < 0) {
		return false;
	}
	return true;
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.