fs/io/FileOutputStream: use class FileDescriptor

This commit is contained in:
Max Kellermann 2015-03-03 22:18:38 +01:00
parent dd4beea44c
commit cd08e5c7da
2 changed files with 20 additions and 19 deletions

View File

@ -111,14 +111,14 @@ FileOutputStream::Cancel()
/** /**
* Open a file using Linux's O_TMPFILE for writing the given file. * Open a file using Linux's O_TMPFILE for writing the given file.
*/ */
static int static bool
OpenTempFile(Path path) OpenTempFile(FileDescriptor &fd, Path path)
{ {
const auto directory = path.GetDirectoryName(); const auto directory = path.GetDirectoryName();
if (directory.IsNull()) if (directory.IsNull())
return -1; return false;
return OpenFile(directory, O_TMPFILE|O_WRONLY, 0666); return fd.Open(directory.c_str(), O_TMPFILE|O_WRONLY, 0666);
} }
#endif /* HAVE_LINKAT */ #endif /* HAVE_LINKAT */
@ -128,15 +128,13 @@ FileOutputStream::FileOutputStream(Path _path, Error &error)
{ {
#ifdef HAVE_LINKAT #ifdef HAVE_LINKAT
/* try Linux's O_TMPFILE first */ /* try Linux's O_TMPFILE first */
fd = OpenTempFile(path); is_tmpfile = OpenTempFile(fd, path);
is_tmpfile = fd >= 0;
if (!is_tmpfile) { if (!is_tmpfile) {
#endif #endif
/* fall back to plain POSIX */ /* fall back to plain POSIX */
fd = OpenFile(path, if (!fd.Open(path.c_str(),
O_WRONLY|O_CREAT|O_TRUNC, O_WRONLY|O_CREAT|O_TRUNC,
0666); 0666))
if (fd < 0)
error.FormatErrno("Failed to create %s", path.c_str()); error.FormatErrno("Failed to create %s", path.c_str());
#ifdef HAVE_LINKAT #ifdef HAVE_LINKAT
} }
@ -148,7 +146,7 @@ FileOutputStream::Write(const void *data, size_t size, Error &error)
{ {
assert(IsDefined()); assert(IsDefined());
ssize_t nbytes = write(fd, data, size); ssize_t nbytes = fd.Write(data, size);
if (nbytes < 0) { if (nbytes < 0) {
error.FormatErrno("Failed to write to %s", path.c_str()); error.FormatErrno("Failed to write to %s", path.c_str());
return false; return false;
@ -172,18 +170,18 @@ FileOutputStream::Commit(Error &error)
/* hard-link the temporary file to the final path */ /* hard-link the temporary file to the final path */
char fd_path[64]; char fd_path[64];
snprintf(fd_path, sizeof(fd_path), "/proc/self/fd/%d", fd); snprintf(fd_path, sizeof(fd_path), "/proc/self/fd/%d",
fd.Get());
if (linkat(AT_FDCWD, fd_path, AT_FDCWD, path.c_str(), if (linkat(AT_FDCWD, fd_path, AT_FDCWD, path.c_str(),
AT_SYMLINK_FOLLOW) < 0) { AT_SYMLINK_FOLLOW) < 0) {
error.FormatErrno("Failed to commit %s", path.c_str()); error.FormatErrno("Failed to commit %s", path.c_str());
close(fd); fd.Close();
return false; return false;
} }
} }
#endif #endif
bool success = close(fd) == 0; bool success = fd.Close();
fd = -1;
if (!success) if (!success)
error.FormatErrno("Failed to commit %s", path.c_str()); error.FormatErrno("Failed to commit %s", path.c_str());
@ -195,8 +193,7 @@ FileOutputStream::Cancel()
{ {
assert(IsDefined()); assert(IsDefined());
close(fd); fd.Close();
fd = -1;
#ifdef HAVE_LINKAT #ifdef HAVE_LINKAT
if (!is_tmpfile) if (!is_tmpfile)

View File

@ -25,6 +25,10 @@
#include "fs/AllocatedPath.hxx" #include "fs/AllocatedPath.hxx"
#include "Compiler.h" #include "Compiler.h"
#ifndef WIN32
#include "system/FileDescriptor.hxx"
#endif
#include <assert.h> #include <assert.h>
#ifdef WIN32 #ifdef WIN32
@ -39,7 +43,7 @@ class FileOutputStream final : public OutputStream {
#ifdef WIN32 #ifdef WIN32
HANDLE handle; HANDLE handle;
#else #else
int fd; FileDescriptor fd;
#endif #endif
#ifdef HAVE_LINKAT #ifdef HAVE_LINKAT
@ -64,7 +68,7 @@ public:
#ifdef WIN32 #ifdef WIN32
return handle != INVALID_HANDLE_VALUE; return handle != INVALID_HANDLE_VALUE;
#else #else
return fd >= 0; return fd.IsDefined();
#endif #endif
} }