📄 posixstorage.cxx
字号:
Boolean PosixStorageManager::transformNeutral(StringC &, Boolean, Messenger &) const{ return 1;}#endif /* not FILENAME_TYPE_DEFINED */Boolean PosixStorageManager::resolveRelative(const StringC &baseId, StringC &specId, Boolean search) const{ if (isAbsolute(specId)) return 1; if (!search || searchDirs_.size() == 0) { specId = combineDir(extractDir(baseId), specId); return 1; } return 0;}StorageObject *PosixStorageManager::makeStorageObject(const StringC &spec, const StringC &base, Boolean search, Boolean mayRewind, Messenger &mgr, StringC &found){ if (spec.size() == 0) { mgr.message(PosixStorageMessages::invalidFilename, StringMessageArg(spec)); return 0; } descriptorManager_.acquireD(); Boolean absolute = isAbsolute(spec); SearchResultMessageArg sr; for (size_t i = 0; i < searchDirs_.size() + 1; i++) { StringC filename; if (absolute) filename = spec; else if (i == 0) filename = combineDir(extractDir(base), spec); else filename = combineDir(searchDirs_[i - 1], spec);#ifdef SP_WIDE_SYSTEM String<FChar> cfilename(filename); cfilename += FChar(0);#else String<FChar> cfilename = filenameCodingSystem_->convertOut(filename);#endif int fd; do { fd = openFile(cfilename.data()); } while (fd < 0 && errno == EINTR); if (fd >= 0) { found = filename; return new PosixStorageObject(fd, filename, cfilename, mayRewind, &descriptorManager_); } int savedErrno = errno; if (absolute || !search || searchDirs_.size() == 0) { ParentLocationMessenger(mgr).message(PosixStorageMessages::openSystemCall, StringMessageArg(filename), ErrnoMessageArg(savedErrno)); descriptorManager_.releaseD(); return 0; } sr.add(filename, savedErrno); } descriptorManager_.releaseD(); ParentLocationMessenger(mgr).message(PosixStorageMessages::cannotFind, StringMessageArg(spec), sr); return 0;}PosixStorageObject::PosixStorageObject(int fd, const StringC &filename, const String<FChar> &cfilename, Boolean mayRewind, DescriptorManager *manager): DescriptorUser(manager), PosixBaseStorageObject(fd, mayRewind), suspended_(0), filename_(filename), cfilename_(cfilename){}PosixStorageObject::~PosixStorageObject(){ if (fd_ >= 0) { (void)xclose(fd_); releaseD(); }}Boolean PosixStorageObject::seek(off_t off, Messenger &mgr){ if (lseek(fd_, off, SEEK_SET) < 0) { fd_ = -1; systemError(mgr, PosixStorageMessages::lseekSystemCall, errno); return 0; } else return 1;}Boolean PosixStorageObject::read(char *buf, size_t bufSize, Messenger &mgr, size_t &nread){ if (readSaved(buf, bufSize, nread)) return 1; if (suspended_) resume(mgr); if (fd_ < 0 || eof_) return 0; long n; do { n = ::read(fd_, buf, bufSize); } while (n < 0 && errno == EINTR); if (n > 0) { nread = size_t(n); saveBytes(buf, nread); return 1; } if (n < 0) { int saveErrno = errno; releaseD(); (void)xclose(fd_); systemError(mgr, PosixStorageMessages::readSystemCall, saveErrno); fd_ = -1; } else { eof_ = 1; // n == 0, so end of file if (!mayRewind_) { releaseD(); if (xclose(fd_) < 0) systemError(mgr, PosixStorageMessages::closeSystemCall, errno); fd_ = -1; } } return 0;}void PosixStorageObject::willNotRewind(){ RewindStorageObject::willNotRewind(); if (eof_ && fd_ >= 0) { releaseD(); (void)xclose(fd_); fd_ = -1; }}Boolean PosixStorageObject::suspend(){ if (fd_ < 0 || suspended_) return 0; struct stat sb; if (fstat(fd_, &sb) < 0 || !S_ISREG(sb.st_mode)) return 0; suspendFailedMessage_ = 0; suspendPos_ = lseek(fd_, 0, SEEK_CUR); if (suspendPos_ == (off_t)-1) { suspendFailedMessage_ = &PosixStorageMessages::lseekSystemCall; suspendErrno_ = errno; } if (xclose(fd_) < 0 && !suspendFailedMessage_) { suspendFailedMessage_ = &PosixStorageMessages::closeSystemCall; suspendErrno_ = errno; } fd_ = -1; suspended_ = 1; releaseD(); return 1;}void PosixStorageObject::resume(Messenger &mgr){ ASSERT(suspended_); if (suspendFailedMessage_) { systemError(mgr, *suspendFailedMessage_, suspendErrno_); suspended_ = 0; return; } acquireD(); // suspended_ must be 1 until after acquireD() is called, // so that we don't try to suspend this one before it is resumed. suspended_ = 0; do { fd_ = openFile(cfilename_.data()); } while (fd_ < 0 && errno == EINTR); if (fd_ < 0) { releaseD(); systemError(mgr, PosixStorageMessages::openSystemCall, errno); return; } if (lseek(fd_, suspendPos_, SEEK_SET) < 0) { systemError(mgr, PosixStorageMessages::lseekSystemCall, errno); (void)xclose(fd_); fd_ = -1; releaseD(); }}#ifdef SP_STAT_BLKSIZEsize_t PosixBaseStorageObject::getBlockSize() const{ struct stat sb; long sz; if (fstat(fd_, &sb) < 0) return defaultBlockSize; if (!S_ISREG(sb.st_mode)) return defaultBlockSize; if ((unsigned long)sb.st_blksize > size_t(-1)) sz = size_t(-1); else sz = sb.st_blksize; return sz;}#else /* not SP_STAT_BLKSIZE */size_t PosixBaseStorageObject::getBlockSize() const{ return defaultBlockSize;}#endif /* not SP_STAT_BLKSIZE */void PosixStorageObject::systemError(Messenger &mgr, const MessageType2 &msg, int err){ ParentLocationMessenger(mgr).message(msg, StringMessageArg(filename_), ErrnoMessageArg(err));}class PosixFdStorageObject : public PosixBaseStorageObject {public: PosixFdStorageObject(int, Boolean mayRewind); Boolean read(char *buf, size_t bufSize, Messenger &mgr, size_t &nread); Boolean seek(off_t, Messenger &); enum { noError, readError, invalidNumberError, lseekError };private: int origFd_;};PosixFdStorageManager::PosixFdStorageManager(const char *type, const CharsetInfo *idCharset): IdStorageManager(idCharset), type_(type){}Boolean PosixFdStorageManager::inheritable() const{ return 0;}StorageObject *PosixFdStorageManager::makeStorageObject(const StringC &id, const StringC &, Boolean, Boolean mayRewind, Messenger &mgr, StringC &foundId){ int n = 0; size_t i; for (i = 0; i < id.size(); i++) { UnivChar ch; if (!idCharset()->descToUniv(id[i], ch)) break; if (ch < UnivCharsetDesc::zero || ch > UnivCharsetDesc::zero + 9) break; int digit = ch - UnivCharsetDesc::zero; // Allow the division to be done at compile-time. if (n > INT_MAX/10) break; n *= 10; if (n > INT_MAX - digit) break; n += digit; } if (i < id.size() || i == 0) { mgr.message(PosixStorageMessages::invalidNumber, StringMessageArg(id)); return 0; } foundId = id; // Could check access mode with fcntl(n, F_GETFL). return new PosixFdStorageObject(n, mayRewind);}PosixFdStorageObject::PosixFdStorageObject(int fd, Boolean mayRewind): PosixBaseStorageObject(fd, mayRewind), origFd_(fd){}const char *PosixFdStorageManager::type() const{ return type_;}Boolean PosixFdStorageObject::read(char *buf, size_t bufSize, Messenger &mgr, size_t &nread){ if (readSaved(buf, bufSize, nread)) return 1; if (fd_ < 0 || eof_) return 0; long n; do { n = ::read(fd_, buf, bufSize); } while (n < 0 && errno == EINTR); if (n > 0) { nread = size_t(n); saveBytes(buf, nread); return 1; } if (n < 0) { ParentLocationMessenger(mgr).message(PosixStorageMessages::fdRead, NumberMessageArg(fd_), ErrnoMessageArg(errno)); fd_ = -1; } else eof_ = 1; return 0;}Boolean PosixFdStorageObject::seek(off_t off, Messenger &mgr){ if (lseek(fd_, off, SEEK_SET) < 0) { ParentLocationMessenger(mgr).message(PosixStorageMessages::fdLseek, NumberMessageArg(fd_), ErrnoMessageArg(errno)); return 0; } else return 1;}#ifdef SP_NAMESPACE}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -