Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
mpd
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Иван Мажукин
mpd
Commits
cf23fd87
Commit
cf23fd87
authored
Jan 21, 2019
by
Max Kellermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fs/io/FileOutputStream: add constructor with directory fd
parent
dee88723
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
52 additions
and
8 deletions
+52
-8
FileOutputStream.cxx
src/fs/io/FileOutputStream.cxx
+43
-8
FileOutputStream.hxx
src/fs/io/FileOutputStream.hxx
+9
-0
No files found.
src/fs/io/FileOutputStream.cxx
View file @
cf23fd87
...
...
@@ -31,8 +31,27 @@
#include "system/Error.hxx"
#include "util/StringFormat.hxx"
#ifdef __linux__
#include <fcntl.h>
#endif
#ifdef __linux__
FileOutputStream
::
FileOutputStream
(
FileDescriptor
_directory_fd
,
Path
_path
,
Mode
_mode
)
:
path
(
_path
),
directory_fd
(
_directory_fd
),
mode
(
_mode
)
{
Open
();
}
#endif
FileOutputStream
::
FileOutputStream
(
Path
_path
,
Mode
_mode
)
:
path
(
_path
),
mode
(
_mode
)
:
path
(
_path
),
#ifdef __linux__
directory_fd
(
AT_FDCWD
),
#endif
mode
(
_mode
)
{
Open
();
}
...
...
@@ -155,8 +174,12 @@ FileOutputStream::Cancel() noexcept
* Open a file using Linux's O_TMPFILE for writing the given file.
*/
static
bool
OpenTempFile
(
FileDescriptor
&
fd
,
Path
path
)
OpenTempFile
(
FileDescriptor
directory_fd
,
FileDescriptor
&
fd
,
Path
path
)
{
if
(
directory_fd
!=
FileDescriptor
(
AT_FDCWD
))
return
fd
.
Open
(
directory_fd
,
"."
,
O_TMPFILE
|
O_WRONLY
,
0666
);
const
auto
directory
=
path
.
GetDirectoryName
();
if
(
directory
.
IsNull
())
return
false
;
...
...
@@ -171,11 +194,15 @@ FileOutputStream::OpenCreate(bool visible)
{
#ifdef HAVE_O_TMPFILE
/* try Linux's O_TMPFILE first */
is_tmpfile
=
!
visible
&&
OpenTempFile
(
fd
,
GetPath
());
is_tmpfile
=
!
visible
&&
OpenTempFile
(
directory_fd
,
fd
,
GetPath
());
if
(
!
is_tmpfile
)
{
#endif
/* fall back to plain POSIX */
if
(
!
fd
.
Open
(
GetPath
().
c_str
(),
if
(
!
fd
.
Open
(
#ifdef __linux__
directory_fd
,
#endif
GetPath
().
c_str
(),
O_WRONLY
|
O_CREAT
|
O_TRUNC
,
0666
))
throw
FormatErrno
(
"Failed to create %s"
,
...
...
@@ -194,7 +221,11 @@ FileOutputStream::OpenAppend(bool create)
if
(
create
)
flags
|=
O_CREAT
;
if
(
!
fd
.
Open
(
path
.
c_str
(),
flags
))
if
(
!
fd
.
Open
(
#ifdef __linux__
directory_fd
,
#endif
path
.
c_str
(),
flags
))
throw
FormatErrno
(
"Failed to append to %s"
,
path
.
c_str
());
}
...
...
@@ -225,12 +256,12 @@ FileOutputStream::Commit()
#ifdef HAVE_O_TMPFILE
if
(
is_tmpfile
)
{
unlink
(
GetPath
().
c_str
()
);
unlink
at
(
directory_fd
.
Get
(),
GetPath
().
c_str
(),
0
);
/* hard-link the temporary file to the final path */
if
(
linkat
(
AT_FDCWD
,
StringFormat
<
64
>
(
"/proc/self/fd/%d"
,
fd
.
Get
()),
AT_FDCWD
,
path
.
c_str
(),
directory_fd
.
Get
()
,
path
.
c_str
(),
AT_SYMLINK_FOLLOW
)
<
0
)
throw
FormatErrno
(
"Failed to commit %s"
,
path
.
c_str
());
...
...
@@ -259,7 +290,11 @@ FileOutputStream::Cancel() noexcept
#ifdef HAVE_O_TMPFILE
if
(
!
is_tmpfile
)
#endif
unlink
(
GetPath
().
c_str
());
#ifdef __linux__
unlinkat
(
directory_fd
.
Get
(),
GetPath
().
c_str
(),
0
);
#else
unlink
(
GetPath
().
c_str
());
#endif
break
;
case
Mode
:
:
CREATE_VISIBLE
:
...
...
src/fs/io/FileOutputStream.hxx
View file @
cf23fd87
...
...
@@ -59,6 +59,10 @@ class Path;
class
FileOutputStream
final
:
public
OutputStream
{
const
AllocatedPath
path
;
#ifdef __linux__
const
FileDescriptor
directory_fd
;
#endif
#ifdef _WIN32
HANDLE
handle
=
INVALID_HANDLE_VALUE
;
#else
...
...
@@ -108,6 +112,11 @@ private:
public
:
explicit
FileOutputStream
(
Path
_path
,
Mode
_mode
=
Mode
::
CREATE
);
#ifdef __linux__
FileOutputStream
(
FileDescriptor
_directory_fd
,
Path
_path
,
Mode
_mode
=
Mode
::
CREATE
);
#endif
~
FileOutputStream
()
noexcept
{
if
(
IsDefined
())
Cancel
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment