Doc. no. | N4080 |
Date: | 2014-06-20 |
Project: | File System TS |
Reply to: | Beman Dawes <bdawes at acm dot org> |
Revised 2014-06-20 at 09:06:18 UTC
Reference ISO/IEC TS 18822
Section: X 8.1 [path.generic] Status: Immediate Submitter: CH-4 Opened: 2014-01-20 Last modified: 2014-06-19
View all issues with Immediate status.
Discussion:
8.1 [path.generic] says: "The filename dot-dot is treated as a reference to the parent directory." So it must be specified what "/.." and "/../.." refer to.
Add a statement what the parent directory of the root directory is.
[2014-02-07, Beman Dawes suggests wording]
[ 2014-02-11 Issaquah: Implementation defined. See wiki notes for rationale. Beman to provide wording for review next meeting. ]
[ 22 May 2014 Beman provides wording, taken directly from POSIX. See pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_12 ]
Proposed resolution:
Change 8.1 [path.generic]:
The filename dot is treated as a reference to the current directory. The filename dot-dot is treated as a reference to the parent directory. What the filename dot-dot refers to relative to root-directory is implementation-defined. Specific filenames may have special meanings for a particular operating system.
Section: X 13.1 [directory_iterator.members] Status: Immediate Submitter: CH-13 Opened: 2014-01-20 Last modified: 2014-06-19
View all issues with Immediate status.
Discussion:
The behaviour of increment is underspecified: What happens if the implementation detects an endless loop (e.g. caused by links)? What happens with automounting and possible race conditions?
More information on this can be found here.
Suggested action:
Specify the required behaviour in these cases.
[2014-02-13 LWG/SG-3 Issaquah: STL will provide wording for next meeting for the endless loop case. The other cases are covered by existing wording in the front matter.]
[17 Jun 2014 At the request of the LWG, Beman provides wording for a note.]
Proposed resolution:
In 14 Class recursive_directory_iterator [class.rec.dir.itr], add:
[Note: If the directory structure being iterated over contains cycles then the end iterator may be unreachable. --end note]
Section: X 15.4 [fs.op.copy_file] Status: Immediate Submitter: CH-15 Opened: 2014-01-20 Last modified: 2014-06-19
View all issues with Immediate status.
Discussion:
Even if to and from are different paths, they may be equivalent.
Specify what happens if (options & copy_options::overwrite_existing) but from and to resolve to the same file.
[2014-02-09, Beman Dawes: Need advice on this issue:]
What do existing implentations do? Possible resolutions:[2014-02-13 LWG/SG-3 Issaquah: LWG/SG-3 decided to treat equivalence in this case as an error. Beman to provide wording.]
[2014-04-09 Beman provided wording as requested. The Effects were rewritten to increase clarity. Behavior remains unchanged except for treating equivalence as an error.]
[17 Jun 2014 Rapperswil LWG moves to Immediate. Jonathan Wakely will provide editorial changes to improve the presentation of bitmask values.]
Proposed resolution:
Change 15.4 [fs.op.copy_file]:Precondition: At most one constant from each
copy_options
option group ([enum.copy_options]) is present inoptions
.Effects:
Ifexists(to) &&
!(options & (copy_options::skip_existing | copy_options::overwrite_existing | copy_options::update_existing))
report a file already exists error as specified in Error reporting (7).
If!exists(to) || (options & copy_options::overwrite_existing) || ((options & copy_options::update_existing) && last_write_time(from) > last_write_time(to)) || !(options & (copy_options::skip_existing | copy_options::overwrite_existing | copy_options::update_existing))
copy the contents and attributes of the filefrom
resolves to the fileto
resolves to.Report a file already exists error as specified in Error reporting (7) if:
exists(to)
andequivalent(from, to)
, orexists(to)
and(options & (copy_options::skip_existing | copy_options::overwrite_existing | copy_options::update_existing)) == copy_options::none.
Otherwise copy the contents and attributes of the file
from
resolves to to the fileto
resolves to if:
!exists(to)
, orexists(to)
and(options & copy_options::overwrite_existing) != copy_options::none
, orexists(to)
and(options & copy_options::update_existing) != copy_options::none
andfrom
is more recent thanto
, determined as if by use of thelast_write_time
function.Otherwise no effects.
Returns:
true
if thefrom
file was copied, otherwisefalse
. The signature with argumentec
returnfalse
if an error occurs.Throws: As specified in Error reporting (7).
Complexity: At most one direct or indirect invocation of
status(to)
.
Section: X 15.14 [fs.op.file_size] Status: Immediate Submitter: FI-9 Opened: 2014-01-20 Last modified: 2014-06-19
View all issues with Immediate status.
Discussion:
"The signature with argument ec returns static_cast<uintmax_t>(-1) if an error occurs.", one would expect that both signatures return that if an error occurs?
Clarify the Returns clause, and apply the same for every function that returns an uintmax_t where applicable.
[2014-02-13 LWG/SG-3 Issaquah:]
Discussion when around in circles for a while, until someone suggested the reference to 15.15 was wrong, and that the issue applied to the previous function in the WP, 15.14 File size [fs.op.file_size]. The NB Comment makes much more sense if it applies to file_size(), so the chair was directed to change the reference from 15.15 [fs.op.hard_lk_ct] to 15.14 [fs.op.file_size]. The intent that file_size() is only meaningful for regular_files. Beman to strike the the static_cast, changing it to "Otherwise an error is reported.".Proposed resolution:
Change 15.14 [fs.op.file_size]:
uintmax_t file_size(const path& p); uintmax_t file_size(const path& p, error_code& ec) noexcept;
Returns: If
!exists(p)
an error is reported (7). Otherwise, the size in bytes of the file&&|| !is_regular_file(p)p
resolves to, determined as if by the value of the POSIXstat
structure memberst_size
obtained as if by POSIXstat()
.Otherwise,The signature with argumentstatic_cast<uintmax_t>(-1)
.ec
returnsstatic_cast<uintmax_t>(-1)
if an error occurs.Throws: As specified in Error reporting (7).
Section: X 6 [fs.filesystem.synopsis] Status: Immediate Submitter: P.J. Plauger Opened: 2014-01-30 Last modified: 2014-06-19
View other active issues in 6 [fs.filesystem.synopsis].
View all other issues in 6 [fs.filesystem.synopsis].
View all issues with Immediate status.
Discussion:
enum class directory_options has no summary.
Proposed resolution:
Change 6 [fs.filesystem.synopsis]:
enum class directory_options;{none,follow_directory_symlink,skip_permission_denied};
Add the following sub-section:
10.4 Enum class
directory_options
[enum.directory_options]The enum class type
directory_options
is a bitmask type (C++11 §17.5.2.1.3) that specifies bitmask constants used to identify directory traversal options.
Name Value Meaning none
0
(Default) Skip directory symlinks, permission denied is error. follow_directory_symlink
1
Follow rather than skip directory symlinks. skip_permission_denied
2
Skip directories that would otherwise result in permission denied errors.
Section: X 6 [fs.filesystem.synopsis] Status: Immediate Submitter: P.J. Plauger Opened: 2014-01-30 Last modified: 2014-06-19
View other active issues in 6 [fs.filesystem.synopsis].
View all other issues in 6 [fs.filesystem.synopsis].
View all issues with Immediate status.
Discussion:
directory_options::skip_permission_denied is not used.
[2014-04-13 Beman: skip_permissions_denied not being used is a symptom of a more serious problem; two directory_itorator constructors are missing directory_options arguments and a description of how they are used. Proposed wording provided.]
[17 Jun 2014 LWG requests two signatures rather than one with default argument. Beman updates wording.]
Proposed resolution:
Change 13 [class.directory_iterator]:
directory_iterator() noexcept; explicit directory_iterator(const path& p); directory_iterator(const path& p, directory_options options); directory_iterator(const path& p, error_code& ec) noexcept; directory_iterator(const path& p, directory_options options, error_code& ec) noexcept; directory_iterator(const directory_iterator&) = default; directory_iterator(directory_iterator&&) = default; ~directory_iterator();
Change 13.1 directory_iterator members [directory_iterator.members]:
explicit directory_iterator(const path& p); directory_iterator(const path& p, directory_options options); directory_iterator(const path& p, error_code& ec) noexcept; directory_iterator(const path& p, directory_options options, error_code& ec) noexcept;Effects: For the directory that
p
resolves to, constructs an iterator for the first element in a sequence ofdirectory_entry
elements representing the files in the directory, if any; otherwise the end iterator.However, if
options & directory_options::skip_permissions_denied != directory_options::none
and construction encounters an error indicating that permission to accessp
is denied, constructs the end iterator and does not report an error.
Change 14
Class recursive_directory_iterator
[class.rec.dir.itr]
:
explicit recursive_directory_iterator(const path& p,directory_options options = directory_options::none); recursive_directory_iterator(const path& p, directory_options options); recursive_directory_iterator(const path& p, directory_options options, error_code& ec) noexcept; recursive_directory_iterator(const path& p, error_code& ec) noexcept;
Change 14.1 recursive_directory_iterator members [rec.dir.itr.members]:
explicit recursive_directory_iterator(const path& p,directory_options options = directory_options::none); recursive_directory_iterator(const path& p, directory_options options); recursive_directory_iterator(const path& p, directory_options options, error_code& ec) noexcept; recursive_directory_iterator(const path& p, error_code& ec) noexcept;Effects: Constructs a iterator representing the first entry in the directory
p
resolves to, if any; otherwise, the end iterator.However, if
options & directory_options::skip_permissions_denied != directory_options::none
and construction encounters an error indicating that permission to accessp
is denied, constructs the end iterator and does not report an error.
Change 14.1 recursive_directory_iterator members [rec.dir.itr.members]:
recursive_directory_iterator& operator++(); recursive_directory_iterator& increment(error_code& ec);Requires:
*this != recursive_directory_iterator()
.Effects: As specified by C++11 § 24.1.1 Input iterators, except that:
- If there are no more entries at this depth, then if
depth()!= 0
iteration over the parent directory resumes; otherwise*this = recursive_directory_iterator()
.- Otherwise if
recursion_pending() && is_directory(this->status()) && (!is_symlink(this->symlink_status()) || (options() & directory_options::follow_directory_symlink) !=
then either directory0directory_options::none)(*this)->path()
is recursively iterated into or, ifoptions() & directory_options::skip_permissions_denied != directory_options::none
and an error occurs indicating that permission to access directory(*this)->path()
is denied, then directory(*this)->path()
is treated as an empty directory and no error is reported .
Section: X 10.2 [enum.copy_options] Status: Immediate Submitter: P.J. Plauger Opened: 2014-01-30 Last modified: 2014-06-19
View all other issues in 10.2 [enum.copy_options].
View all issues with Immediate status.
Discussion:
copy_options::copy_symlinks is not used (should test it before calling copy_symlinks in copy).
[20 May 2014 Beman Dawes provides proposed wording.]
Proposed resolution:
Change 15.3 Copy [fs.op.copy]:
If
is_symlink(f)
, then:
- If
options & copy_options::skip_symlinks
, then return. Missing != copy_options::none fixed by issue 59- Otherwise if
!exists(t) && (options & copy_options::copy_symlinks) != copy_options::none
, thencopy_symlink(from, to, options)
.- Otherwise report an error as specified in Error reporting (7) .
Section: X 15.2 [fs.op.canonical], X 15.11 [fs.op.current_path], X 15.27 [fs.op.read_symlink], X 15.36 [fs.op.system_complete], X 15.37 [fs.op.temp_dir_path], X 15.38 [fs.op.unique_path], X 8.4 [path.member] Status: Immediate Submitter: P.J. Plauger Opened: 2014-01-30 Last modified: 2014-06-19
View all issues with Immediate status.
Discussion:
all functions with error_code arguments should be noexcept (see canonical, current_path, read_symlink, system_complete, temp_directory_path, unique_path, plus member functions).
[2014-02-03: Stephan T. Lavavej comments:]
The declaration and definition of "recursive_directory_iterator& increment(error_code& ec);" should almost certainly be marked noexcept.
[2014-02-08: Daniel comments]
All functions that return a path value such as canonical, current_path, read_symlink, system_complete, temp_directory_path, unique_path, or any member function returning a path value or basic_string value might legally throw an exception, if the allocator of the underlying string complains about insufficient memory. This is an anti-pattern for noexcept, because the exception-specification includes the return statement of a function and given the fact that the language currently does declare RVO as an optional action, we cannot rely on it.
The Standard is currently very careful not to specify functions as noexcept, if this case can happen, see e.g. std::locale::name(). To the contrary, enforcing them to be noexcept, would cause a similar problem as the unconditional noexcept specifier of the value-returning kill_dependency as denoted by LWG 2236. Basically this requirement conflicts with the section "Adopted Guidelines", second bullet of N3279.[Beman Dawes 2014-02-27]
Issues 37, 38, 41, and 49 are concerned with signatures which should or should not be noexcept. I will provide unified proposed wording for these issues, possibly in a separate paper.[21 May 2014 Beman Dawes reviewed all functions with error_code&
arguments,
and provided proposed wording for the one case found where the above guidelines were not met.
This was the case previously identified by Stephan T. Lavavej.
]
Proposed resolution:
Change 14 Class recursive_directory_iterator [class.rec.dir.itr]:
recursive_directory_iterator& increment(error_code& ec) noexcept;
Change 14.1 recursive_directory_iterator members [rec.dir.itr.members]:
recursive_directory_iterator& increment(error_code& ec) noexcept;
Section: X 12 [class.directory_entry] Status: Immediate Submitter: P.J. Plauger Opened: 2014-01-30 Last modified: 2014-06-17
View other active issues in 12 [class.directory_entry].
View all other issues in 12 [class.directory_entry].
View all issues with Immediate status.
Discussion:
class directory_entry should retain operator const path&() from V2.
[2014-05-19 Beman Dawes supplied proposed wording.]
[2014-06-02 Beman Dawes provides rationale:]
This conversion operator was removed whenstatus()
andsymlink_status()
were added during the transition from V2 to V3 as it seemed a bit unusual to have a conversion operator for one of the several values held. Users complained as they had found the automatic conversion convenient in the most commondirectory_entry
use case.
[17 Jun 2014 Rapperswil LWG discusses in depth, accepts proposed wording.]
Proposed resolution:
Change 12 Class directory_entry [class.directory_entry]:
// observers const path& path() const noexcept; operator const path&() const noexcept; file_status status() const; file_status status(error_code& ec) const noexcept; file_status symlink_status() const; file_status symlink_status(error_code& ec) const noexcept;
Change 12.3 directory_entry observers [directory_entry.obs]:
const path& path() const noexcept; operator const path&() const noexcept;Returns:
m_path
Section: X 13 [class.directory_iterator], X 14 [class.rec.dir.itr] Status: Immediate Submitter: P.J. Plauger Opened: 2014-01-30 Last modified: 2014-06-19
View all other issues in 13 [class.directory_iterator].
View all issues with Immediate status.
Discussion:
class directory_iterator move construct/assign should be noexcept.
class recursive_directory_iterator move construct/assign should be noexcept.
[Beman Dawes 2014-02-27]
Issues 37, 38, 41, and 49 are concerned with signatures which should or should not be noexcept. I will provide unified proposed wording for these issues, possibly in a separate paper.[Daniel Krügler 2014-02-28]
directory_iterator begin(directory_iterator iter) noexcept; directory_iterator end(const directory_iterator&) noexcept;are noexcept, but we have no guarantee that at least the move-constructor is noexcept:
directory_iterator(const directory_iterator&) = default; directory_iterator(directory_iterator&&) = default;This means that either the above noexcept specifications are not warranted or that at least the move-constructor of directory_iterator is required to be noexcept. The same applies to recursive_directory_iterator.
[21 May 2014 Beman Dawes provided proposed resolution wording.]
[18 Jun 2014 "= default" removed per LWG discussion]
Proposed resolution:
Change 13 Class directory_iterator [class.directory_iterator]:
To 13.1 directory_iterator members [directory_iterator.members] add:directory_iterator(const directory_iterator& rhs)= default; directory_iterator(directory_iterator&& rhs) noexcept= default; ... directory_iterator& operator=(const directory_iterator& rhs)= default; directory_iterator& operator=(directory_iterator&& rhs) noexcept= default;
directory_iterator(const directory_iterator& rhs); directory_iterator(directory_iterator&& rhs) noexcept;Effects: Constructs an object of class
directory_iterator
.Postconditions:
*this
has the original value ofrhs
.directory_iterator& operator=(const directory_iterator& rhs); directory_iterator& operator=(directory_iterator&& rhs) noexcept;Effects: If
*this
andrhs
are the same object, the member has no effect.Postconditions:
Returns:*this
has the original value ofrhs
.*this
.
Change 14 Class recursive_directory_iterator [class.rec.dir.itr]:
To 14.1 recursive_directory_iterator members [rec.dir.itr.members] add:recursive_directory_iterator(const recursive_directory_iterator& rhs)= default; recursive_directory_iterator(recursive_directory_iterator&& rhs) noexcept= default; ... recursive_directory_iterator& operator=(const recursive_directory_iterator& rhs)= default; recursive_directory_iterator& operator=(recursive_directory_iterator&& rhs) noexcept= default;
recursive_directory_iterator(const recursive_directory_iterator& rhs);Effects: Constructs an object of class
recursive_directory_iterator
.Postconditions:
this->options() == rhs.options() && this->depth() == rhs.depth() && this->recursion_pending() == rhs.recursion_pending()
.recursive_directory_iterator(recursive_directory_iterator&& rhs) noexcept;Effects: Constructs an object of class
recursive_directory_iterator
.Postconditions:
this->options()
,this->depth()
, andthis->recursion_pending()
return the values thatrhs.options()
,rhs.depth()
, andrhs.recursion_pending()
, respectively, had before the function call.recursive_directory_iterator& operator=(const recursive_directory_iterator& rhs);Effects: If
*this
andrhs
are the same object, the member has no effect.Postconditions:
Returns:this->options() == rhs.options() && this->depth() == rhs.depth() && this->recursion_pending() == rhs.recursion_pending()
.*this
.recursive_directory_iterator& operator=(recursive_directory_iterator&& rhs) noexcept;Effects: If
*this
andrhs
are the same object, the member has no effect.Postconditions:
Returns:this->options()
,this->depth()
, andthis->recursion_pending()
return the values thatrhs.options()
,rhs.depth()
, andrhs.recursion_pending()
, respectively, had before the function call.*this
.
Section: X 15.7 [fs.op.create_directory] Status: Immediate Submitter: P.J. Plauger Opened: 2014-01-30 Last modified: 2014-06-19
View all issues with Immediate status.
Discussion:
create_directory should refer to perms::all instead of the Posix S_IRWXU|S_IRWXG|S_IRWXO.
[2014-02-28 Beman provided proposed wording.]
Proposed resolution:
Effects: Establishes the postcondition by attempting to create the
directory p
resolves to, as if by POSIX
mkdir()
with a second argument of S_IRWXU|S_IRWXG|S_IRWXO static_cast<int>(perms::all)
. Creation
failure because p
resolves to an existing directory shall not be
treated as an error.
Section: X 8.4.6 [path.native.obs] Status: Immediate Submitter: P.J. Plauger Opened: 2014-01-30 Last modified: 2014-06-19
View all issues with Immediate status.
Discussion:
path::template<class charT>string() should promise to convert by the same rules as u16string for string<char16_t>, etc. and one-for-one otherwise.
What if charT is signed char (or even float)? I don't see where that choice is disallowed, so we should either disallow it or make it be something that is quasi-sensible.[2014-02-08 Daniel comments]
There are two relevant places in the wording that seem to clarify what is required here:
Most importantly, 5 [fs.req] says:
Throughout this Technical Specification, char, wchar_t, char16_t, and char32_t are collectively called encoded character types.
Template parameters named charT shall be one of the encoded character types. […] [Note: Use of an encoded character type implies an associated encoding. Since signed char and unsigned char have no implied encoding, they are not included as permitted types. — end note]
For both the mentioned string function template and the specific non-template functions (such as u16string()) the same Remarks element exists, that refers to character conversion:
Conversion, if any, is performed as specified by 8.2 [path.cvt].
The first quote excludes arbitrary types such as signed char or float as feasible template arguments. The second quote makes clear that both the function template and the non-template functions do normatively refer to the same wording in 8.2 [path.cvt].
Based on this interpretation of the issue discussion I recommend resolving it as NAD. In addition to that recommendation I recommend to rename the current usage of the symbol charT in this technical specification, because 5 [fs.req] assigns a very special meaning to the constraints on charT types that does not exist to this extend in the rest of the standard library. A similar approach is used in Clause 22, where a special symbol C is used for constrained character types (C++11 §22.3.1.1.1 [locale.category]):A template formal parameter with name C represents the set of types containing char, wchar_t, and any other implementation-defined character types that satisfy the requirements for a character on which any of the iostream components can be instantiated.
[2014-02-28 Beman provides proposed resolution wording]
[18 Jun 2014 Beman changes proposed name from C to EcharT in response to tentative vote concern that C was insuficiently informative as a name.]
Proposed resolution:
In the entire Working Paper, except in the synopsis for path inserter and extractor and 8.6.1 path inserter and extractor [path.io],
change each instance of "charT
" to "EcharT
".
For example, in 5 [fs.req]:
Template parameters namedcharT
EcharT
shall be one of the encoded character types.
Section: X 8.4.1 [path.construct], X 12 [class.directory_entry] Status: Immediate Submitter: Stephan T. Lavavej Opened: 2014-02-03 Last modified: 2014-06-20
View all other issues in 8.4.1 [path.construct].
View all issues with Immediate status.
Discussion:
path's move ctor is marked noexcept, but it contains a basic_string. Similarly, directory_entry's move ctor is marked noexcept, but it contains a path. This is affected by LWG 2319 "basic_string's move constructor should not be noexcept".
[Beman Dawes 2014-02-27]
Issues 37, 38, 41, and 49 are concerned with signatures which should or should not be noexcept. I will provide unified proposed wording for these issues, possibly in a separate paper.[21 May 2014 Beman Dawes provides wording. See LWG 2319 for rationale. ]
[19 Jun 2014 LWG revises P/R to stay consistent with LWG issues.]
Proposed resolution:
Change 8 Class path [class.path]:Change 8.4.1 path constructors [path.construct]:path() noexcept;
Change 12 Class directory_entry [class.directory_entry]:path() noexcept;
directory_entry() noexcept = default;
Section: X 12 [class.directory_entry] Status: Immediate Submitter: Stephan T. Lavavej Opened: 2014-02-03 Last modified: 2014-06-20
View other active issues in 12 [class.directory_entry].
View all other issues in 12 [class.directory_entry].
View all issues with Immediate status.
Discussion:
12 [class.directory_entry] depicts directory_entry as having mutable m_status and m_symlink_status data members. This is problematic because of C++11's multithreading guarantees, which say that const member functions are simultaneously callable. As a result, mutable data members must be protected with synchronization, which was probably not considered during this design. The complexity and expense may be acceptable in directory_entry (since it can save filesystem queries, apparently) but it would be very very nice to have a note about this.
[2014-02-13 LWG/SG-3 discussed in Issaquah: Beman and STL will work together to better understand the concerns, and to formulate a solution. This is not a blocking issue for finishing the TS, but is a blocking issue for merging into the IS]
[2014-04-17 Beman provides proposed wording]
[2014-06-19 Rapperswil LWG decides to remove mutable private members. Beman provides wording.]
Proposed resolution:
Change 12 [class.directory_entry] as indicated:namespace std { namespace experimental { namespace filesystem { inline namespace v1 { class directory_entry { public: // constructors and destructor directory_entry() = default; directory_entry(const directory_entry&) = default; directory_entry(directory_entry&&) noexcept = default; explicit directory_entry(const path& p);explicit directory_entry(const path& p, file_status st=file_status(),file_status symlink_st=file_status());~directory_entry(); // modifiers directory_entry& operator=(const directory_entry&) = default; directory_entry& operator=(directory_entry&&) noexcept = default; void assign(const path& p);void assign(const path& p, file_status st=file_status(),file_status symlink_st=file_status()); void replace_filename(const path& p);void replace_filename(const path& p, file_status st=file_status(),file_status symlink_st=file_status()); // observers const path& path() const noexcept; file_status status() const; file_status status(error_code& ec) const noexcept; file_status symlink_status() const; file_status symlink_status(error_code& ec) const noexcept; bool operator< (const directory_entry& rhs) const noexcept; bool operator==(const directory_entry& rhs) const noexcept; bool operator!=(const directory_entry& rhs) const noexcept; bool operator<=(const directory_entry& rhs) const noexcept; bool operator> (const directory_entry& rhs) const noexcept; bool operator>=(const directory_entry& rhs) const noexcept; private: path m_path; // for exposition onlymutable file_status m_status; // for exposition only; stat()-likemutable file_status m_symlink_status; // for exposition only; lstat()-like}; } } } } // namespaces std::experimental::filesystem::v1
A directory_entry
object stores a path
object,
a .
file_status
object for non-symbolic link status, and a file_status
object for symbolic link status
The
file_status
objects act as value caches.
[Note: Becausestatus()
on a pathname may be a relatively expensive operation, some operating systems provide status information as a byproduct of directory iteration. Caching such status information can result in significant time savings. Cached and non-cached results may differ in the presence of file system races. —end note]
directory_entry
constructors
[directory_entry.cons]
Add the description of this constructor in its entirety:
explicit directory_entry(const path& p);
Effects: Constructs an object of typedirectory_entry
Postcondition:
path() == p
.
explicit directory_entry(const path& p, file_status st=file_status(),file_status symlink_st=file_status());
Strike the description
directory_entry
modifiers
[directory_entry.mods]
Add the description of this function in its entirety:
void assign(const path& p);
Postcondition:
path() == p
.
void assign(const path& p, file_status st=file_status(),file_status symlink_st=file_status());
Strike the description
Add the description of this function in its entirety:
void replace_filename(const path& p);
Postcondition:
path() == x.parent_path() / p
wherex
is the value ofpath()
before the function is called.
void replace_filename(const path& p, file_status st=file_status(),file_status symlink_st=file_status());
Strike the description
directory_entry
observers
[directory_entry.obs]
const path& path() const noexcept;
Returns:
m_path
file_status status() const; file_status status(error_code& ec) const noexcept;
Effects: As if,if (!status_known(m_status)) { if (status_known(m_symlink_status) && !is_symlink(m_symlink_status)) { m_status = m_symlink_status; } else { m_status = status(m_path[, ec]); } }Returns:
.
m_statusstatus(path()[, ec])Throws: As specified in Error reporting (7).
file_status symlink_status() const; file_status symlink_status(error_code& ec) const noexcept;
Effects: As if,if (!status_known(m_symlink_status)) { m_symlink_status = symlink_status(m_path[, ec]); }Returns:
.
m_symlink_statussymlink_status(path()[, ec])Throws: As specified in Error reporting (7).
bool operator==(const directory_entry& rhs) const noexcept;
Returns:
m_path == rhs.m_path
.
[Note: Status members do not participate in determining equality. — end note]
bool operator!=(const directory_entry& rhs) const noexcept;
Returns:
m_path != rhs.m_path
.
bool operator< (const directory_entry& rhs) const noexcept;
Returns:
m_path < rhs.m_path
.
bool operator<=(const directory_entry& rhs) const noexcept;
Returns:
m_path <= rhs.m_path
.
bool operator> (const directory_entry& rhs) const noexcept;
Returns:
m_path > rhs.m_path
.
bool operator>=(const directory_entry& rhs) const noexcept;
Returns:
m_path >= rhs.m_path
.
Section: X 5 [fs.req] Status: Immediate Submitter: Clark Nelson Opened: 2014-02-10 Last modified: 2014-06-20
View all issues with Immediate status.
Discussion:
SD-6: SG10 Feature Test Recommendations recommends that each library header provide feature test macros. For Technical Specifications, the TS itself should specify recommended names for the feature test macros.[Beman Dawes 2014-02-28 provided the proposed resolution. Thanks to Vicente J. Botet Escriba, Richard Smith, and Clark Nelson for suggestions and corrections.]
Proposed resolution:
Add a new sub-section:
5.2 Feature test macros [fs.req.macros]
This macro allows users to determine which version of this Technical Specification is supported by header
<experimental/filesystem>
.Header
<experimental/filesystem>
shall supply the following macro definition:#define __cpp_lib_experimental_filesystem 201406[Note: The value of macro
__cpp_lib_experimental_filesystem
is yyyymm where yyyy is the year and mm the month when the version of the Technical Specification was completed. — end note]
Section: X 2.1 [fs.conform.9945] Status: Immediate Submitter: LWG/SG-3 Opened: 2014-02-13 Last modified: 2014-06-19
View all other issues in 2.1 [fs.conform.9945].
View all issues with Immediate status.
Discussion:
§ 2.1 [fs.conform.9945] specifes "No diagnostic is required" for races. That prescription is used by the standard for the core language; it is not appropriate in library specifications. LWG/SG-3 wishes this be changed to undefined behavior.[Beman comments: The replacment wording is similar to that used by C++14 17.6.4.10]
Proposed resolution:
Change the following paragraph from § 2.1 [fs.conform.9945]Insert a new sub-section head before the modified paragraph:The behavior of functions described in this Technical Specification may differ from their specification in the presence of file system races ([fs.def.race]). No diagnostic is required.Behavior is undefined if calls to functions provided by this Technical Specification introduce a file system race (4.6 [fs.def.race]).
2.1 File system race behavior [fs.race.behavior]
Section: X 15.25 [fs.op.last_write_time] Status: Immediate Submitter: LWG/SG-3 Opened: 2014-02-13 Last modified: 2014-06-19
View all other issues in 15.25 [fs.op.last_write_time].
View all issues with Immediate status.
Discussion:
POSIX now says: "Since the utimbuf structure only contains time_t variables and is not accurate to fractions of a second, applications should use the utimensat() function instead of the obsolescent utime() function."
Suggested resolution: Rewrite the last_write_time setter description to utilize utimensat() or similar.
[20 May 2014 Beman Dawes supplies proposed wording. He comments:]
POSIX supplies two functions, futimens()
and utimensat()
,
as replacements for utime()
.
futimens()
is appropriate for the current TS.
utimensat()
will be appropriate for a future File System TS that adds the
functionality of the whole family of POSIX *at()
functions.
Proposed resolution:
Change 15.25 Last write time [fs.op.last_write_time]:
Effects: Sets the time of last data modification of the file resolved to by
p
tonew_time
, as if by POSIXstat()
followed by POSIXutime()
futimens()
.
Section: X 15.1 [fs.op.absolute] Status: Immediate Submitter: Daniel Krügler Opened: 2014-02-28 Last modified: 2014-06-19
View all issues with Immediate status.
Discussion:
The Throws element [fs.op.absolute] says:
"If
base.is_absolute()
is true, throws only if memory allocation fails."
We can strike:
"If
base.is_absolute()
is true," and the wording will still hold. Note that:
- None of the involved functions has requirements.
- In *every* case potentially memory allocation occurs, even for "
return p
", so this allocation can fail.
[02-03-2014 Beman Dawes comments and provides P/R]
The Throws element should follow the same form as similar Throws elements in the TS. There isn't enough special about this function to justify special wording and by referencing Error reporting (7) we ensure absolute() follows the overall policy for handling memory allocation failures.Proposed resolution:
[Change 15.1 [fs.op.absolute]:]
Throws:
IfAs specified in Error reporting (7).base.is_absolute()
is true, throws only if memory allocation fails.
Section: X 5 Requirements [fs.req] Status: Immediate Submitter: Daniel Kruegler Opened: 2014-05-19 Last modified: 2014-06-19
View all issues with Immediate status.
Discussion:
The SG3 WP refers in several places to a template parameter named "Allocator" but does not impose requirements on this type.
Proposed resolution:
Add the following to 5 Requirements [fs.req]:
Template parameters named
Allocator
shall meet the C++ Standard's library Allocator requirements (C++11 §17.6.3.5)