aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-12-10 10:52:22 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-12-10 10:52:22 +0000
commit52825b5bd9d658676b8e876da720469398877352 (patch)
tree36b688e334d53462194b99349c5c051077326250
parent77c2c5b6b7686bf8b5093dc12701bcb39019a10a (diff)
downloadpaludis-52825b5bd9d658676b8e876da720469398877352.tar.gz
paludis-52825b5bd9d658676b8e876da720469398877352.tar.xz
Do our own buffering for SafeOFStream
-rw-r--r--paludis/command_output_manager.cc4
-rw-r--r--paludis/environments/paludis/world.cc2
-rw-r--r--paludis/environments/portage/portage_environment.cc2
-rw-r--r--paludis/file_output_manager.cc2
-rw-r--r--paludis/ipc_output_manager.cc6
-rw-r--r--paludis/ndbam.cc2
-rw-r--r--paludis/ndbam_merger.cc2
-rw-r--r--paludis/repositories/e/e_repository.cc4
-rw-r--r--paludis/repositories/e/e_repository_news.cc4
-rw-r--r--paludis/repositories/e/ebuild_flat_metadata_cache.cc2
-rw-r--r--paludis/repositories/e/vdb_merger.cc2
-rw-r--r--paludis/repositories/e/vdb_repository.cc12
-rw-r--r--paludis/repositories/repository/repository_repository.cc2
-rw-r--r--paludis/repositories/unpackaged/installed_repository.cc8
-rw-r--r--paludis/repository_name_cache.cc6
-rw-r--r--paludis/set_file.cc4
-rw-r--r--paludis/sohooks_TEST.cc2
-rw-r--r--paludis/util/process.cc4
-rw-r--r--paludis/util/process_TEST.cc2
-rw-r--r--paludis/util/safe_ofstream.cc79
-rw-r--r--paludis/util/safe_ofstream.hh15
-rw-r--r--paludis/util/safe_ofstream_TEST.cc12
-rw-r--r--src/clients/accerso/accerso.cc2
-rw-r--r--src/clients/adjutrix/downgrade_check.cc2
-rw-r--r--src/clients/cave/cmd_execute_resolution.cc2
-rw-r--r--src/clients/cave/cmd_graph_jobs.cc2
-rw-r--r--src/clients/instruo/instruo.cc2
-rw-r--r--src/output/console_install_task.cc2
28 files changed, 126 insertions, 64 deletions
diff --git a/paludis/command_output_manager.cc b/paludis/command_output_manager.cc
index 19a0c77..34a14b9 100644
--- a/paludis/command_output_manager.cc
+++ b/paludis/command_output_manager.cc
@@ -99,7 +99,7 @@ CommandOutputManager::CommandOutputManager(const std::string & s, const std::str
if (0 != ::close(_imp->stdout_pipe->read_fd()))
throw CommandOutputManagerError("close stdout_pipe read_fd failed");
_imp->stdout_pipe->clear_read_fd();
- _imp->stdout_stream.reset(new SafeOFStream(_imp->stdout_pipe->write_fd()));
+ _imp->stdout_stream.reset(new SafeOFStream(_imp->stdout_pipe->write_fd(), false));
_imp->stderr_pipe.reset(new Pipe(true));
_imp->stderr_process.reset(new Process(ProcessCommand(_imp->stderr_command)));
@@ -109,7 +109,7 @@ CommandOutputManager::CommandOutputManager(const std::string & s, const std::str
if (0 != ::close(_imp->stderr_pipe->read_fd()))
throw CommandOutputManagerError("close stderr_pipe read_fd failed");
_imp->stderr_pipe->clear_read_fd();
- _imp->stderr_stream.reset(new SafeOFStream(_imp->stderr_pipe->write_fd()));
+ _imp->stderr_stream.reset(new SafeOFStream(_imp->stderr_pipe->write_fd(), false));
}
CommandOutputManager::~CommandOutputManager()
diff --git a/paludis/environments/paludis/world.cc b/paludis/environments/paludis/world.cc
index 79e865d..2ffd2d1 100644
--- a/paludis/environments/paludis/world.cc
+++ b/paludis/environments/paludis/world.cc
@@ -106,7 +106,7 @@ World::_add_string_to_world(const std::string & n) const
{
try
{
- SafeOFStream f(*_imp->maybe_world_file);
+ SafeOFStream f(*_imp->maybe_world_file, -1, true);
}
catch (const SafeOFStreamError & e)
{
diff --git a/paludis/environments/portage/portage_environment.cc b/paludis/environments/portage/portage_environment.cc
index 0c0510a..597640d 100644
--- a/paludis/environments/portage/portage_environment.cc
+++ b/paludis/environments/portage/portage_environment.cc
@@ -917,7 +917,7 @@ PortageEnvironment::_add_string_to_world(const std::string & s) const
{
try
{
- SafeOFStream f(_imp->world_file);
+ SafeOFStream f(_imp->world_file, -1, true);
}
catch (const SafeOFStreamError & e)
{
diff --git a/paludis/file_output_manager.cc b/paludis/file_output_manager.cc
index d7bab19..ce49109 100644
--- a/paludis/file_output_manager.cc
+++ b/paludis/file_output_manager.cc
@@ -51,7 +51,7 @@ namespace paludis
const std::string & s
) :
filename(o),
- stream(std::make_shared<SafeOFStream>(filename)),
+ stream(std::make_shared<SafeOFStream>(filename, -1, true)),
keep_on_success(k),
keep_on_empty(l),
summary_output_manager(m),
diff --git a/paludis/ipc_output_manager.cc b/paludis/ipc_output_manager.cc
index 2465df5..5477cc5 100644
--- a/paludis/ipc_output_manager.cc
+++ b/paludis/ipc_output_manager.cc
@@ -61,7 +61,7 @@ namespace paludis
std::shared_ptr<SafeOFStream> pipe_command_write_stream;
Imp(int r, int w) :
- pipe_command_write_stream(std::make_shared<SafeOFStream>(w))
+ pipe_command_write_stream(std::make_shared<SafeOFStream>(w, false))
{
*pipe_command_write_stream << "PING 1 GOAT" << '\0' << std::flush;
@@ -94,8 +94,8 @@ IPCOutputManager::IPCOutputManager(const int r, const int w, const CreateOutputM
throw InternalError(PALUDIS_HERE, "got response '" + response + "'");
int stdout_fd(destringify<int>(tokens[2])), stderr_fd(destringify<int>(tokens[3]));
- _imp->stdout_stream = std::make_shared<SafeOFStream>(stdout_fd);
- _imp->stderr_stream = std::make_shared<SafeOFStream>(stderr_fd);
+ _imp->stdout_stream = std::make_shared<SafeOFStream>(stdout_fd, false);
+ _imp->stderr_stream = std::make_shared<SafeOFStream>(stderr_fd, false);
if (0 != ::fcntl(stdout_fd, F_SETFD, FD_CLOEXEC))
throw InternalError(PALUDIS_HERE, "fcntl failed");
diff --git a/paludis/ndbam.cc b/paludis/ndbam.cc
index 7092def..4173c39 100644
--- a/paludis/ndbam.cc
+++ b/paludis/ndbam.cc
@@ -130,7 +130,7 @@ NDBAM::NDBAM(const FSPath & l,
(l / "indices" / "categories").mkdir(0755, { fspmkdo_ok_if_exists });
(l / "indices" / "packages").mkdir(0755, { fspmkdo_ok_if_exists });
(l / "data").mkdir(0755, { fspmkdo_ok_if_exists });
- SafeOFStream n(l / "ndbam.conf");
+ SafeOFStream n(l / "ndbam.conf", -1, true);
n << "ndbam_format = 1" << std::endl;
n << "repository_format = " << preferred_format << std::endl;
if (! n)
diff --git a/paludis/ndbam_merger.cc b/paludis/ndbam_merger.cc
index 3458cbf..4caa7dd 100644
--- a/paludis/ndbam_merger.cc
+++ b/paludis/ndbam_merger.cc
@@ -349,7 +349,7 @@ void
NDBAMMerger::merge()
{
display_override(">>> Merging to " + stringify(_imp->params.root()));
- _imp->contents_file = std::make_shared<SafeOFStream>(_imp->params.contents_file());
+ _imp->contents_file = std::make_shared<SafeOFStream>(_imp->params.contents_file(), -1, false);
FSMerger::merge();
}
diff --git a/paludis/repositories/e/e_repository.cc b/paludis/repositories/e/e_repository.cc
index 0663f57..cf1bfb9 100644
--- a/paludis/repositories/e/e_repository.cc
+++ b/paludis/repositories/e/e_repository.cc
@@ -1096,7 +1096,7 @@ ERepository::make_manifest(const QualifiedPackageName & qpn)
FSPath package_dir = _imp->layout->package_directory(qpn);
FSPath(package_dir / "Manifest").unlink();
- SafeOFStream manifest(FSPath(package_dir / "Manifest"));
+ SafeOFStream manifest(FSPath(package_dir / "Manifest"), -1, true);
if (! manifest)
throw ERepositoryConfigurationError("Couldn't open Manifest for writing.");
@@ -1999,7 +1999,7 @@ ERepository::merge(const MergeParams & m)
if (! has_category_named(m.package_id()->name().category()))
{
- SafeOFStream s(_imp->layout->categories_file(), O_CREAT | O_WRONLY | O_CLOEXEC | O_APPEND);
+ SafeOFStream s(_imp->layout->categories_file(), O_CREAT | O_WRONLY | O_CLOEXEC | O_APPEND, true);
s << m.package_id()->name().category() << std::endl;
}
}
diff --git a/paludis/repositories/e/e_repository_news.cc b/paludis/repositories/e/e_repository_news.cc
index fd17dc0..da7df1e 100644
--- a/paludis/repositories/e/e_repository_news.cc
+++ b/paludis/repositories/e/e_repository_news.cc
@@ -220,13 +220,13 @@ ERepositoryNews::update_news() const
{
Context update_context("When updating skip and unread files:");
- SafeOFStream s(_imp->skip_file, O_CREAT | O_WRONLY | O_APPEND);
+ SafeOFStream s(_imp->skip_file, O_CREAT | O_WRONLY | O_APPEND, false);
if (! s)
Log::get_instance()->message("e.news.skip_file.append_failure", ll_warning, lc_no_context) <<
"Cannot append to news skip file '" << _imp->skip_file <<
"', skipping news item '" << *d << "'";
- SafeOFStream t(_imp->unread_file, O_CREAT | O_WRONLY | O_APPEND);
+ SafeOFStream t(_imp->unread_file, O_CREAT | O_WRONLY | O_APPEND, false);
if (! t)
Log::get_instance()->message("e.news.unread_file.append_failure", ll_warning, lc_no_context) <<
"Cannot append to unread file '" << _imp->unread_file <<
diff --git a/paludis/repositories/e/ebuild_flat_metadata_cache.cc b/paludis/repositories/e/ebuild_flat_metadata_cache.cc
index 8b5dc7a..4c85e8a 100644
--- a/paludis/repositories/e/ebuild_flat_metadata_cache.cc
+++ b/paludis/repositories/e/ebuild_flat_metadata_cache.cc
@@ -881,7 +881,7 @@ EbuildFlatMetadataCache::save(const std::shared_ptr<const EbuildID> & id)
try
{
{
- SafeOFStream cache_file(_imp->filename);
+ SafeOFStream cache_file(_imp->filename, -1, true);
cache_file << cache.str();
}
_imp->filename.utime(Timestamp(_imp->ebuild_stat.mtim().seconds(), 0));
diff --git a/paludis/repositories/e/vdb_merger.cc b/paludis/repositories/e/vdb_merger.cc
index 492179b..fb315cd 100644
--- a/paludis/repositories/e/vdb_merger.cc
+++ b/paludis/repositories/e/vdb_merger.cc
@@ -275,7 +275,7 @@ void
VDBMerger::merge()
{
display_override(">>> Merging to " + stringify(_imp->params.root()));
- _imp->contents_file = std::make_shared<SafeOFStream>(_imp->params.contents_file());
+ _imp->contents_file = std::make_shared<SafeOFStream>(_imp->params.contents_file(), -1, false);
FSMerger::merge();
}
diff --git a/paludis/repositories/e/vdb_repository.cc b/paludis/repositories/e/vdb_repository.cc
index ec62c2f..7f4ae5f 100644
--- a/paludis/repositories/e/vdb_repository.cc
+++ b/paludis/repositories/e/vdb_repository.cc
@@ -799,7 +799,7 @@ VDBRepository::write_provides_cache() const
try
{
- SafeOFStream f(_imp->params.provides_cache());
+ SafeOFStream f(_imp->params.provides_cache(), -1, true);
f << "paludis-3" << std::endl;
f << name() << std::endl;
@@ -1292,7 +1292,7 @@ namespace
if (v.changed)
{
std::cout << " Rewriting " << f << std::endl;
- SafeOFStream ff(f);
+ SafeOFStream ff(f, -1, true);
ff << v.str.str() << std::endl;
}
@@ -1512,7 +1512,7 @@ VDBRepository::perform_updates()
std::shared_ptr<const EAPI> eapi(std::static_pointer_cast<const VDBID>(m->first)->eapi());
if (eapi->supported())
{
- SafeOFStream pf(to_dir / eapi->supported()->ebuild_environment_variables()->env_pf());
+ SafeOFStream pf(to_dir / eapi->supported()->ebuild_environment_variables()->env_pf(), -1, true);
pf << newpf << std::endl;
}
else
@@ -1522,7 +1522,7 @@ VDBRepository::perform_updates()
<< "', cannot update PF-equivalent VDB key for move";
}
- SafeOFStream category(to_dir / "CATEGORY");
+ SafeOFStream category(to_dir / "CATEGORY", -1, true);
category << m->second.category() << std::endl;
if (newpf != oldpf)
@@ -1546,7 +1546,7 @@ VDBRepository::perform_updates()
{
std::cout << " " << *m->first << " to " << m->second << std::endl;
- SafeOFStream f(m->first->fs_location_key()->value() / "SLOT");
+ SafeOFStream f(m->first->fs_location_key()->value() / "SLOT", -1, true);
f << m->second << std::endl;
}
}
@@ -1604,7 +1604,7 @@ VDBRepository::perform_updates()
if (! failed)
{
cache_dir.mkdir(0755, { fspmkdo_ok_if_exists });
- SafeOFStream cache_file_f(cache_file);
+ SafeOFStream cache_file_f(cache_file, -1, true);
for (std::map<FSPath, std::time_t, FSPathComparator>::const_iterator it(update_timestamps.begin()),
it_end(update_timestamps.end()); it_end != it; ++it)
cache_file_f << it->second << '\t' << it->first << std::endl;
diff --git a/paludis/repositories/repository/repository_repository.cc b/paludis/repositories/repository/repository_repository.cc
index fad366a..95949ca 100644
--- a/paludis/repositories/repository/repository_repository.cc
+++ b/paludis/repositories/repository/repository_repository.cc
@@ -473,7 +473,7 @@ RepositoryRepository::merge(const MergeParams & m)
std::string data((std::istreambuf_iterator<char>(config_template_input)), std::istreambuf_iterator<char>());
data = replace_vars(data, repo_sync, repo_format, repo_name);
- SafeOFStream config_filename_output(config_filename_file);
+ SafeOFStream config_filename_output(config_filename_file, -1, true);
config_filename_output << data;
}
diff --git a/paludis/repositories/unpackaged/installed_repository.cc b/paludis/repositories/unpackaged/installed_repository.cc
index 771613f..fd4350c 100644
--- a/paludis/repositories/unpackaged/installed_repository.cc
+++ b/paludis/repositories/unpackaged/installed_repository.cc
@@ -332,26 +332,26 @@ InstalledUnpackagedRepository::merge(const MergeParams & m)
target_ver_dir.mkdir(0755, { });
{
- SafeOFStream source_repository_file(target_ver_dir / "source_repository");
+ SafeOFStream source_repository_file(target_ver_dir / "source_repository", -1, true);
source_repository_file << m.package_id()->repository()->name() << std::endl;
}
if (m.package_id()->short_description_key())
{
- SafeOFStream description_file(target_ver_dir / "description");
+ SafeOFStream description_file(target_ver_dir / "description", -1, true);
description_file << m.package_id()->short_description_key()->value() << std::endl;
}
if (m.package_id()->build_dependencies_key())
{
- SafeOFStream build_dependencies_file(target_ver_dir / "build_dependencies");
+ SafeOFStream build_dependencies_file(target_ver_dir / "build_dependencies", -1, true);
StringifyFormatter f;
build_dependencies_file << m.package_id()->build_dependencies_key()->pretty_print_flat(f) << std::endl;
}
if (m.package_id()->run_dependencies_key())
{
- SafeOFStream run_dependencies_file(target_ver_dir / "run_dependencies");
+ SafeOFStream run_dependencies_file(target_ver_dir / "run_dependencies", -1, true);
StringifyFormatter f;
run_dependencies_file << m.package_id()->run_dependencies_key()->pretty_print_flat(f) << std::endl;
}
diff --git a/paludis/repository_name_cache.cc b/paludis/repository_name_cache.cc
index 27e76a8..fa17968 100644
--- a/paludis/repository_name_cache.cc
+++ b/paludis/repository_name_cache.cc
@@ -164,7 +164,7 @@ Imp<RepositoryNameCache>::update(const PackageNamePart & p, NameCacheMap::iterat
try
{
- SafeOFStream f(ff);
+ SafeOFStream f(ff, -1, true);
for (std::set<CategoryNamePart>::const_iterator it(r->second.begin()),
it_end(r->second.end()); it_end != it; ++it)
@@ -250,7 +250,7 @@ RepositoryNameCache::regenerate_cache() const
{
try
{
- SafeOFStream f(_imp->location / stringify(e->first));
+ SafeOFStream f(_imp->location / stringify(e->first), -1, true);
f << e->second;
}
catch (const SafeOFStreamError & ee)
@@ -263,7 +263,7 @@ RepositoryNameCache::regenerate_cache() const
try
{
- SafeOFStream f(_imp->location / "_VERSION_");;
+ SafeOFStream f(_imp->location / "_VERSION_", -1, true);;
f << "paludis-2" << std::endl;
f << _imp->repo->name() << std::endl;
}
diff --git a/paludis/set_file.cc b/paludis/set_file.cc
index b2bc0e3..f6a36bc 100644
--- a/paludis/set_file.cc
+++ b/paludis/set_file.cc
@@ -422,7 +422,7 @@ SimpleHandler::rewrite() const
try
{
- SafeOFStream f(_p.file_name());
+ SafeOFStream f(_p.file_name(), -1, true);
for (std::list<std::string>::const_iterator i(_lines.begin()), i_end(_lines.end()) ;
i != i_end ; ++i)
@@ -515,7 +515,7 @@ PaludisConfHandler::rewrite() const
try
{
- SafeOFStream f(_p.file_name());
+ SafeOFStream f(_p.file_name(), -1, true);
for (std::list<std::string>::const_iterator i(_lines.begin()), i_end(_lines.end()) ;
i != i_end ; ++i)
diff --git a/paludis/sohooks_TEST.cc b/paludis/sohooks_TEST.cc
index ff6d370..04ae277 100644
--- a/paludis/sohooks_TEST.cc
+++ b/paludis/sohooks_TEST.cc
@@ -48,7 +48,7 @@ namespace
HookResult
ordering_run(const Environment *, const Hook &)
{
- SafeOFStream f(FSPath("hooker_TEST_dir/ordering.out"), O_CREAT | O_WRONLY | O_APPEND);
+ SafeOFStream f(FSPath("hooker_TEST_dir/ordering.out"), O_CREAT | O_WRONLY | O_APPEND, false);
f << "sohook" << std::endl;
return make_named_values<HookResult>(n::max_exit_status() = 0, n::output() = "");
}
diff --git a/paludis/util/process.cc b/paludis/util/process.cc
index 8778d47..63366ef 100644
--- a/paludis/util/process.cc
+++ b/paludis/util/process.cc
@@ -531,7 +531,7 @@ Process::run()
thread->prefix_stdout = _imp->prefix_stdout;
if (! _imp->capture_stdout)
{
- thread->own_capture_stdout.reset(new SafeOFStream(STDOUT_FILENO));
+ thread->own_capture_stdout.reset(new SafeOFStream(STDOUT_FILENO, false));
_imp->capture_stdout = thread->own_capture_stdout.get();
}
}
@@ -541,7 +541,7 @@ Process::run()
thread->prefix_stderr = _imp->prefix_stderr;
if (! _imp->capture_stderr)
{
- thread->own_capture_stderr.reset(new SafeOFStream(STDERR_FILENO));
+ thread->own_capture_stderr.reset(new SafeOFStream(STDERR_FILENO, false));
_imp->capture_stderr = thread->own_capture_stderr.get();
}
}
diff --git a/paludis/util/process_TEST.cc b/paludis/util/process_TEST.cc
index 294d023..518cd0c 100644
--- a/paludis/util/process_TEST.cc
+++ b/paludis/util/process_TEST.cc
@@ -314,7 +314,7 @@ namespace test_cases
{
{
- SafeOFStream s(input_pipe->write_fd());
+ SafeOFStream s(input_pipe->write_fd(), true);
s << "backwards" << std::endl;
}
TEST_CHECK(0 == ::close(input_pipe->write_fd()));
diff --git a/paludis/util/safe_ofstream.cc b/paludis/util/safe_ofstream.cc
index 4ebc117..85d84a5 100644
--- a/paludis/util/safe_ofstream.cc
+++ b/paludis/util/safe_ofstream.cc
@@ -19,6 +19,7 @@
#include <paludis/util/safe_ofstream.hh>
#include <paludis/util/stringify.hh>
+#include <paludis/util/pimp-impl.hh>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -28,36 +29,86 @@
using namespace paludis;
-SafeOFStreamBuf::SafeOFStreamBuf(const int f) :
+namespace paludis
+{
+ template <>
+ struct Imp<SafeOFStreamBuf>
+ {
+ std::shared_ptr<std::string> buffered_text;
+ };
+}
+
+SafeOFStreamBuf::SafeOFStreamBuf(const int f, const bool buffer) :
+ Pimp<SafeOFStreamBuf>(),
fd(f)
{
+ if (buffer)
+ _imp->buffered_text = std::make_shared<std::string>();
+}
+
+SafeOFStreamBuf::~SafeOFStreamBuf()
+{
}
SafeOFStreamBuf::int_type
SafeOFStreamBuf::overflow(int_type c)
{
- if (c != traits_type::eof())
+ if (_imp->buffered_text)
+ {
+ _imp->buffered_text->append(1, c);
+ if (_imp->buffered_text->length() >= 4096)
+ write_buffered();
+ }
+ else
{
- char z = c;
- if (1 != write(fd, &z, 1))
- return traits_type::eof();
+ if (c != traits_type::eof())
+ {
+ char z = c;
+ if (1 != write(fd, &z, 1))
+ return traits_type::eof();
+ }
}
+
return c;
}
std::streamsize
SafeOFStreamBuf::xsputn(const char * s, std::streamsize num)
{
- return write(fd, s, num);
+ if (_imp->buffered_text)
+ {
+ _imp->buffered_text->append(s, num);
+ if (_imp->buffered_text->length() >= 4096)
+ write_buffered();
+
+ return num;
+ }
+ else
+ return write(fd, s, num);
+}
+
+void
+SafeOFStreamBuf::write_buffered()
+{
+ if (! _imp->buffered_text)
+ return;
+
+ while (! _imp->buffered_text->empty())
+ {
+ int n(::write(fd, _imp->buffered_text->data(), _imp->buffered_text->length()));
+ if (-1 == n)
+ throw SafeOFStreamError("Write to fd " + stringify(fd) + " failed");
+ _imp->buffered_text->erase(0, n);
+ }
}
-SafeOFStreamBase::SafeOFStreamBase(const int f) :
- buf(f)
+SafeOFStreamBase::SafeOFStreamBase(const int f, const bool b) :
+ buf(f, b)
{
}
-SafeOFStream::SafeOFStream(const int f) :
- SafeOFStreamBase(f),
+SafeOFStream::SafeOFStream(const int f, const bool buffer) :
+ SafeOFStreamBase(f, buffer),
std::ostream(&buf),
_close(false)
{
@@ -80,8 +131,8 @@ namespace
}
}
-SafeOFStream::SafeOFStream(const FSPath & p, const int open_flags) :
- SafeOFStreamBase(check_open_path(p, open_flags)),
+SafeOFStream::SafeOFStream(const FSPath & p, const int open_flags, const bool b) :
+ SafeOFStreamBase(check_open_path(p, open_flags), b),
std::ostream(&buf),
_close(true)
{
@@ -89,6 +140,8 @@ SafeOFStream::SafeOFStream(const FSPath & p, const int open_flags) :
SafeOFStream::~SafeOFStream()
{
+ buf.write_buffered();
+
if (_close)
::close(buf.fd);
@@ -101,3 +154,5 @@ SafeOFStreamError::SafeOFStreamError(const std::string & s) throw () :
{
}
+template class Pimp<SafeOFStreamBuf>;
+
diff --git a/paludis/util/safe_ofstream.hh b/paludis/util/safe_ofstream.hh
index 274ffe9..ace9c9b 100644
--- a/paludis/util/safe_ofstream.hh
+++ b/paludis/util/safe_ofstream.hh
@@ -23,6 +23,7 @@
#include <paludis/util/attributes.hh>
#include <paludis/util/exception.hh>
#include <paludis/util/fs_path-fwd.hh>
+#include <paludis/util/pimp.hh>
#include <ostream>
/** \file
@@ -48,6 +49,7 @@ namespace paludis
* \since 0.34.3
*/
class PALUDIS_VISIBLE SafeOFStreamBuf :
+ private Pimp<SafeOFStreamBuf>,
public std::streambuf
{
protected:
@@ -61,10 +63,13 @@ namespace paludis
///\name Basic operations
///\{
- SafeOFStreamBuf(const int f);
+ SafeOFStreamBuf(const int f, const bool buffer);
+ ~SafeOFStreamBuf();
///\}
+ void write_buffered();
+
/// Our file descriptor.
int fd;
};
@@ -85,7 +90,7 @@ namespace paludis
///\name Basic operations
///\{
- SafeOFStreamBase(const int fd);
+ SafeOFStreamBase(const int fd, const bool buffer);
///\}
};
@@ -108,8 +113,8 @@ namespace paludis
///\name Basic operations
///\{
- explicit SafeOFStream(const int fd);
- explicit SafeOFStream(const FSPath &, const int open_flags = -1);
+ SafeOFStream(const int fd, const bool buffer);
+ SafeOFStream(const FSPath &, const int open_flags, const bool buffer);
~SafeOFStream();
///\}
@@ -127,6 +132,8 @@ namespace paludis
public:
SafeOFStreamError(const std::string &) throw ();
};
+
+ extern template class Pimp<SafeOFStreamBuf>;
}
#endif
diff --git a/paludis/util/safe_ofstream_TEST.cc b/paludis/util/safe_ofstream_TEST.cc
index 05c1fb7..5bb5986 100644
--- a/paludis/util/safe_ofstream_TEST.cc
+++ b/paludis/util/safe_ofstream_TEST.cc
@@ -35,7 +35,7 @@ namespace test_cases
void run()
{
- SafeOFStream s(FSPath::cwd() / "safe_ofstream_TEST_dir" / "new");
+ SafeOFStream s(FSPath::cwd() / "safe_ofstream_TEST_dir" / "new", -1, false);
TEST_CHECK(s);
s << "foo";
TEST_CHECK(s);
@@ -53,7 +53,7 @@ namespace test_cases
void run()
{
- SafeOFStream s(FSPath::cwd() / "safe_ofstream_TEST_dir" / "existing");
+ SafeOFStream s(FSPath::cwd() / "safe_ofstream_TEST_dir" / "existing", -1, false);
TEST_CHECK(s);
s << "foo";
TEST_CHECK(s);
@@ -71,7 +71,7 @@ namespace test_cases
void run()
{
- SafeOFStream s(FSPath::cwd() / "safe_ofstream_TEST_dir" / "existing_sym");
+ SafeOFStream s(FSPath::cwd() / "safe_ofstream_TEST_dir" / "existing_sym", -1, false);
TEST_CHECK(s);
s << "foo";
TEST_CHECK(s);
@@ -89,7 +89,7 @@ namespace test_cases
void run()
{
- TEST_CHECK_THROWS(SafeOFStream(FSPath::cwd() / "safe_ofstream_TEST_dir" / "existing_dir"), SafeOFStreamError);
+ TEST_CHECK_THROWS(SafeOFStream(FSPath::cwd() / "safe_ofstream_TEST_dir" / "existing_dir", -1, false), SafeOFStreamError);
}
bool repeatable() const
@@ -104,7 +104,7 @@ namespace test_cases
void run()
{
- TEST_CHECK_THROWS(SafeOFStream(FSPath::cwd() / "safe_ofstream_TEST_dir" / "existing_perm"), SafeOFStreamError);
+ TEST_CHECK_THROWS(SafeOFStream(FSPath::cwd() / "safe_ofstream_TEST_dir" / "existing_perm", -1, false), SafeOFStreamError);
}
bool skip() const
@@ -127,7 +127,7 @@ namespace test_cases
bool threw(false);
try
{
- SafeOFStream s(FSPath("/dev/full"));
+ SafeOFStream s(FSPath("/dev/full"), -1, false);
TEST_CHECK(s);
s << "foo";
TEST_CHECK(! s);
diff --git a/src/clients/accerso/accerso.cc b/src/clients/accerso/accerso.cc
index 072aa68..c8e109c 100644
--- a/src/clients/accerso/accerso.cc
+++ b/src/clients/accerso/accerso.cc
@@ -209,7 +209,7 @@ main(int argc, char *argv[])
std::shared_ptr<SafeOFStream> outf;
if (CommandLine::get_instance()->a_report_file.specified())
- outf = std::make_shared<SafeOFStream>(FSPath(CommandLine::get_instance()->a_report_file.argument()));
+ outf = std::make_shared<SafeOFStream>(FSPath(CommandLine::get_instance()->a_report_file.argument()), -1, true);
std::ostream & out(outf ? *outf : cout);
diff --git a/src/clients/adjutrix/downgrade_check.cc b/src/clients/adjutrix/downgrade_check.cc
index 9ab34cd..aeb7dbd 100644
--- a/src/clients/adjutrix/downgrade_check.cc
+++ b/src/clients/adjutrix/downgrade_check.cc
@@ -151,7 +151,7 @@ do_build_downgrade_check_list(NoConfigEnvironment & env)
bool b(i);
env.set_accept_unstable(b);
std::cerr << "Generating " << (b ? "unstable" : "stable") << "..." << std::endl;
- SafeOFStream f(output_dir / ((b ? "unstable" : "stable") + std::string(".txt")));
+ SafeOFStream f(output_dir / ((b ? "unstable" : "stable") + std::string(".txt")), -1, true);
exit_status |= build_one_list(env, f);
}
diff --git a/src/clients/cave/cmd_execute_resolution.cc b/src/clients/cave/cmd_execute_resolution.cc
index a775bf5..195558f 100644
--- a/src/clients/cave/cmd_execute_resolution.cc
+++ b/src/clients/cave/cmd_execute_resolution.cc
@@ -193,7 +193,7 @@ namespace
));
cout << fuc(fs_writing_resume_file(), fv<'f'>(stringify(resume_file)));
- SafeOFStream stream(resume_file);
+ SafeOFStream stream(resume_file, -1, true);
Serialiser ser(stream);
resume_data.serialise(ser);
}
diff --git a/src/clients/cave/cmd_graph_jobs.cc b/src/clients/cave/cmd_graph_jobs.cc
index 1993782..39ad3da 100644
--- a/src/clients/cave/cmd_graph_jobs.cc
+++ b/src/clients/cave/cmd_graph_jobs.cc
@@ -248,7 +248,7 @@ GraphJobsCommand::run(
std::shared_ptr<SafeOFStream> stream_if_file;
if (! cmdline.graph_jobs_options.a_graph_jobs_basename.argument().empty())
- stream_if_file = std::make_shared<SafeOFStream>(FSPath(cmdline.graph_jobs_options.a_graph_jobs_basename.argument() + ".graphviz"));
+ stream_if_file = std::make_shared<SafeOFStream>(FSPath(cmdline.graph_jobs_options.a_graph_jobs_basename.argument() + ".graphviz"), -1, true);
int retcode(0);
diff --git a/src/clients/instruo/instruo.cc b/src/clients/instruo/instruo.cc
index 6c74b95..7b4d162 100644
--- a/src/clients/instruo/instruo.cc
+++ b/src/clients/instruo/instruo.cc
@@ -370,7 +370,7 @@ main(int argc, char *argv[])
std::shared_ptr<SafeOFStream> outf;
if (CommandLine::get_instance()->a_report_file.specified())
- outf = std::make_shared<SafeOFStream>(FSPath(CommandLine::get_instance()->a_report_file.argument()));
+ outf = std::make_shared<SafeOFStream>(FSPath(CommandLine::get_instance()->a_report_file.argument()), -1, true);
std::ostream & out(outf ? *outf : cout);
diff --git a/src/output/console_install_task.cc b/src/output/console_install_task.cc
index 6110e38..f1a53e8 100644
--- a/src/output/console_install_task.cc
+++ b/src/output/console_install_task.cc
@@ -1913,7 +1913,7 @@ ConsoleInstallTask::show_resume_command(const std::string & resume_command_templ
if (-1 != fd)
{
::fchmod(fd, 0644);
- SafeOFStream resume_command_file(fd);
+ SafeOFStream resume_command_file(fd, true);
resume_command_file << resume_command << endl;
if (resume_command_file)