--- nono/lib/mappedfile.cpp 2026/04/29 17:04:34 1.1 +++ nono/lib/mappedfile.cpp 2026/04/29 17:05:48 1.1.1.5 @@ -4,7 +4,9 @@ // Licensed under nono-license.txt // +// // ファイルを mmap して提供するクラス +// #include "mappedfile.h" #include "mystring.h" @@ -16,7 +18,6 @@ // コンストラクタ MappedFile::MappedFile() { - fd = -1; } // デストラクタ @@ -45,47 +46,15 @@ MappedFile::SetDispname(const std::strin dispname = name; } -// サイズが len で確定しているファイルを読み込み専用でオープンして mmap する。 -// ファイルがなければエラー。これは ROM とか用。 -// 成功すれば mmap した領域のポインタを返す。 -// 失敗すればエラーメッセージを表示して NULL を返す。 -uint8 * -MappedFile::OpenRdOnly(off_t len) -{ - memlen = len; - - fd = open(filename.c_str(), O_RDONLY); - if (fd < 0) { - warn("%s open failed", dispname.c_str()); - return NULL; - } - - if (CheckFilesize() == false) { - Close(); - return NULL; - } - - // mmap する。 - // RDONLY なのでファイルには書き戻さないけど、 - // オンメモリでハックを入れたりできるよう MAP_PRIVATE を指定する。 - void *m = mmap(NULL, memlen, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); - if (m == MAP_FAILED) { - warn("%s mmap failed", dispname.c_str()); - Close(); - return NULL; - } - mem = (uint8 *)m; - - return mem; -} - // サイズが len で確定しているファイルを読み書き両用でオープンして mmap する。 -// ファイルがなければ作成する。これは SRAM とか用。 +// ファイルがなければ作成して、あれば data で初期化する。これは SRAM とか用。 // 成功すれば mmap した領域のポインタを返す。 // 失敗すればエラーメッセージを表示して NULL を返す。 uint8 * -MappedFile::OpenCreate(off_t memlen_) +MappedFile::OpenCreate(off_t memlen_, const uint8 *data, uint datalen) { + void *m; + memlen = memlen_; fd = open(filename.c_str(), O_RDWR); @@ -101,12 +70,22 @@ MappedFile::OpenCreate(off_t memlen_) return NULL; } - // ゼロで埋める - std::vector zerobuf(memlen); - if (write(fd, &zerobuf[0], zerobuf.size()) < 0) { - warn("%s write failed", dispname.c_str()); - Close(); - return NULL; + uint written = 0; + + // data, datalen が指定されていれば先頭から書き込む。 + if (data != NULL && datalen > 0) { + if (write(fd, data, datalen) < 0) { + warn("%s write failed", dispname.c_str()); + goto abort; + } + written = datalen; + } + + // (残りを)ゼロで埋める。 + std::vector zerobuf(memlen - written); + if (write(fd, zerobuf.data(), zerobuf.size()) < 0) { + warn("%s clear failed", dispname.c_str()); + goto abort; } warnx("%s created", dispname.c_str()); @@ -115,55 +94,22 @@ MappedFile::OpenCreate(off_t memlen_) } if (CheckFilesize() == false) { - Close(); - return NULL; + goto abort; } // mmap する。 - void *m = mmap(NULL, memlen, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + m = mmap(NULL, memlen, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (m == MAP_FAILED) { warn("%s mmap failed", dispname.c_str()); - Close(); - return NULL; + goto abort; } mem = (uint8 *)m; return mem; -} - -// サイズの確定していないファイルを読み書き両用でオープンして mmap する。 -// ファイルがなければエラー。これはディスクイメージ用。 -// 成功すれば mmap した領域のポインタを返す。 -// 失敗すればエラーメッセージを表示して NULL を返す。 -uint8 * -MappedFile::OpenFile() -{ - struct stat st; - - fd = open(filename.c_str(), O_RDWR); - if (fd < 0) { - warn("%s open failed", dispname.c_str()); - return NULL; - } - - // ファイルサイズを取得 - if (fstat(fd, &st) < 0) { - warn("%s stat failed", dispname.c_str()); - Close(); - return NULL; - } - memlen = st.st_size; - - // mmap する。 - void *m = mmap(NULL, memlen, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - if (mem == MAP_FAILED) { - warn("%s mmap failed", dispname.c_str()); - Close(); - return NULL; - } - mem = (uint8 *)m; - return mem; + abort: + Close(); + return NULL; } // ファイルサイズが memlen と同じかどうか調べる。 @@ -205,9 +151,7 @@ MappedFile::Close() mem = NULL; memlen = 0; } - if (fd >= 0) { - close(fd); - } + fd.Close(); filename.clear(); dispname.clear();