Annotation of nono/host/diskdriver.cpp, revision 1.1.1.1

1.1       root        1: //
                      2: // nono
                      3: // Copyright (C) 2021 nono project
                      4: // Licensed under nono-license.txt
                      5: //
                      6: 
                      7: //
                      8: // ディスクイメージのドライバ (基本クラス)。
                      9: //
                     10: 
                     11: #include "diskdriver.h"
                     12: 
                     13: // コンストラクタ
                     14: DiskImageDriver::DiskImageDriver(const std::string& objname_,
                     15:                const std::string& pathname_)
                     16:        : inherited(OBJ_NONE)
                     17:        , pathname(pathname_)
                     18: {
                     19:        SetName(objname_);
                     20: }
                     21: 
                     22: // デストラクタ
                     23: DiskImageDriver::~DiskImageDriver()
                     24: {
                     25: }
                     26: 
                     27: // このディスクイメージが書き込み可能かどうかを返す。
                     28: int
                     29: DiskImageDriver::IsWriteable() const
                     30: {
                     31:        int rv;
                     32: 
                     33:        // ファイルのパーミッション
                     34:        int r = access(pathname.c_str(), W_OK);
                     35:        if (r == 0) {
                     36:                rv = 1;
                     37:        } else if (errno == EACCES) {
                     38:                rv = 0;
                     39:        } else {
                     40:                if (errno == ENOENT) {
                     41:                        warn("%s", pathname.c_str());
                     42:                } else {
                     43:                        warn("%s: access failed", pathname.c_str());
                     44:                }
                     45:                rv = -1;
                     46:        }
                     47: 
                     48:        return rv;
                     49: }
                     50: 
                     51: // ディスクイメージの現在位置から nbytes を dst に読み込み、現在位置を進める。
                     52: // 成功すれば読み込めたバイト数を返すが、nbytes 読めるまで繰り返すため
                     53: // 必ず nbytes を返す。
                     54: // 失敗すれば errno をセットして -1 を返す。
                     55: // 読み込み途中で EOF に達したらそこまでのバイト数を返すのではなく EIO
                     56: // 扱いにする。ここでいうディスクイメージの読み込み中に EOF を超えると
                     57: // すればそれは何か壊れていると思われるので。
                     58: /*static*/ ssize_t
                     59: DiskImageDriver::readimg(int fd_, void *dst, size_t nbytes)
                     60: {
                     61:        size_t n = 0;
                     62: 
                     63:        while (n < nbytes) {
                     64:                auto r = read(fd_, (uint8 *)dst + n, nbytes - n);
                     65:                if (__predict_false(r < 0)) {
                     66:                        if (errno == EINTR) {
                     67:                                continue;
                     68:                        }
                     69:                        return -1;
                     70:                }
                     71:                if (__predict_false(r == 0)) {
                     72:                        errno = EIO;
                     73:                        return -1;
                     74:                }
                     75: 
                     76:                n += r;
                     77:        }
                     78: 
                     79:        return n;
                     80: }
                     81: 
                     82: // ディスクイメージの現在位置に src から nbytes を書き込み、現在位置を進める。
                     83: // 成功すれば書き込んだバイト数を返すが、nbytes 書けるまで繰り返すため
                     84: // 必ず nbytes を返す。ファイルポインタは移動しない。
                     85: // 失敗すれば errno をセットして -1 を返す。
                     86: /*static*/ ssize_t
                     87: DiskImageDriver::writeimg(int fd_, const void *src, size_t nbytes)
                     88: {
                     89:        size_t n = 0;
                     90: 
                     91:        while (n < nbytes) {
                     92:                auto r = write(fd_, (const uint8 *)src + n, nbytes - n);
                     93:                if (__predict_false(r < 0)) {
                     94:                        if (errno == EINTR) {
                     95:                                continue;
                     96:                        }
                     97:                        return -1;
                     98:                }
                     99:                if (__predict_false(r == 0)) {
                    100:                        // 通常起きないはずらしいので。
                    101:                        errno = EIO;
                    102:                        return -1;
                    103:                }
                    104: 
                    105:                n += r;
                    106:        }
                    107: 
                    108:        return n;
                    109: }
                    110: 
                    111: // ディスクイメージの offset から nbytes を dst に読み込む。
                    112: // 成功すれば読み込めたバイト数を返すが、nbytes 読めるまで繰り返すため
                    113: // 必ず nbytes を返す。ファイルポインタは移動しない。
                    114: // 失敗すれば errno をセットして -1 を返す。
                    115: // 読み込み途中で EOF に達したらそこまでのバイト数を返すのではなく EIO
                    116: // 扱いにする。ここでいうディスクイメージの読み込み中に EOF を超えると
                    117: // すればそれは何か壊れていると思われるので。
                    118: /*static*/ ssize_t
                    119: DiskImageDriver::readpos(int fd_, void *dst, size_t nbytes, off_t offset)
                    120: {
                    121:        size_t n = 0;
                    122: 
                    123:        while (n < nbytes) {
                    124:                auto r = pread(fd_, (uint8 *)dst + n, nbytes - n, offset + n);
                    125:                if (__predict_false(r < 0)) {
                    126:                        if (errno == EINTR) {
                    127:                                continue;
                    128:                        }
                    129:                        return -1;
                    130:                }
                    131:                if (__predict_false(r == 0)) {
                    132:                        errno = EIO;
                    133:                        return -1;
                    134:                }
                    135: 
                    136:                n += r;
                    137:        }
                    138: 
                    139:        return n;
                    140: }
                    141: 
                    142: // ディスクイメージの offset 以降に src から nbytes を書き込む。
                    143: // 成功すれば書き込んだバイト数を返すが、nbytes 書けるまで繰り返すため
                    144: // 必ず nbytes を返す。ファイルポインタは移動しない。
                    145: // 失敗すれば errno をセットして -1 を返す。
                    146: /*static*/ ssize_t
                    147: DiskImageDriver::writepos(int fd_, const void *src, size_t nbytes, off_t offset)
                    148: {
                    149:        size_t n = 0;
                    150: 
                    151:        while (n < nbytes) {
                    152:                auto r = pwrite(fd_, (const uint8 *)src + n, nbytes - n, offset + n);
                    153:                if (__predict_false(r < 0)) {
                    154:                        if (errno == EINTR) {
                    155:                                continue;
                    156:                        }
                    157:                        return -1;
                    158:                }
                    159:                if (__predict_false(r == 0)) {
                    160:                        // 通常起きないはずらしいので。
                    161:                        errno = EIO;
                    162:                        return -1;
                    163:                }
                    164: 
                    165:                n += r;
                    166:        }
                    167: 
                    168:        return n;
                    169: }

unix.superglobalmegacorp.com

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