Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
501};503class PosixEnv : public Env {504public:505PosixEnv();506~PosixEnv() override {507static const char msg[] =508"PosixEnv singleton destroyed. Unsupported behavior!\n";509std::fwrite(msg, 1, sizeof(msg), stderr);510std::abort();511}513Status NewSequentialFile(const std::string& filename,514SequentialFile** result) override {515int fd = ::open(filename.c_str(), O_RDONLY | kOpenBaseFlags);516if (fd < 0) {517*result = nullptr;518return PosixError(filename, errno);519}521*result = new PosixSequentialFile(filename, fd);522return Status::OK();523}525Status NewRandomAccessFile(const std::string& filename,526RandomAccessFile** result) override {527*result = nullptr;528int fd = ::open(filename.c_str(), O_RDONLY | kOpenBaseFlags);529if (fd < 0) {530return PosixError(filename, errno);531}533if (!mmap_limiter_.Acquire()) {534*result = new PosixRandomAccessFile(filename, fd, &fd_limiter_);535return Status::OK();536}538uint64_t file_size;539Status status = GetFileSize(filename, &file_size);540if (status.ok()) {541void* mmap_base =542::mmap(/*addr=*/nullptr, file_size, PROT_READ, MAP_SHARED, fd, 0);543if (mmap_base != MAP_FAILED) {544*result = new PosixMmapReadableFile(filename,545reinterpret_cast<char*>(mmap_base),546file_size, &mmap_limiter_);547} else {548status = PosixError(filename, errno);549}550}551::close(fd);552if (!status.ok()) {553mmap_limiter_.Release();554}555return status;556}558Status NewWritableFile(const std::string& filename,559WritableFile** result) override {560int fd = ::open(filename.c_str(),561O_TRUNC | O_WRONLY | O_CREAT | kOpenBaseFlags, 0644);562if (fd < 0) {563*result = nullptr;564return PosixError(filename, errno);565}567*result = new PosixWritableFile(filename, fd);568return Status::OK();569}571Status NewAppendableFile(const std::string& filename,572WritableFile** result) override {573int fd = ::open(filename.c_str(),574O_APPEND | O_WRONLY | O_CREAT | kOpenBaseFlags, 0644);575if (fd < 0) {576*result = nullptr;577return PosixError(filename, errno);578}580*result = new PosixWritableFile(filename, fd);581return Status::OK();582}584bool FileExists(const std::string& filename) override {585return ::access(filename.c_str(), F_OK) == 0;586}588Status GetChildren(const std::string& directory_path,589std::vector<std::string>* result) override {590result->clear();591::DIR* dir = ::opendir(directory_path.c_str());592if (dir == nullptr) {593return PosixError(directory_path, errno);594}595struct ::dirent* entry;596while ((entry = ::readdir(dir)) != nullptr) {597result->emplace_back(entry->d_name);598}599::closedir(dir);600return Status::OK();601}603Status DeleteFile(const std::string& filename) override {604if (::unlink(filename.c_str()) != 0) {605return PosixError(filename, errno);606}607return Status::OK();608}610Status CreateDir(const std::string& dirname) override {611if (::mkdir(dirname.c_str(), 0755) != 0) {612return PosixError(dirname, errno);613}614return Status::OK();615}617Status DeleteDir(const std::string& dirname) override {618if (::rmdir(dirname.c_str()) != 0) {619return PosixError(dirname, errno);620}621return Status::OK();622}624Status GetFileSize(const std::string& filename, uint64_t* size) override {625struct ::stat file_stat;626if (::stat(filename.c_str(), &file_stat) != 0) {627*size = 0;628return PosixError(filename, errno);629}630*size = file_stat.st_size;631return Status::OK();632}634Status RenameFile(const std::string& from, const std::string& to) override {635if (std::rename(from.c_str(), to.c_str()) != 0) {636return PosixError(from, errno);637}638return Status::OK();639}641Status LockFile(const std::string& filename, FileLock** lock) override {642*lock = nullptr;644int fd = ::open(filename.c_str(), O_RDWR | O_CREAT | kOpenBaseFlags, 0644);645if (fd < 0) {646return PosixError(filename, errno);647}649if (!locks_.Insert(filename)) {650::close(fd);651return Status::IOError("lock " + filename, "already held by process");652}654if (LockOrUnlock(fd, true) == -1) {655int lock_errno = errno;656::close(fd);657locks_.Remove(filename);658return PosixError("lock " + filename, lock_errno);659}661*lock = new PosixFileLock(fd, filename);662return Status::OK();663}665Status UnlockFile(FileLock* lock) override {666PosixFileLock* posix_file_lock = static_cast<PosixFileLock*>(lock);667if (LockOrUnlock(posix_file_lock->fd(), false) == -1) {668return PosixError("unlock " + posix_file_lock->filename(), errno);669}670locks_.Remove(posix_file_lock->filename());671::close(posix_file_lock->fd());672delete posix_file_lock;673return Status::OK();674}676void Schedule(void (*background_work_function)(void* background_work_arg),677void* background_work_arg) override;679void StartThread(void (*thread_main)(void* thread_main_arg),680void* thread_main_arg) override {681std::thread new_thread(thread_main, thread_main_arg);682new_thread.detach();683}685Status GetTestDirectory(std::string* result) override {686const char* env = std::getenv("TEST_TMPDIR");687if (env && env[0] != '\0') {688*result = env;689} else {690char buf[100];691std::snprintf(buf, sizeof(buf), "/tmp/leveldbtest-%d",692static_cast<int>(::geteuid()));693*result = buf;694}696// The CreateDir status is ignored because the directory may already exist.697CreateDir(*result);699return Status::OK();700}702Status NewLogger(const std::string& filename, Logger** result) override {703int fd = ::open(filename.c_str(),704O_APPEND | O_WRONLY | O_CREAT | kOpenBaseFlags, 0644);705if (fd < 0) {706*result = nullptr;707return PosixError(filename, errno);708}710std::FILE* fp = ::fdopen(fd, "w");711if (fp == nullptr) {712::close(fd);713*result = nullptr;714return PosixError(filename, errno);715} else {716*result = new PosixLogger(fp);717return Status::OK();718}719}721uint64_t NowMicros() override {722static constexpr uint64_t kUsecondsPerSecond = 1000000;723struct ::timeval tv;724::gettimeofday(&tv, nullptr);725return static_cast<uint64_t>(tv.tv_sec) * kUsecondsPerSecond + tv.tv_usec;726}728void SleepForMicroseconds(int micros) override {729std::this_thread::sleep_for(std::chrono::microseconds(micros));730}732private:733[[noreturn]] void BackgroundThreadMain();735[[noreturn]] static void BackgroundThreadEntryPoint(PosixEnv* env) {736env->BackgroundThreadMain();737}739// Stores the work item data in a Schedule() call.740//741// Instances are constructed on the thread calling Schedule() and used on the742// background thread.743//744// This structure is thread-safe because it is immutable.745struct BackgroundWorkItem {746explicit BackgroundWorkItem(void (*function)(void* arg), void* arg)747: function(function), arg(arg) {}749void (*const function)(void*);750void* const arg;
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.