File:  [Isaki's NoNo m68k/m88k emulator] / nono / host / diskdriver.cpp
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Wed Apr 29 17:06:02 2026 UTC (2 months, 3 weeks ago) by root
Branches: MAIN, Isaki
CVS tags: v027, HEAD
nono 1.7.0

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

//
// ディスクイメージのドライバ (基本クラス)。
//

#include "diskdriver.h"

// コンストラクタ
DiskImageDriver::DiskImageDriver(const std::string& objname_,
		const std::string& pathname_)
	: inherited(OBJ_NONE)
	, pathname(pathname_)
{
	SetName(objname_);
}

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

// このディスクイメージが書き込み可能かどうかを返す。
int
DiskImageDriver::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;
}

// ディスクイメージの現在位置から nbytes を dst に読み込み、現在位置を進める。
// 成功すれば読み込めたバイト数を返すが、nbytes 読めるまで繰り返すため
// 必ず nbytes を返す。
// 失敗すれば errno をセットして -1 を返す。
// 読み込み途中で EOF に達したらそこまでのバイト数を返すのではなく EIO
// 扱いにする。ここでいうディスクイメージの読み込み中に EOF を超えると
// すればそれは何か壊れていると思われるので。
/*static*/ ssize_t
DiskImageDriver::readimg(int fd_, void *dst, size_t nbytes)
{
	size_t n = 0;

	while (n < nbytes) {
		auto r = read(fd_, (uint8 *)dst + n, nbytes - n);
		if (__predict_false(r < 0)) {
			if (errno == EINTR) {
				continue;
			}
			return -1;
		}
		if (__predict_false(r == 0)) {
			errno = EIO;
			return -1;
		}

		n += r;
	}

	return n;
}

// ディスクイメージの現在位置に src から nbytes を書き込み、現在位置を進める。
// 成功すれば書き込んだバイト数を返すが、nbytes 書けるまで繰り返すため
// 必ず nbytes を返す。ファイルポインタは移動しない。
// 失敗すれば errno をセットして -1 を返す。
/*static*/ ssize_t
DiskImageDriver::writeimg(int fd_, const void *src, size_t nbytes)
{
	size_t n = 0;

	while (n < nbytes) {
		auto r = write(fd_, (const uint8 *)src + n, nbytes - n);
		if (__predict_false(r < 0)) {
			if (errno == EINTR) {
				continue;
			}
			return -1;
		}
		if (__predict_false(r == 0)) {
			// 通常起きないはずらしいので。
			errno = EIO;
			return -1;
		}

		n += r;
	}

	return n;
}

// ディスクイメージの offset から nbytes を dst に読み込む。
// 成功すれば読み込めたバイト数を返すが、nbytes 読めるまで繰り返すため
// 必ず nbytes を返す。ファイルポインタは移動しない。
// 失敗すれば errno をセットして -1 を返す。
// 読み込み途中で EOF に達したらそこまでのバイト数を返すのではなく EIO
// 扱いにする。ここでいうディスクイメージの読み込み中に EOF を超えると
// すればそれは何か壊れていると思われるので。
/*static*/ ssize_t
DiskImageDriver::readpos(int fd_, void *dst, size_t nbytes, off_t offset)
{
	size_t n = 0;

	while (n < nbytes) {
		auto r = pread(fd_, (uint8 *)dst + n, nbytes - n, offset + n);
		if (__predict_false(r < 0)) {
			if (errno == EINTR) {
				continue;
			}
			return -1;
		}
		if (__predict_false(r == 0)) {
			errno = EIO;
			return -1;
		}

		n += r;
	}

	return n;
}

// ディスクイメージの offset 以降に src から nbytes を書き込む。
// 成功すれば書き込んだバイト数を返すが、nbytes 書けるまで繰り返すため
// 必ず nbytes を返す。ファイルポインタは移動しない。
// 失敗すれば errno をセットして -1 を返す。
/*static*/ ssize_t
DiskImageDriver::writepos(int fd_, const void *src, size_t nbytes, off_t offset)
{
	size_t n = 0;

	while (n < nbytes) {
		auto r = pwrite(fd_, (const uint8 *)src + n, nbytes - n, offset + n);
		if (__predict_false(r < 0)) {
			if (errno == EINTR) {
				continue;
			}
			return -1;
		}
		if (__predict_false(r == 0)) {
			// 通常起きないはずらしいので。
			errno = EIO;
			return -1;
		}

		n += r;
	}

	return n;
}

unix.superglobalmegacorp.com

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