blob: a7da2faa13de2fad9848f834bae55c5ba247f2eb [file] [log] [blame]
// Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "image-burner/image_burner_utils.h"
#include <fcntl.h>
#include <stdio.h>
#include <base/logging.h>
#include <rootdev/rootdev.h>
namespace imageburn {
const int kFsyncRatio = 1024;
BurnWriter::BurnWriter() : file_(NULL),
writes_count_(0) {
}
BurnWriter::~BurnWriter() {
if (file_)
fclose(file_);
}
bool BurnWriter::Open(const char* path) {
if (file_)
Close();
DCHECK(!file_);
int fd = open(path, O_WRONLY);
if (fd >= 0)
file_ = fdopen(fd, "wb");
if (!file_) {
PLOG(ERROR) << "Couldn't open target path " << path;
return false;
} else {
LOG(INFO) << path << " opened";
return true;
}
}
bool BurnWriter::Close() {
if (file_) {
if (fclose(file_) != 0) {
PLOG(ERROR) << "Couldn't close target file";
return false;
} else {
LOG(INFO) << "Target file closed";
}
file_ = 0;
}
return true;
}
int BurnWriter::Write(char* data_block, int data_size) {
size_t written = fwrite(data_block, sizeof(char), data_size, file_);
if (written != static_cast<size_t>(data_size)) {
PLOG(ERROR) << "Error writing to target file";
return written;
}
if (!writes_count_ && fsync(fileno(file_))) {
PLOG(ERROR) << "Error syncing target file";
return -1;
}
writes_count_++;
if (writes_count_ == kFsyncRatio)
writes_count_ = 0;
return written;
}
BurnReader::BurnReader() : file_(NULL) {
}
BurnReader::~BurnReader() {
if (file_)
fclose(file_);
}
bool BurnReader::Open(const char* path) {
if (file_)
Close();
file_ = fopen(path, "rb");
if (!file_) {
PLOG(ERROR) << "Couldn't open source path " << path;
return false;
} else {
LOG(INFO) << path << " opened";
return true;
}
}
bool BurnReader::Close() {
if (file_) {
if (fclose(file_) != 0) {
PLOG(ERROR) << "Couldn't close source file";
return false;
} else {
LOG(INFO) << "Source file closed";
}
file_ = NULL;
}
return true;
}
int BurnReader::Read(char* data_block, int data_size) {
int read = fread(data_block, sizeof(char), data_size, file_);
if (read < 0)
PLOG(ERROR) << "Error reading from source file";
return read;
}
int64_t BurnReader::GetSize() {
int current = ftell(file_);
fseek(file_, 0, SEEK_END);
int64_t result = static_cast<int64_t>(ftell(file_));
fseek(file_, current, SEEK_SET);
return result;
}
bool BurnRootPathGetter::GetRootPath(std::string* path) {
char root_path[PATH_MAX];
if (rootdev(root_path, sizeof(root_path), true, true)) {
// Coult not get root path.
return false;
}
*path = root_path;
return true;
}
} // namespace imageburn