|
|
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;
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.