Minor File interface changes.

These are intended to make the sample file writing easier.
This commit is contained in:
Scott Lamb 2016-01-06 23:38:46 -08:00
parent 7b45f48027
commit a46df2c2e5
3 changed files with 20 additions and 7 deletions

View File

@ -79,18 +79,23 @@ class RealFile : public File {
return 0; return 0;
} }
int Write(re2::StringPiece *data) final { int Sync() final { return (fsync(fd_) < 0) ? errno : 0; }
int Truncate(off_t length) final {
return (ftruncate(fd_, length) < 0) ? errno : 0;
}
int Write(re2::StringPiece data, size_t *bytes_written) final {
if (fd_ < 0) { if (fd_ < 0) {
return EBADF; return EBADF;
} }
ssize_t ret; ssize_t ret;
while ((ret = write(fd_, data->data(), data->size())) == -1 && while ((ret = write(fd_, data.data(), data.size())) == -1 && errno == EINTR)
errno == EINTR)
; ;
if (ret < 0) { if (ret < 0) {
return errno; return errno;
} }
data->remove_prefix(ret); *bytes_written = static_cast<size_t>(ret);
return 0; return 0;
} }

View File

@ -65,9 +65,15 @@ class File {
// Already closed is considered a success. // Already closed is considered a success.
virtual int Close() = 0; virtual int Close() = 0;
// fsync(), returning 0 on success or errno>0 on failure.
virtual int Sync() = 0;
// ftruncate(), returning 0 on success or errno>0 on failure.
virtual int Truncate(off_t length) = 0;
// Write to the file, returning 0 on success or errno>0 on failure. // Write to the file, returning 0 on success or errno>0 on failure.
// On success, data->remove_prefix will be called with the written bytes. // On success, |bytes_written| will be updated.
virtual int Write(re2::StringPiece *data) = 0; virtual int Write(re2::StringPiece data, size_t *bytes_written) = 0;
}; };
// Interface to the local filesystem. There's typically one per program, // Interface to the local filesystem. There's typically one per program,

View File

@ -109,8 +109,10 @@ void WriteFileOrDie(const std::string &path, re2::StringPiece contents) {
O_WRONLY | O_CREAT | O_TRUNC, 0600, &f); O_WRONLY | O_CREAT | O_TRUNC, 0600, &f);
CHECK_EQ(ret, 0) << "open " << path << ": " << strerror(ret); CHECK_EQ(ret, 0) << "open " << path << ": " << strerror(ret);
while (!contents.empty()) { while (!contents.empty()) {
ret = f->Write(&contents); size_t written;
ret = f->Write(contents, &written);
CHECK_EQ(ret, 0) << "write " << path << ": " << strerror(ret); CHECK_EQ(ret, 0) << "write " << path << ": " << strerror(ret);
contents.remove_prefix(written);
} }
ret = f->Close(); ret = f->Close();
CHECK_EQ(ret, 0) << "close " << path << ": " << strerror(ret); CHECK_EQ(ret, 0) << "close " << path << ": " << strerror(ret);