2010-05-12 03:42:16 +08:00
|
|
|
// -*- C++ -*-
|
|
|
|
//===------------------------- fstream ------------------------------------===//
|
|
|
|
//
|
2010-05-12 05:36:01 +08:00
|
|
|
// The LLVM Compiler Infrastructure
|
2010-05-12 03:42:16 +08:00
|
|
|
//
|
2010-11-17 06:09:02 +08:00
|
|
|
// This file is dual licensed under the MIT and the University of Illinois Open
|
|
|
|
// Source Licenses. See LICENSE.TXT for details.
|
2010-05-12 03:42:16 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#ifndef _LIBCPP_FSTREAM
|
|
|
|
#define _LIBCPP_FSTREAM
|
|
|
|
|
|
|
|
/*
|
|
|
|
fstream synopsis
|
|
|
|
|
|
|
|
template <class charT, class traits = char_traits<charT> >
|
|
|
|
class basic_filebuf
|
|
|
|
: public basic_streambuf<charT, traits>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
typedef charT char_type;
|
|
|
|
typedef traits traits_type;
|
|
|
|
typedef typename traits_type::int_type int_type;
|
|
|
|
typedef typename traits_type::pos_type pos_type;
|
|
|
|
typedef typename traits_type::off_type off_type;
|
|
|
|
|
|
|
|
// 27.9.1.2 Constructors/destructor:
|
|
|
|
basic_filebuf();
|
|
|
|
basic_filebuf(basic_filebuf&& rhs);
|
|
|
|
virtual ~basic_filebuf();
|
|
|
|
|
|
|
|
// 27.9.1.3 Assign/swap:
|
|
|
|
basic_filebuf& operator=(basic_filebuf&& rhs);
|
|
|
|
void swap(basic_filebuf& rhs);
|
|
|
|
|
|
|
|
// 27.9.1.4 Members:
|
|
|
|
bool is_open() const;
|
|
|
|
basic_filebuf* open(const char* s, ios_base::openmode mode);
|
|
|
|
basic_filebuf* open(const string& s, ios_base::openmode mode);
|
Implement <filesystem>
This patch implements the <filesystem> header and uses that
to provide <experimental/filesystem>.
Unlike other standard headers, the symbols needed for <filesystem>
have not yet been placed in libc++.so. Instead they live in the
new libc++fs.a library. Users of filesystem are required to link this
library. (Also note that libc++experimental no longer contains the
definition of <experimental/filesystem>, which now requires linking libc++fs).
The reason for keeping <filesystem> out of the dylib for now is that
it's still somewhat experimental, and the possibility of requiring an
ABI breaking change is very real. In the future the symbols will likely
be moved into the dylib, or the dylib will be made to link libc++fs automagically).
Note that moving the symbols out of libc++experimental may break user builds
until they update to -lc++fs. This should be OK, because the experimental
library provides no stability guarantees. However, I plan on looking into
ways we can force libc++experimental to automagically link libc++fs.
In order to use a single implementation and set of tests for <filesystem>, it
has been placed in a special `__fs` namespace. This namespace is inline in
C++17 onward, but not before that. As such implementation is available
in C++11 onward, but no filesystem namespace is present "directly", and
as such name conflicts shouldn't occur in C++11 or C++14.
llvm-svn: 338093
2018-07-27 11:07:09 +08:00
|
|
|
basic_filebuf* open(const filesystem::path& p, ios_base::openmode mode); // C++17
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_filebuf* close();
|
|
|
|
|
|
|
|
protected:
|
|
|
|
// 27.9.1.5 Overridden virtual functions:
|
|
|
|
virtual streamsize showmanyc();
|
|
|
|
virtual int_type underflow();
|
|
|
|
virtual int_type uflow();
|
|
|
|
virtual int_type pbackfail(int_type c = traits_type::eof());
|
|
|
|
virtual int_type overflow (int_type c = traits_type::eof());
|
|
|
|
virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* s, streamsize n);
|
|
|
|
virtual pos_type seekoff(off_type off, ios_base::seekdir way,
|
|
|
|
ios_base::openmode which = ios_base::in | ios_base::out);
|
|
|
|
virtual pos_type seekpos(pos_type sp,
|
|
|
|
ios_base::openmode which = ios_base::in | ios_base::out);
|
|
|
|
virtual int sync();
|
|
|
|
virtual void imbue(const locale& loc);
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class charT, class traits>
|
|
|
|
void
|
|
|
|
swap(basic_filebuf<charT, traits>& x, basic_filebuf<charT, traits>& y);
|
|
|
|
|
|
|
|
typedef basic_filebuf<char> filebuf;
|
|
|
|
typedef basic_filebuf<wchar_t> wfilebuf;
|
|
|
|
|
|
|
|
template <class charT, class traits = char_traits<charT> >
|
|
|
|
class basic_ifstream
|
|
|
|
: public basic_istream<charT,traits>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
typedef charT char_type;
|
|
|
|
typedef traits traits_type;
|
|
|
|
typedef typename traits_type::int_type int_type;
|
|
|
|
typedef typename traits_type::pos_type pos_type;
|
|
|
|
typedef typename traits_type::off_type off_type;
|
|
|
|
|
|
|
|
basic_ifstream();
|
|
|
|
explicit basic_ifstream(const char* s, ios_base::openmode mode = ios_base::in);
|
|
|
|
explicit basic_ifstream(const string& s, ios_base::openmode mode = ios_base::in);
|
Implement <filesystem>
This patch implements the <filesystem> header and uses that
to provide <experimental/filesystem>.
Unlike other standard headers, the symbols needed for <filesystem>
have not yet been placed in libc++.so. Instead they live in the
new libc++fs.a library. Users of filesystem are required to link this
library. (Also note that libc++experimental no longer contains the
definition of <experimental/filesystem>, which now requires linking libc++fs).
The reason for keeping <filesystem> out of the dylib for now is that
it's still somewhat experimental, and the possibility of requiring an
ABI breaking change is very real. In the future the symbols will likely
be moved into the dylib, or the dylib will be made to link libc++fs automagically).
Note that moving the symbols out of libc++experimental may break user builds
until they update to -lc++fs. This should be OK, because the experimental
library provides no stability guarantees. However, I plan on looking into
ways we can force libc++experimental to automagically link libc++fs.
In order to use a single implementation and set of tests for <filesystem>, it
has been placed in a special `__fs` namespace. This namespace is inline in
C++17 onward, but not before that. As such implementation is available
in C++11 onward, but no filesystem namespace is present "directly", and
as such name conflicts shouldn't occur in C++11 or C++14.
llvm-svn: 338093
2018-07-27 11:07:09 +08:00
|
|
|
explicit basic_ifstream(const filesystem::path& p,
|
|
|
|
ios_base::openmode mode = ios_base::in); // C++17
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_ifstream(basic_ifstream&& rhs);
|
|
|
|
|
|
|
|
basic_ifstream& operator=(basic_ifstream&& rhs);
|
|
|
|
void swap(basic_ifstream& rhs);
|
|
|
|
|
|
|
|
basic_filebuf<char_type, traits_type>* rdbuf() const;
|
|
|
|
bool is_open() const;
|
|
|
|
void open(const char* s, ios_base::openmode mode = ios_base::in);
|
|
|
|
void open(const string& s, ios_base::openmode mode = ios_base::in);
|
Implement <filesystem>
This patch implements the <filesystem> header and uses that
to provide <experimental/filesystem>.
Unlike other standard headers, the symbols needed for <filesystem>
have not yet been placed in libc++.so. Instead they live in the
new libc++fs.a library. Users of filesystem are required to link this
library. (Also note that libc++experimental no longer contains the
definition of <experimental/filesystem>, which now requires linking libc++fs).
The reason for keeping <filesystem> out of the dylib for now is that
it's still somewhat experimental, and the possibility of requiring an
ABI breaking change is very real. In the future the symbols will likely
be moved into the dylib, or the dylib will be made to link libc++fs automagically).
Note that moving the symbols out of libc++experimental may break user builds
until they update to -lc++fs. This should be OK, because the experimental
library provides no stability guarantees. However, I plan on looking into
ways we can force libc++experimental to automagically link libc++fs.
In order to use a single implementation and set of tests for <filesystem>, it
has been placed in a special `__fs` namespace. This namespace is inline in
C++17 onward, but not before that. As such implementation is available
in C++11 onward, but no filesystem namespace is present "directly", and
as such name conflicts shouldn't occur in C++11 or C++14.
llvm-svn: 338093
2018-07-27 11:07:09 +08:00
|
|
|
void open(const filesystem::path& s, ios_base::openmode mode = ios_base::in); // C++17
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
void close();
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class charT, class traits>
|
|
|
|
void
|
|
|
|
swap(basic_ifstream<charT, traits>& x, basic_ifstream<charT, traits>& y);
|
|
|
|
|
|
|
|
typedef basic_ifstream<char> ifstream;
|
|
|
|
typedef basic_ifstream<wchar_t> wifstream;
|
|
|
|
|
|
|
|
template <class charT, class traits = char_traits<charT> >
|
|
|
|
class basic_ofstream
|
|
|
|
: public basic_ostream<charT,traits>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
typedef charT char_type;
|
|
|
|
typedef traits traits_type;
|
|
|
|
typedef typename traits_type::int_type int_type;
|
|
|
|
typedef typename traits_type::pos_type pos_type;
|
|
|
|
typedef typename traits_type::off_type off_type;
|
|
|
|
|
|
|
|
basic_ofstream();
|
|
|
|
explicit basic_ofstream(const char* s, ios_base::openmode mode = ios_base::out);
|
|
|
|
explicit basic_ofstream(const string& s, ios_base::openmode mode = ios_base::out);
|
Implement <filesystem>
This patch implements the <filesystem> header and uses that
to provide <experimental/filesystem>.
Unlike other standard headers, the symbols needed for <filesystem>
have not yet been placed in libc++.so. Instead they live in the
new libc++fs.a library. Users of filesystem are required to link this
library. (Also note that libc++experimental no longer contains the
definition of <experimental/filesystem>, which now requires linking libc++fs).
The reason for keeping <filesystem> out of the dylib for now is that
it's still somewhat experimental, and the possibility of requiring an
ABI breaking change is very real. In the future the symbols will likely
be moved into the dylib, or the dylib will be made to link libc++fs automagically).
Note that moving the symbols out of libc++experimental may break user builds
until they update to -lc++fs. This should be OK, because the experimental
library provides no stability guarantees. However, I plan on looking into
ways we can force libc++experimental to automagically link libc++fs.
In order to use a single implementation and set of tests for <filesystem>, it
has been placed in a special `__fs` namespace. This namespace is inline in
C++17 onward, but not before that. As such implementation is available
in C++11 onward, but no filesystem namespace is present "directly", and
as such name conflicts shouldn't occur in C++11 or C++14.
llvm-svn: 338093
2018-07-27 11:07:09 +08:00
|
|
|
explicit basic_ofstream(const filesystem::path& p,
|
|
|
|
ios_base::openmode mode = ios_base::out); // C++17
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_ofstream(basic_ofstream&& rhs);
|
|
|
|
|
|
|
|
basic_ofstream& operator=(basic_ofstream&& rhs);
|
|
|
|
void swap(basic_ofstream& rhs);
|
|
|
|
|
|
|
|
basic_filebuf<char_type, traits_type>* rdbuf() const;
|
|
|
|
bool is_open() const;
|
|
|
|
void open(const char* s, ios_base::openmode mode = ios_base::out);
|
|
|
|
void open(const string& s, ios_base::openmode mode = ios_base::out);
|
Implement <filesystem>
This patch implements the <filesystem> header and uses that
to provide <experimental/filesystem>.
Unlike other standard headers, the symbols needed for <filesystem>
have not yet been placed in libc++.so. Instead they live in the
new libc++fs.a library. Users of filesystem are required to link this
library. (Also note that libc++experimental no longer contains the
definition of <experimental/filesystem>, which now requires linking libc++fs).
The reason for keeping <filesystem> out of the dylib for now is that
it's still somewhat experimental, and the possibility of requiring an
ABI breaking change is very real. In the future the symbols will likely
be moved into the dylib, or the dylib will be made to link libc++fs automagically).
Note that moving the symbols out of libc++experimental may break user builds
until they update to -lc++fs. This should be OK, because the experimental
library provides no stability guarantees. However, I plan on looking into
ways we can force libc++experimental to automagically link libc++fs.
In order to use a single implementation and set of tests for <filesystem>, it
has been placed in a special `__fs` namespace. This namespace is inline in
C++17 onward, but not before that. As such implementation is available
in C++11 onward, but no filesystem namespace is present "directly", and
as such name conflicts shouldn't occur in C++11 or C++14.
llvm-svn: 338093
2018-07-27 11:07:09 +08:00
|
|
|
void open(const filesystem::path& p,
|
|
|
|
ios_base::openmode mode = ios_base::out); // C++17
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
void close();
|
|
|
|
};
|
|
|
|
|
2010-08-22 08:02:43 +08:00
|
|
|
template <class charT, class traits>
|
2010-05-12 03:42:16 +08:00
|
|
|
void
|
|
|
|
swap(basic_ofstream<charT, traits>& x, basic_ofstream<charT, traits>& y);
|
|
|
|
|
|
|
|
typedef basic_ofstream<char> ofstream;
|
|
|
|
typedef basic_ofstream<wchar_t> wofstream;
|
|
|
|
|
|
|
|
template <class charT, class traits=char_traits<charT> >
|
|
|
|
class basic_fstream
|
|
|
|
: public basic_iostream<charT,traits>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
typedef charT char_type;
|
|
|
|
typedef traits traits_type;
|
|
|
|
typedef typename traits_type::int_type int_type;
|
|
|
|
typedef typename traits_type::pos_type pos_type;
|
|
|
|
typedef typename traits_type::off_type off_type;
|
|
|
|
|
|
|
|
basic_fstream();
|
|
|
|
explicit basic_fstream(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out);
|
|
|
|
explicit basic_fstream(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out);
|
Implement <filesystem>
This patch implements the <filesystem> header and uses that
to provide <experimental/filesystem>.
Unlike other standard headers, the symbols needed for <filesystem>
have not yet been placed in libc++.so. Instead they live in the
new libc++fs.a library. Users of filesystem are required to link this
library. (Also note that libc++experimental no longer contains the
definition of <experimental/filesystem>, which now requires linking libc++fs).
The reason for keeping <filesystem> out of the dylib for now is that
it's still somewhat experimental, and the possibility of requiring an
ABI breaking change is very real. In the future the symbols will likely
be moved into the dylib, or the dylib will be made to link libc++fs automagically).
Note that moving the symbols out of libc++experimental may break user builds
until they update to -lc++fs. This should be OK, because the experimental
library provides no stability guarantees. However, I plan on looking into
ways we can force libc++experimental to automagically link libc++fs.
In order to use a single implementation and set of tests for <filesystem>, it
has been placed in a special `__fs` namespace. This namespace is inline in
C++17 onward, but not before that. As such implementation is available
in C++11 onward, but no filesystem namespace is present "directly", and
as such name conflicts shouldn't occur in C++11 or C++14.
llvm-svn: 338093
2018-07-27 11:07:09 +08:00
|
|
|
explicit basic_fstream(const filesystem::path& p,
|
|
|
|
ios_base::openmode mode = ios_base::in|ios_base::out); C++17
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_fstream(basic_fstream&& rhs);
|
|
|
|
|
|
|
|
basic_fstream& operator=(basic_fstream&& rhs);
|
|
|
|
void swap(basic_fstream& rhs);
|
|
|
|
|
|
|
|
basic_filebuf<char_type, traits_type>* rdbuf() const;
|
|
|
|
bool is_open() const;
|
|
|
|
void open(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out);
|
|
|
|
void open(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out);
|
Implement <filesystem>
This patch implements the <filesystem> header and uses that
to provide <experimental/filesystem>.
Unlike other standard headers, the symbols needed for <filesystem>
have not yet been placed in libc++.so. Instead they live in the
new libc++fs.a library. Users of filesystem are required to link this
library. (Also note that libc++experimental no longer contains the
definition of <experimental/filesystem>, which now requires linking libc++fs).
The reason for keeping <filesystem> out of the dylib for now is that
it's still somewhat experimental, and the possibility of requiring an
ABI breaking change is very real. In the future the symbols will likely
be moved into the dylib, or the dylib will be made to link libc++fs automagically).
Note that moving the symbols out of libc++experimental may break user builds
until they update to -lc++fs. This should be OK, because the experimental
library provides no stability guarantees. However, I plan on looking into
ways we can force libc++experimental to automagically link libc++fs.
In order to use a single implementation and set of tests for <filesystem>, it
has been placed in a special `__fs` namespace. This namespace is inline in
C++17 onward, but not before that. As such implementation is available
in C++11 onward, but no filesystem namespace is present "directly", and
as such name conflicts shouldn't occur in C++11 or C++14.
llvm-svn: 338093
2018-07-27 11:07:09 +08:00
|
|
|
void open(const filesystem::path& s,
|
|
|
|
ios_base::openmode mode = ios_base::in|ios_base::out); // C++17
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
void close();
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class charT, class traits>
|
|
|
|
void swap(basic_fstream<charT, traits>& x, basic_fstream<charT, traits>& y);
|
|
|
|
|
|
|
|
typedef basic_fstream<char> fstream;
|
|
|
|
typedef basic_fstream<wchar_t> wfstream;
|
|
|
|
|
|
|
|
} // std
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <__config>
|
|
|
|
#include <ostream>
|
|
|
|
#include <istream>
|
|
|
|
#include <__locale>
|
|
|
|
#include <cstdio>
|
2018-07-22 10:00:53 +08:00
|
|
|
#include <cstdlib>
|
Implement <filesystem>
This patch implements the <filesystem> header and uses that
to provide <experimental/filesystem>.
Unlike other standard headers, the symbols needed for <filesystem>
have not yet been placed in libc++.so. Instead they live in the
new libc++fs.a library. Users of filesystem are required to link this
library. (Also note that libc++experimental no longer contains the
definition of <experimental/filesystem>, which now requires linking libc++fs).
The reason for keeping <filesystem> out of the dylib for now is that
it's still somewhat experimental, and the possibility of requiring an
ABI breaking change is very real. In the future the symbols will likely
be moved into the dylib, or the dylib will be made to link libc++fs automagically).
Note that moving the symbols out of libc++experimental may break user builds
until they update to -lc++fs. This should be OK, because the experimental
library provides no stability guarantees. However, I plan on looking into
ways we can force libc++experimental to automagically link libc++fs.
In order to use a single implementation and set of tests for <filesystem>, it
has been placed in a special `__fs` namespace. This namespace is inline in
C++17 onward, but not before that. As such implementation is available
in C++11 onward, but no filesystem namespace is present "directly", and
as such name conflicts shouldn't occur in C++11 or C++14.
llvm-svn: 338093
2018-07-27 11:07:09 +08:00
|
|
|
#include <filesystem>
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2011-10-18 04:05:10 +08:00
|
|
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
2010-05-12 03:42:16 +08:00
|
|
|
#pragma GCC system_header
|
2011-10-18 04:05:10 +08:00
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2017-06-01 06:07:49 +08:00
|
|
|
_LIBCPP_PUSH_MACROS
|
|
|
|
#include <__undef_macros>
|
|
|
|
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
_LIBCPP_BEGIN_NAMESPACE_STD
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
2017-01-05 07:56:00 +08:00
|
|
|
class _LIBCPP_TEMPLATE_VIS basic_filebuf
|
2010-05-12 03:42:16 +08:00
|
|
|
: public basic_streambuf<_CharT, _Traits>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
typedef _CharT char_type;
|
|
|
|
typedef _Traits traits_type;
|
|
|
|
typedef typename traits_type::int_type int_type;
|
|
|
|
typedef typename traits_type::pos_type pos_type;
|
|
|
|
typedef typename traits_type::off_type off_type;
|
|
|
|
typedef typename traits_type::state_type state_type;
|
|
|
|
|
|
|
|
// 27.9.1.2 Constructors/destructor:
|
|
|
|
basic_filebuf();
|
2017-04-19 07:38:41 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_filebuf(basic_filebuf&& __rhs);
|
|
|
|
#endif
|
|
|
|
virtual ~basic_filebuf();
|
|
|
|
|
|
|
|
// 27.9.1.3 Assign/swap:
|
2017-04-19 07:38:41 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2016-04-22 09:04:55 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_filebuf& operator=(basic_filebuf&& __rhs);
|
|
|
|
#endif
|
|
|
|
void swap(basic_filebuf& __rhs);
|
|
|
|
|
|
|
|
// 27.9.1.4 Members:
|
2016-04-22 09:04:55 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
bool is_open() const;
|
Add option to disable access to the global filesystem namespace.
Systems like FreeBSD's Capsicum and Nuxi CloudABI apply the concept of
capability-based security on the way processes can interact with the
filesystem API. It is no longer possible to interact with the VFS
through calls like open(), unlink(), rename(), etc. Instead, processes
are only allowed to interact with files and directories to which they
have been granted access. The *at() functions can be used for this
purpose.
This change adds a new config switch called
_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE. If set, all functionality
that requires the global filesystem namespace will be disabled. More
concretely:
- fstream's open() function will be removed.
- cstdio will no longer pull in fopen(), rename(), etc.
- The test suite's get_temp_file_name() will be removed. This will cause
all tests that use the global filesystem namespace to break, but will
at least make all the other tests run (as get_temp_file_name will not
build anyway).
It is important to mention that this change will make fstream rather
useless on those systems for now. Still, I'd rather not have fstream
disabled entirely, as it is of course possible to come up with an
extension for fstream that would allow access to local filesystem
namespaces (e.g., by adding an openat() member function).
Differential revision: http://reviews.llvm.org/D8194
Reviewed by: jroelofs (thanks!)
llvm-svn: 232049
2015-03-12 23:44:39 +08:00
|
|
|
#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_filebuf* open(const char* __s, ios_base::openmode __mode);
|
2018-01-23 10:07:27 +08:00
|
|
|
#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
|
|
|
|
basic_filebuf* open(const wchar_t* __s, ios_base::openmode __mode);
|
|
|
|
#endif
|
2016-04-22 09:04:55 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_filebuf* open(const string& __s, ios_base::openmode __mode);
|
2018-07-22 10:00:53 +08:00
|
|
|
|
Implement <filesystem>
This patch implements the <filesystem> header and uses that
to provide <experimental/filesystem>.
Unlike other standard headers, the symbols needed for <filesystem>
have not yet been placed in libc++.so. Instead they live in the
new libc++fs.a library. Users of filesystem are required to link this
library. (Also note that libc++experimental no longer contains the
definition of <experimental/filesystem>, which now requires linking libc++fs).
The reason for keeping <filesystem> out of the dylib for now is that
it's still somewhat experimental, and the possibility of requiring an
ABI breaking change is very real. In the future the symbols will likely
be moved into the dylib, or the dylib will be made to link libc++fs automagically).
Note that moving the symbols out of libc++experimental may break user builds
until they update to -lc++fs. This should be OK, because the experimental
library provides no stability guarantees. However, I plan on looking into
ways we can force libc++experimental to automagically link libc++fs.
In order to use a single implementation and set of tests for <filesystem>, it
has been placed in a special `__fs` namespace. This namespace is inline in
C++17 onward, but not before that. As such implementation is available
in C++11 onward, but no filesystem namespace is present "directly", and
as such name conflicts shouldn't occur in C++11 or C++14.
llvm-svn: 338093
2018-07-27 11:07:09 +08:00
|
|
|
#if _LIBCPP_STD_VER >= 17
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
basic_filebuf* open(const _VSTD_FS::path& __p, ios_base::openmode __mode) {
|
|
|
|
return open(__p.c_str(), __mode);
|
|
|
|
}
|
|
|
|
#endif
|
2018-07-22 10:00:53 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
basic_filebuf* __open(int __fd, ios_base::openmode __mode);
|
Add option to disable access to the global filesystem namespace.
Systems like FreeBSD's Capsicum and Nuxi CloudABI apply the concept of
capability-based security on the way processes can interact with the
filesystem API. It is no longer possible to interact with the VFS
through calls like open(), unlink(), rename(), etc. Instead, processes
are only allowed to interact with files and directories to which they
have been granted access. The *at() functions can be used for this
purpose.
This change adds a new config switch called
_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE. If set, all functionality
that requires the global filesystem namespace will be disabled. More
concretely:
- fstream's open() function will be removed.
- cstdio will no longer pull in fopen(), rename(), etc.
- The test suite's get_temp_file_name() will be removed. This will cause
all tests that use the global filesystem namespace to break, but will
at least make all the other tests run (as get_temp_file_name will not
build anyway).
It is important to mention that this change will make fstream rather
useless on those systems for now. Still, I'd rather not have fstream
disabled entirely, as it is of course possible to come up with an
extension for fstream that would allow access to local filesystem
namespaces (e.g., by adding an openat() member function).
Differential revision: http://reviews.llvm.org/D8194
Reviewed by: jroelofs (thanks!)
llvm-svn: 232049
2015-03-12 23:44:39 +08:00
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_filebuf* close();
|
|
|
|
|
2018-07-22 10:00:53 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
inline static const char*
|
|
|
|
__make_mdstring(ios_base::openmode __mode) _NOEXCEPT;
|
|
|
|
|
|
|
|
protected:
|
2010-05-12 03:42:16 +08:00
|
|
|
// 27.9.1.5 Overridden virtual functions:
|
|
|
|
virtual int_type underflow();
|
|
|
|
virtual int_type pbackfail(int_type __c = traits_type::eof());
|
|
|
|
virtual int_type overflow (int_type __c = traits_type::eof());
|
|
|
|
virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* __s, streamsize __n);
|
|
|
|
virtual pos_type seekoff(off_type __off, ios_base::seekdir __way,
|
|
|
|
ios_base::openmode __wch = ios_base::in | ios_base::out);
|
|
|
|
virtual pos_type seekpos(pos_type __sp,
|
|
|
|
ios_base::openmode __wch = ios_base::in | ios_base::out);
|
|
|
|
virtual int sync();
|
|
|
|
virtual void imbue(const locale& __loc);
|
|
|
|
|
|
|
|
private:
|
2018-07-22 10:00:53 +08:00
|
|
|
char* __extbuf_;
|
|
|
|
const char* __extbufnext_;
|
|
|
|
const char* __extbufend_;
|
|
|
|
char __extbuf_min_[8];
|
|
|
|
size_t __ebs_;
|
|
|
|
char_type* __intbuf_;
|
|
|
|
size_t __ibs_;
|
|
|
|
FILE* __file_;
|
|
|
|
const codecvt<char_type, char, state_type>* __cv_;
|
|
|
|
state_type __st_;
|
|
|
|
state_type __st_last_;
|
|
|
|
ios_base::openmode __om_;
|
|
|
|
ios_base::openmode __cm_;
|
|
|
|
bool __owns_eb_;
|
|
|
|
bool __owns_ib_;
|
|
|
|
bool __always_noconv_;
|
|
|
|
|
|
|
|
bool __read_mode();
|
|
|
|
void __write_mode();
|
2010-05-12 03:42:16 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
basic_filebuf<_CharT, _Traits>::basic_filebuf()
|
|
|
|
: __extbuf_(0),
|
|
|
|
__extbufnext_(0),
|
|
|
|
__extbufend_(0),
|
|
|
|
__ebs_(0),
|
|
|
|
__intbuf_(0),
|
|
|
|
__ibs_(0),
|
|
|
|
__file_(0),
|
2012-08-25 00:52:47 +08:00
|
|
|
__cv_(nullptr),
|
2010-05-12 03:42:16 +08:00
|
|
|
__st_(),
|
2012-08-25 05:20:56 +08:00
|
|
|
__st_last_(),
|
2010-05-12 03:42:16 +08:00
|
|
|
__om_(0),
|
|
|
|
__cm_(0),
|
|
|
|
__owns_eb_(false),
|
|
|
|
__owns_ib_(false),
|
2012-08-25 00:52:47 +08:00
|
|
|
__always_noconv_(false)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2012-08-25 00:52:47 +08:00
|
|
|
if (has_facet<codecvt<char_type, char, state_type> >(this->getloc()))
|
|
|
|
{
|
|
|
|
__cv_ = &use_facet<codecvt<char_type, char, state_type> >(this->getloc());
|
|
|
|
__always_noconv_ = __cv_->always_noconv();
|
|
|
|
}
|
2012-08-25 02:06:47 +08:00
|
|
|
setbuf(0, 4096);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
2017-04-19 07:38:41 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
basic_filebuf<_CharT, _Traits>::basic_filebuf(basic_filebuf&& __rhs)
|
|
|
|
: basic_streambuf<_CharT, _Traits>(__rhs)
|
|
|
|
{
|
|
|
|
if (__rhs.__extbuf_ == __rhs.__extbuf_min_)
|
|
|
|
{
|
|
|
|
__extbuf_ = __extbuf_min_;
|
|
|
|
__extbufnext_ = __extbuf_ + (__rhs.__extbufnext_ - __rhs.__extbuf_);
|
|
|
|
__extbufend_ = __extbuf_ + (__rhs.__extbufend_ - __rhs.__extbuf_);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
__extbuf_ = __rhs.__extbuf_;
|
|
|
|
__extbufnext_ = __rhs.__extbufnext_;
|
|
|
|
__extbufend_ = __rhs.__extbufend_;
|
|
|
|
}
|
|
|
|
__ebs_ = __rhs.__ebs_;
|
|
|
|
__intbuf_ = __rhs.__intbuf_;
|
|
|
|
__ibs_ = __rhs.__ibs_;
|
|
|
|
__file_ = __rhs.__file_;
|
|
|
|
__cv_ = __rhs.__cv_;
|
|
|
|
__st_ = __rhs.__st_;
|
2012-08-25 05:20:56 +08:00
|
|
|
__st_last_ = __rhs.__st_last_;
|
2010-05-12 03:42:16 +08:00
|
|
|
__om_ = __rhs.__om_;
|
|
|
|
__cm_ = __rhs.__cm_;
|
|
|
|
__owns_eb_ = __rhs.__owns_eb_;
|
|
|
|
__owns_ib_ = __rhs.__owns_ib_;
|
|
|
|
__always_noconv_ = __rhs.__always_noconv_;
|
|
|
|
if (__rhs.pbase())
|
|
|
|
{
|
|
|
|
if (__rhs.pbase() == __rhs.__intbuf_)
|
|
|
|
this->setp(__intbuf_, __intbuf_ + (__rhs. epptr() - __rhs.pbase()));
|
|
|
|
else
|
|
|
|
this->setp((char_type*)__extbuf_,
|
|
|
|
(char_type*)__extbuf_ + (__rhs. epptr() - __rhs.pbase()));
|
2017-09-12 23:00:43 +08:00
|
|
|
this->__pbump(__rhs. pptr() - __rhs.pbase());
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
else if (__rhs.eback())
|
|
|
|
{
|
|
|
|
if (__rhs.eback() == __rhs.__intbuf_)
|
|
|
|
this->setg(__intbuf_, __intbuf_ + (__rhs.gptr() - __rhs.eback()),
|
|
|
|
__intbuf_ + (__rhs.egptr() - __rhs.eback()));
|
|
|
|
else
|
|
|
|
this->setg((char_type*)__extbuf_,
|
|
|
|
(char_type*)__extbuf_ + (__rhs.gptr() - __rhs.eback()),
|
|
|
|
(char_type*)__extbuf_ + (__rhs.egptr() - __rhs.eback()));
|
|
|
|
}
|
|
|
|
__rhs.__extbuf_ = 0;
|
|
|
|
__rhs.__extbufnext_ = 0;
|
|
|
|
__rhs.__extbufend_ = 0;
|
|
|
|
__rhs.__ebs_ = 0;
|
|
|
|
__rhs.__intbuf_ = 0;
|
|
|
|
__rhs.__ibs_ = 0;
|
|
|
|
__rhs.__file_ = 0;
|
|
|
|
__rhs.__st_ = state_type();
|
2012-08-25 05:20:56 +08:00
|
|
|
__rhs.__st_last_ = state_type();
|
2010-05-12 03:42:16 +08:00
|
|
|
__rhs.__om_ = 0;
|
|
|
|
__rhs.__cm_ = 0;
|
|
|
|
__rhs.__owns_eb_ = false;
|
|
|
|
__rhs.__owns_ib_ = false;
|
|
|
|
__rhs.setg(0, 0, 0);
|
|
|
|
__rhs.setp(0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
2016-04-22 09:04:55 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_filebuf<_CharT, _Traits>&
|
|
|
|
basic_filebuf<_CharT, _Traits>::operator=(basic_filebuf&& __rhs)
|
|
|
|
{
|
|
|
|
close();
|
|
|
|
swap(__rhs);
|
2012-10-13 10:03:45 +08:00
|
|
|
return *this;
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
2017-04-19 07:38:41 +08:00
|
|
|
#endif // _LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
basic_filebuf<_CharT, _Traits>::~basic_filebuf()
|
|
|
|
{
|
|
|
|
#ifndef _LIBCPP_NO_EXCEPTIONS
|
|
|
|
try
|
|
|
|
{
|
2010-08-22 08:02:43 +08:00
|
|
|
#endif // _LIBCPP_NO_EXCEPTIONS
|
2010-05-12 03:42:16 +08:00
|
|
|
close();
|
|
|
|
#ifndef _LIBCPP_NO_EXCEPTIONS
|
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
}
|
2010-08-22 08:02:43 +08:00
|
|
|
#endif // _LIBCPP_NO_EXCEPTIONS
|
2010-05-12 03:42:16 +08:00
|
|
|
if (__owns_eb_)
|
|
|
|
delete [] __extbuf_;
|
|
|
|
if (__owns_ib_)
|
|
|
|
delete [] __intbuf_;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
void
|
|
|
|
basic_filebuf<_CharT, _Traits>::swap(basic_filebuf& __rhs)
|
|
|
|
{
|
|
|
|
basic_streambuf<char_type, traits_type>::swap(__rhs);
|
|
|
|
if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_)
|
|
|
|
{
|
2011-07-01 05:18:19 +08:00
|
|
|
_VSTD::swap(__extbuf_, __rhs.__extbuf_);
|
|
|
|
_VSTD::swap(__extbufnext_, __rhs.__extbufnext_);
|
|
|
|
_VSTD::swap(__extbufend_, __rhs.__extbufend_);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ptrdiff_t __ln = __extbufnext_ - __extbuf_;
|
|
|
|
ptrdiff_t __le = __extbufend_ - __extbuf_;
|
|
|
|
ptrdiff_t __rn = __rhs.__extbufnext_ - __rhs.__extbuf_;
|
|
|
|
ptrdiff_t __re = __rhs.__extbufend_ - __rhs.__extbuf_;
|
|
|
|
if (__extbuf_ == __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_)
|
|
|
|
{
|
|
|
|
__extbuf_ = __rhs.__extbuf_;
|
|
|
|
__rhs.__extbuf_ = __rhs.__extbuf_min_;
|
|
|
|
}
|
|
|
|
else if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ == __rhs.__extbuf_min_)
|
|
|
|
{
|
|
|
|
__rhs.__extbuf_ = __extbuf_;
|
|
|
|
__extbuf_ = __extbuf_min_;
|
|
|
|
}
|
|
|
|
__extbufnext_ = __extbuf_ + __rn;
|
|
|
|
__extbufend_ = __extbuf_ + __re;
|
|
|
|
__rhs.__extbufnext_ = __rhs.__extbuf_ + __ln;
|
|
|
|
__rhs.__extbufend_ = __rhs.__extbuf_ + __le;
|
|
|
|
}
|
2011-07-01 05:18:19 +08:00
|
|
|
_VSTD::swap(__ebs_, __rhs.__ebs_);
|
|
|
|
_VSTD::swap(__intbuf_, __rhs.__intbuf_);
|
|
|
|
_VSTD::swap(__ibs_, __rhs.__ibs_);
|
|
|
|
_VSTD::swap(__file_, __rhs.__file_);
|
|
|
|
_VSTD::swap(__cv_, __rhs.__cv_);
|
|
|
|
_VSTD::swap(__st_, __rhs.__st_);
|
2012-08-25 05:20:56 +08:00
|
|
|
_VSTD::swap(__st_last_, __rhs.__st_last_);
|
2011-07-01 05:18:19 +08:00
|
|
|
_VSTD::swap(__om_, __rhs.__om_);
|
|
|
|
_VSTD::swap(__cm_, __rhs.__cm_);
|
|
|
|
_VSTD::swap(__owns_eb_, __rhs.__owns_eb_);
|
|
|
|
_VSTD::swap(__owns_ib_, __rhs.__owns_ib_);
|
|
|
|
_VSTD::swap(__always_noconv_, __rhs.__always_noconv_);
|
2010-05-12 03:42:16 +08:00
|
|
|
if (this->eback() == (char_type*)__rhs.__extbuf_min_)
|
|
|
|
{
|
|
|
|
ptrdiff_t __n = this->gptr() - this->eback();
|
|
|
|
ptrdiff_t __e = this->egptr() - this->eback();
|
|
|
|
this->setg((char_type*)__extbuf_min_,
|
|
|
|
(char_type*)__extbuf_min_ + __n,
|
|
|
|
(char_type*)__extbuf_min_ + __e);
|
|
|
|
}
|
|
|
|
else if (this->pbase() == (char_type*)__rhs.__extbuf_min_)
|
|
|
|
{
|
|
|
|
ptrdiff_t __n = this->pptr() - this->pbase();
|
|
|
|
ptrdiff_t __e = this->epptr() - this->pbase();
|
|
|
|
this->setp((char_type*)__extbuf_min_,
|
|
|
|
(char_type*)__extbuf_min_ + __e);
|
2017-09-12 23:00:43 +08:00
|
|
|
this->__pbump(__n);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
if (__rhs.eback() == (char_type*)__extbuf_min_)
|
|
|
|
{
|
|
|
|
ptrdiff_t __n = __rhs.gptr() - __rhs.eback();
|
|
|
|
ptrdiff_t __e = __rhs.egptr() - __rhs.eback();
|
|
|
|
__rhs.setg((char_type*)__rhs.__extbuf_min_,
|
|
|
|
(char_type*)__rhs.__extbuf_min_ + __n,
|
|
|
|
(char_type*)__rhs.__extbuf_min_ + __e);
|
|
|
|
}
|
|
|
|
else if (__rhs.pbase() == (char_type*)__extbuf_min_)
|
|
|
|
{
|
|
|
|
ptrdiff_t __n = __rhs.pptr() - __rhs.pbase();
|
|
|
|
ptrdiff_t __e = __rhs.epptr() - __rhs.pbase();
|
|
|
|
__rhs.setp((char_type*)__rhs.__extbuf_min_,
|
|
|
|
(char_type*)__rhs.__extbuf_min_ + __e);
|
2017-09-12 23:00:43 +08:00
|
|
|
__rhs.__pbump(__n);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
|
|
void
|
|
|
|
swap(basic_filebuf<_CharT, _Traits>& __x, basic_filebuf<_CharT, _Traits>& __y)
|
|
|
|
{
|
|
|
|
__x.swap(__y);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
2016-04-22 09:04:55 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
|
|
|
basic_filebuf<_CharT, _Traits>::is_open() const
|
|
|
|
{
|
|
|
|
return __file_ != 0;
|
|
|
|
}
|
|
|
|
|
2018-07-22 10:00:53 +08:00
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
const char* basic_filebuf<_CharT, _Traits>::__make_mdstring(
|
|
|
|
ios_base::openmode __mode) _NOEXCEPT {
|
|
|
|
switch (__mode & ~ios_base::ate) {
|
|
|
|
case ios_base::out:
|
|
|
|
case ios_base::out | ios_base::trunc:
|
|
|
|
return "w";
|
|
|
|
case ios_base::out | ios_base::app:
|
|
|
|
case ios_base::app:
|
|
|
|
return "a";
|
|
|
|
case ios_base::in:
|
|
|
|
return "r";
|
|
|
|
case ios_base::in | ios_base::out:
|
|
|
|
return "r+";
|
|
|
|
case ios_base::in | ios_base::out | ios_base::trunc:
|
|
|
|
return "w+";
|
|
|
|
case ios_base::in | ios_base::out | ios_base::app:
|
|
|
|
case ios_base::in | ios_base::app:
|
|
|
|
return "a+";
|
|
|
|
case ios_base::out | ios_base::binary:
|
|
|
|
case ios_base::out | ios_base::trunc | ios_base::binary:
|
|
|
|
return "wb";
|
|
|
|
case ios_base::out | ios_base::app | ios_base::binary:
|
|
|
|
case ios_base::app | ios_base::binary:
|
|
|
|
return "ab";
|
|
|
|
case ios_base::in | ios_base::binary:
|
|
|
|
return "rb";
|
|
|
|
case ios_base::in | ios_base::out | ios_base::binary:
|
|
|
|
return "r+b";
|
|
|
|
case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
|
|
|
|
return "w+b";
|
|
|
|
case ios_base::in | ios_base::out | ios_base::app | ios_base::binary:
|
|
|
|
case ios_base::in | ios_base::app | ios_base::binary:
|
|
|
|
return "a+b";
|
|
|
|
default:
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
_LIBCPP_UNREACHABLE();
|
|
|
|
}
|
|
|
|
|
Add option to disable access to the global filesystem namespace.
Systems like FreeBSD's Capsicum and Nuxi CloudABI apply the concept of
capability-based security on the way processes can interact with the
filesystem API. It is no longer possible to interact with the VFS
through calls like open(), unlink(), rename(), etc. Instead, processes
are only allowed to interact with files and directories to which they
have been granted access. The *at() functions can be used for this
purpose.
This change adds a new config switch called
_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE. If set, all functionality
that requires the global filesystem namespace will be disabled. More
concretely:
- fstream's open() function will be removed.
- cstdio will no longer pull in fopen(), rename(), etc.
- The test suite's get_temp_file_name() will be removed. This will cause
all tests that use the global filesystem namespace to break, but will
at least make all the other tests run (as get_temp_file_name will not
build anyway).
It is important to mention that this change will make fstream rather
useless on those systems for now. Still, I'd rather not have fstream
disabled entirely, as it is of course possible to come up with an
extension for fstream that would allow access to local filesystem
namespaces (e.g., by adding an openat() member function).
Differential revision: http://reviews.llvm.org/D8194
Reviewed by: jroelofs (thanks!)
llvm-svn: 232049
2015-03-12 23:44:39 +08:00
|
|
|
#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
basic_filebuf<_CharT, _Traits>*
|
|
|
|
basic_filebuf<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode)
|
|
|
|
{
|
|
|
|
basic_filebuf<_CharT, _Traits>* __rt = 0;
|
|
|
|
if (__file_ == 0)
|
|
|
|
{
|
2018-07-22 10:00:53 +08:00
|
|
|
if (const char* __mdstr = __make_mdstring(__mode)) {
|
2010-05-12 03:42:16 +08:00
|
|
|
__rt = this;
|
2018-07-22 10:00:53 +08:00
|
|
|
__file_ = fopen(__s, __mdstr);
|
|
|
|
if (__file_) {
|
|
|
|
__om_ = __mode;
|
|
|
|
if (__mode & ios_base::ate) {
|
|
|
|
if (fseek(__file_, 0, SEEK_END)) {
|
|
|
|
fclose(__file_);
|
|
|
|
__file_ = 0;
|
|
|
|
__rt = 0;
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
2018-07-22 10:00:53 +08:00
|
|
|
}
|
|
|
|
} else
|
|
|
|
__rt = 0;
|
|
|
|
}
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
return __rt;
|
|
|
|
}
|
|
|
|
|
2018-07-22 10:00:53 +08:00
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY basic_filebuf<_CharT, _Traits>*
|
|
|
|
basic_filebuf<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) {
|
|
|
|
basic_filebuf<_CharT, _Traits>* __rt = 0;
|
|
|
|
if (__file_ == 0) {
|
|
|
|
if (const char* __mdstr = __make_mdstring(__mode)) {
|
|
|
|
__rt = this;
|
|
|
|
__file_ = fdopen(__fd, __mdstr);
|
|
|
|
if (__file_) {
|
|
|
|
__om_ = __mode;
|
|
|
|
if (__mode & ios_base::ate) {
|
|
|
|
if (fseek(__file_, 0, SEEK_END)) {
|
|
|
|
fclose(__file_);
|
|
|
|
__file_ = 0;
|
|
|
|
__rt = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
__rt = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return __rt;
|
|
|
|
}
|
|
|
|
|
2018-01-23 10:07:27 +08:00
|
|
|
#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
|
|
|
|
// This is basically the same as the char* overload except that it uses _wfopen
|
|
|
|
// and long mode strings.
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
basic_filebuf<_CharT, _Traits>*
|
|
|
|
basic_filebuf<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode)
|
|
|
|
{
|
|
|
|
basic_filebuf<_CharT, _Traits>* __rt = 0;
|
|
|
|
if (__file_ == 0)
|
|
|
|
{
|
|
|
|
__rt = this;
|
|
|
|
const wchar_t* __mdstr;
|
|
|
|
switch (__mode & ~ios_base::ate)
|
|
|
|
{
|
|
|
|
case ios_base::out:
|
|
|
|
case ios_base::out | ios_base::trunc:
|
|
|
|
__mdstr = L"w";
|
|
|
|
break;
|
|
|
|
case ios_base::out | ios_base::app:
|
|
|
|
case ios_base::app:
|
|
|
|
__mdstr = L"a";
|
|
|
|
break;
|
|
|
|
case ios_base::in:
|
|
|
|
__mdstr = L"r";
|
|
|
|
break;
|
|
|
|
case ios_base::in | ios_base::out:
|
|
|
|
__mdstr = L"r+";
|
|
|
|
break;
|
|
|
|
case ios_base::in | ios_base::out | ios_base::trunc:
|
|
|
|
__mdstr = L"w+";
|
|
|
|
break;
|
|
|
|
case ios_base::in | ios_base::out | ios_base::app:
|
|
|
|
case ios_base::in | ios_base::app:
|
|
|
|
__mdstr = L"a+";
|
|
|
|
break;
|
|
|
|
case ios_base::out | ios_base::binary:
|
|
|
|
case ios_base::out | ios_base::trunc | ios_base::binary:
|
|
|
|
__mdstr = L"wb";
|
|
|
|
break;
|
|
|
|
case ios_base::out | ios_base::app | ios_base::binary:
|
|
|
|
case ios_base::app | ios_base::binary:
|
|
|
|
__mdstr = L"ab";
|
|
|
|
break;
|
|
|
|
case ios_base::in | ios_base::binary:
|
|
|
|
__mdstr = L"rb";
|
|
|
|
break;
|
|
|
|
case ios_base::in | ios_base::out | ios_base::binary:
|
|
|
|
__mdstr = L"r+b";
|
|
|
|
break;
|
|
|
|
case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
|
|
|
|
__mdstr = L"w+b";
|
|
|
|
break;
|
|
|
|
case ios_base::in | ios_base::out | ios_base::app | ios_base::binary:
|
|
|
|
case ios_base::in | ios_base::app | ios_base::binary:
|
|
|
|
__mdstr = L"a+b";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
__rt = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (__rt)
|
|
|
|
{
|
|
|
|
__file_ = _wfopen(__s, __mdstr);
|
|
|
|
if (__file_)
|
|
|
|
{
|
|
|
|
__om_ = __mode;
|
|
|
|
if (__mode & ios_base::ate)
|
|
|
|
{
|
|
|
|
if (fseek(__file_, 0, SEEK_END))
|
|
|
|
{
|
|
|
|
fclose(__file_);
|
|
|
|
__file_ = 0;
|
|
|
|
__rt = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
__rt = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return __rt;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _CharT, class _Traits>
|
2016-04-22 09:04:55 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_filebuf<_CharT, _Traits>*
|
|
|
|
basic_filebuf<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode)
|
|
|
|
{
|
|
|
|
return open(__s.c_str(), __mode);
|
|
|
|
}
|
Add option to disable access to the global filesystem namespace.
Systems like FreeBSD's Capsicum and Nuxi CloudABI apply the concept of
capability-based security on the way processes can interact with the
filesystem API. It is no longer possible to interact with the VFS
through calls like open(), unlink(), rename(), etc. Instead, processes
are only allowed to interact with files and directories to which they
have been granted access. The *at() functions can be used for this
purpose.
This change adds a new config switch called
_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE. If set, all functionality
that requires the global filesystem namespace will be disabled. More
concretely:
- fstream's open() function will be removed.
- cstdio will no longer pull in fopen(), rename(), etc.
- The test suite's get_temp_file_name() will be removed. This will cause
all tests that use the global filesystem namespace to break, but will
at least make all the other tests run (as get_temp_file_name will not
build anyway).
It is important to mention that this change will make fstream rather
useless on those systems for now. Still, I'd rather not have fstream
disabled entirely, as it is of course possible to come up with an
extension for fstream that would allow access to local filesystem
namespaces (e.g., by adding an openat() member function).
Differential revision: http://reviews.llvm.org/D8194
Reviewed by: jroelofs (thanks!)
llvm-svn: 232049
2015-03-12 23:44:39 +08:00
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
basic_filebuf<_CharT, _Traits>*
|
|
|
|
basic_filebuf<_CharT, _Traits>::close()
|
|
|
|
{
|
|
|
|
basic_filebuf<_CharT, _Traits>* __rt = 0;
|
|
|
|
if (__file_)
|
|
|
|
{
|
|
|
|
__rt = this;
|
|
|
|
unique_ptr<FILE, int(*)(FILE*)> __h(__file_, fclose);
|
2012-01-13 07:37:51 +08:00
|
|
|
if (sync())
|
2010-05-12 03:42:16 +08:00
|
|
|
__rt = 0;
|
|
|
|
if (fclose(__h.release()) == 0)
|
|
|
|
__file_ = 0;
|
|
|
|
else
|
|
|
|
__rt = 0;
|
2019-01-08 10:48:45 +08:00
|
|
|
setbuf(0, 0);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
return __rt;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
typename basic_filebuf<_CharT, _Traits>::int_type
|
|
|
|
basic_filebuf<_CharT, _Traits>::underflow()
|
|
|
|
{
|
|
|
|
if (__file_ == 0)
|
|
|
|
return traits_type::eof();
|
|
|
|
bool __initial = __read_mode();
|
|
|
|
char_type __1buf;
|
|
|
|
if (this->gptr() == 0)
|
|
|
|
this->setg(&__1buf, &__1buf+1, &__1buf+1);
|
|
|
|
const size_t __unget_sz = __initial ? 0 : min<size_t>((this->egptr() - this->eback()) / 2, 4);
|
|
|
|
int_type __c = traits_type::eof();
|
|
|
|
if (this->gptr() == this->egptr())
|
|
|
|
{
|
|
|
|
memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type));
|
|
|
|
if (__always_noconv_)
|
|
|
|
{
|
|
|
|
size_t __nmemb = static_cast<size_t>(this->egptr() - this->eback() - __unget_sz);
|
|
|
|
__nmemb = fread(this->eback() + __unget_sz, 1, __nmemb, __file_);
|
|
|
|
if (__nmemb != 0)
|
|
|
|
{
|
|
|
|
this->setg(this->eback(),
|
|
|
|
this->eback() + __unget_sz,
|
|
|
|
this->eback() + __unget_sz + __nmemb);
|
2011-02-03 01:37:16 +08:00
|
|
|
__c = traits_type::to_int_type(*this->gptr());
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-06-05 00:16:59 +08:00
|
|
|
_LIBCPP_ASSERT ( !(__extbufnext_ == NULL && (__extbufend_ != __extbufnext_)), "underflow moving from NULL" );
|
|
|
|
if (__extbufend_ != __extbufnext_)
|
|
|
|
memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_);
|
2010-05-12 03:42:16 +08:00
|
|
|
__extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_);
|
|
|
|
__extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_);
|
2012-08-25 04:37:00 +08:00
|
|
|
size_t __nmemb = _VSTD::min(static_cast<size_t>(__ibs_ - __unget_sz),
|
2010-05-12 03:42:16 +08:00
|
|
|
static_cast<size_t>(__extbufend_ - __extbufnext_));
|
|
|
|
codecvt_base::result __r;
|
2012-08-25 05:20:56 +08:00
|
|
|
__st_last_ = __st_;
|
2017-06-15 04:00:36 +08:00
|
|
|
size_t __nr = fread((void*) const_cast<char *>(__extbufnext_), 1, __nmemb, __file_);
|
2010-05-12 03:42:16 +08:00
|
|
|
if (__nr != 0)
|
|
|
|
{
|
2012-08-25 00:52:47 +08:00
|
|
|
if (!__cv_)
|
2016-08-25 23:09:01 +08:00
|
|
|
__throw_bad_cast();
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
__extbufend_ = __extbufnext_ + __nr;
|
|
|
|
char_type* __inext;
|
|
|
|
__r = __cv_->in(__st_, __extbuf_, __extbufend_, __extbufnext_,
|
|
|
|
this->eback() + __unget_sz,
|
2012-08-25 04:37:00 +08:00
|
|
|
this->eback() + __ibs_, __inext);
|
2010-05-12 03:42:16 +08:00
|
|
|
if (__r == codecvt_base::noconv)
|
|
|
|
{
|
2017-06-15 04:00:36 +08:00
|
|
|
this->setg((char_type*)__extbuf_, (char_type*)__extbuf_,
|
|
|
|
(char_type*)const_cast<char *>(__extbufend_));
|
2011-02-03 01:37:16 +08:00
|
|
|
__c = traits_type::to_int_type(*this->gptr());
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
else if (__inext != this->eback() + __unget_sz)
|
|
|
|
{
|
|
|
|
this->setg(this->eback(), this->eback() + __unget_sz, __inext);
|
2011-02-03 01:37:16 +08:00
|
|
|
__c = traits_type::to_int_type(*this->gptr());
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2011-02-03 01:37:16 +08:00
|
|
|
__c = traits_type::to_int_type(*this->gptr());
|
2010-05-12 03:42:16 +08:00
|
|
|
if (this->eback() == &__1buf)
|
|
|
|
this->setg(0, 0, 0);
|
|
|
|
return __c;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
typename basic_filebuf<_CharT, _Traits>::int_type
|
|
|
|
basic_filebuf<_CharT, _Traits>::pbackfail(int_type __c)
|
|
|
|
{
|
|
|
|
if (__file_ && this->eback() < this->gptr())
|
|
|
|
{
|
|
|
|
if (traits_type::eq_int_type(__c, traits_type::eof()))
|
|
|
|
{
|
|
|
|
this->gbump(-1);
|
|
|
|
return traits_type::not_eof(__c);
|
|
|
|
}
|
|
|
|
if ((__om_ & ios_base::out) ||
|
|
|
|
traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1]))
|
|
|
|
{
|
|
|
|
this->gbump(-1);
|
|
|
|
*this->gptr() = traits_type::to_char_type(__c);
|
|
|
|
return __c;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return traits_type::eof();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
typename basic_filebuf<_CharT, _Traits>::int_type
|
|
|
|
basic_filebuf<_CharT, _Traits>::overflow(int_type __c)
|
|
|
|
{
|
|
|
|
if (__file_ == 0)
|
|
|
|
return traits_type::eof();
|
|
|
|
__write_mode();
|
|
|
|
char_type __1buf;
|
|
|
|
char_type* __pb_save = this->pbase();
|
|
|
|
char_type* __epb_save = this->epptr();
|
|
|
|
if (!traits_type::eq_int_type(__c, traits_type::eof()))
|
|
|
|
{
|
|
|
|
if (this->pptr() == 0)
|
|
|
|
this->setp(&__1buf, &__1buf+1);
|
|
|
|
*this->pptr() = traits_type::to_char_type(__c);
|
|
|
|
this->pbump(1);
|
|
|
|
}
|
|
|
|
if (this->pptr() != this->pbase())
|
|
|
|
{
|
|
|
|
if (__always_noconv_)
|
|
|
|
{
|
|
|
|
size_t __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
|
|
|
|
if (fwrite(this->pbase(), sizeof(char_type), __nmemb, __file_) != __nmemb)
|
|
|
|
return traits_type::eof();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
char* __extbe = __extbuf_;
|
|
|
|
codecvt_base::result __r;
|
|
|
|
do
|
|
|
|
{
|
2012-08-25 00:52:47 +08:00
|
|
|
if (!__cv_)
|
2016-08-25 23:09:01 +08:00
|
|
|
__throw_bad_cast();
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
const char_type* __e;
|
|
|
|
__r = __cv_->out(__st_, this->pbase(), this->pptr(), __e,
|
|
|
|
__extbuf_, __extbuf_ + __ebs_, __extbe);
|
|
|
|
if (__e == this->pbase())
|
|
|
|
return traits_type::eof();
|
|
|
|
if (__r == codecvt_base::noconv)
|
|
|
|
{
|
|
|
|
size_t __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
|
|
|
|
if (fwrite(this->pbase(), 1, __nmemb, __file_) != __nmemb)
|
|
|
|
return traits_type::eof();
|
|
|
|
}
|
|
|
|
else if (__r == codecvt_base::ok || __r == codecvt_base::partial)
|
|
|
|
{
|
|
|
|
size_t __nmemb = static_cast<size_t>(__extbe - __extbuf_);
|
|
|
|
if (fwrite(__extbuf_, 1, __nmemb, __file_) != __nmemb)
|
|
|
|
return traits_type::eof();
|
|
|
|
if (__r == codecvt_base::partial)
|
|
|
|
{
|
2017-06-15 04:00:36 +08:00
|
|
|
this->setp(const_cast<char_type*>(__e), this->pptr());
|
2017-09-12 23:00:43 +08:00
|
|
|
this->__pbump(this->epptr() - this->pbase());
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return traits_type::eof();
|
|
|
|
} while (__r == codecvt_base::partial);
|
|
|
|
}
|
|
|
|
this->setp(__pb_save, __epb_save);
|
|
|
|
}
|
|
|
|
return traits_type::not_eof(__c);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
basic_streambuf<_CharT, _Traits>*
|
|
|
|
basic_filebuf<_CharT, _Traits>::setbuf(char_type* __s, streamsize __n)
|
|
|
|
{
|
|
|
|
this->setg(0, 0, 0);
|
|
|
|
this->setp(0, 0);
|
|
|
|
if (__owns_eb_)
|
|
|
|
delete [] __extbuf_;
|
|
|
|
if (__owns_ib_)
|
|
|
|
delete [] __intbuf_;
|
|
|
|
__ebs_ = __n;
|
|
|
|
if (__ebs_ > sizeof(__extbuf_min_))
|
|
|
|
{
|
|
|
|
if (__always_noconv_ && __s)
|
|
|
|
{
|
|
|
|
__extbuf_ = (char*)__s;
|
|
|
|
__owns_eb_ = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
__extbuf_ = new char[__ebs_];
|
|
|
|
__owns_eb_ = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
__extbuf_ = __extbuf_min_;
|
|
|
|
__ebs_ = sizeof(__extbuf_min_);
|
|
|
|
__owns_eb_ = false;
|
|
|
|
}
|
|
|
|
if (!__always_noconv_)
|
|
|
|
{
|
|
|
|
__ibs_ = max<streamsize>(__n, sizeof(__extbuf_min_));
|
|
|
|
if (__s && __ibs_ >= sizeof(__extbuf_min_))
|
|
|
|
{
|
|
|
|
__intbuf_ = __s;
|
|
|
|
__owns_ib_ = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
__intbuf_ = new char_type[__ibs_];
|
|
|
|
__owns_ib_ = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
__ibs_ = 0;
|
|
|
|
__intbuf_ = 0;
|
|
|
|
__owns_ib_ = false;
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
typename basic_filebuf<_CharT, _Traits>::pos_type
|
|
|
|
basic_filebuf<_CharT, _Traits>::seekoff(off_type __off, ios_base::seekdir __way,
|
|
|
|
ios_base::openmode)
|
|
|
|
{
|
2012-08-25 00:52:47 +08:00
|
|
|
if (!__cv_)
|
2016-08-25 23:09:01 +08:00
|
|
|
__throw_bad_cast();
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
int __width = __cv_->encoding();
|
|
|
|
if (__file_ == 0 || (__width <= 0 && __off != 0) || sync())
|
|
|
|
return pos_type(off_type(-1));
|
|
|
|
// __width > 0 || __off == 0
|
|
|
|
int __whence;
|
|
|
|
switch (__way)
|
|
|
|
{
|
|
|
|
case ios_base::beg:
|
|
|
|
__whence = SEEK_SET;
|
|
|
|
break;
|
|
|
|
case ios_base::cur:
|
|
|
|
__whence = SEEK_CUR;
|
|
|
|
break;
|
|
|
|
case ios_base::end:
|
|
|
|
__whence = SEEK_END;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return pos_type(off_type(-1));
|
|
|
|
}
|
2016-10-31 23:09:10 +08:00
|
|
|
#if defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS)
|
2013-04-03 06:14:51 +08:00
|
|
|
if (fseek(__file_, __width > 0 ? __width * __off : 0, __whence))
|
|
|
|
return pos_type(off_type(-1));
|
|
|
|
pos_type __r = ftell(__file_);
|
|
|
|
#else
|
2010-05-12 03:42:16 +08:00
|
|
|
if (fseeko(__file_, __width > 0 ? __width * __off : 0, __whence))
|
|
|
|
return pos_type(off_type(-1));
|
|
|
|
pos_type __r = ftello(__file_);
|
2013-04-03 06:14:51 +08:00
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
__r.state(__st_);
|
|
|
|
return __r;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
typename basic_filebuf<_CharT, _Traits>::pos_type
|
2010-07-16 02:18:07 +08:00
|
|
|
basic_filebuf<_CharT, _Traits>::seekpos(pos_type __sp, ios_base::openmode)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
if (__file_ == 0 || sync())
|
|
|
|
return pos_type(off_type(-1));
|
2016-10-31 23:09:10 +08:00
|
|
|
#if defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS)
|
2013-04-03 06:14:51 +08:00
|
|
|
if (fseek(__file_, __sp, SEEK_SET))
|
|
|
|
return pos_type(off_type(-1));
|
|
|
|
#else
|
2010-05-12 03:42:16 +08:00
|
|
|
if (fseeko(__file_, __sp, SEEK_SET))
|
|
|
|
return pos_type(off_type(-1));
|
2013-04-03 06:14:51 +08:00
|
|
|
#endif
|
2012-08-25 05:20:56 +08:00
|
|
|
__st_ = __sp.state();
|
2010-05-12 03:42:16 +08:00
|
|
|
return __sp;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
int
|
|
|
|
basic_filebuf<_CharT, _Traits>::sync()
|
|
|
|
{
|
|
|
|
if (__file_ == 0)
|
|
|
|
return 0;
|
2012-08-25 00:52:47 +08:00
|
|
|
if (!__cv_)
|
2016-08-25 23:09:01 +08:00
|
|
|
__throw_bad_cast();
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
if (__cm_ & ios_base::out)
|
|
|
|
{
|
|
|
|
if (this->pptr() != this->pbase())
|
|
|
|
if (overflow() == traits_type::eof())
|
|
|
|
return -1;
|
|
|
|
codecvt_base::result __r;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
char* __extbe;
|
|
|
|
__r = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe);
|
|
|
|
size_t __nmemb = static_cast<size_t>(__extbe - __extbuf_);
|
|
|
|
if (fwrite(__extbuf_, 1, __nmemb, __file_) != __nmemb)
|
|
|
|
return -1;
|
|
|
|
} while (__r == codecvt_base::partial);
|
|
|
|
if (__r == codecvt_base::error)
|
|
|
|
return -1;
|
|
|
|
if (fflush(__file_))
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else if (__cm_ & ios_base::in)
|
|
|
|
{
|
|
|
|
off_type __c;
|
2012-08-25 05:20:56 +08:00
|
|
|
state_type __state = __st_last_;
|
|
|
|
bool __update_st = false;
|
2010-05-12 03:42:16 +08:00
|
|
|
if (__always_noconv_)
|
|
|
|
__c = this->egptr() - this->gptr();
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int __width = __cv_->encoding();
|
|
|
|
__c = __extbufend_ - __extbufnext_;
|
|
|
|
if (__width > 0)
|
|
|
|
__c += __width * (this->egptr() - this->gptr());
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (this->gptr() != this->egptr())
|
|
|
|
{
|
2012-08-25 05:20:56 +08:00
|
|
|
const int __off = __cv_->length(__state, __extbuf_,
|
|
|
|
__extbufnext_,
|
|
|
|
this->gptr() - this->eback());
|
|
|
|
__c += __extbufnext_ - __extbuf_ - __off;
|
|
|
|
__update_st = true;
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-10-31 23:09:10 +08:00
|
|
|
#if defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS)
|
2013-04-03 06:14:51 +08:00
|
|
|
if (fseek(__file_, -__c, SEEK_CUR))
|
|
|
|
return -1;
|
|
|
|
#else
|
2010-05-12 03:42:16 +08:00
|
|
|
if (fseeko(__file_, -__c, SEEK_CUR))
|
|
|
|
return -1;
|
2013-04-03 06:14:51 +08:00
|
|
|
#endif
|
2012-08-25 05:20:56 +08:00
|
|
|
if (__update_st)
|
|
|
|
__st_ = __state;
|
|
|
|
__extbufnext_ = __extbufend_ = __extbuf_;
|
2010-05-12 03:42:16 +08:00
|
|
|
this->setg(0, 0, 0);
|
|
|
|
__cm_ = 0;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
void
|
|
|
|
basic_filebuf<_CharT, _Traits>::imbue(const locale& __loc)
|
|
|
|
{
|
|
|
|
sync();
|
|
|
|
__cv_ = &use_facet<codecvt<char_type, char, state_type> >(__loc);
|
|
|
|
bool __old_anc = __always_noconv_;
|
|
|
|
__always_noconv_ = __cv_->always_noconv();
|
|
|
|
if (__old_anc != __always_noconv_)
|
|
|
|
{
|
|
|
|
this->setg(0, 0, 0);
|
|
|
|
this->setp(0, 0);
|
|
|
|
// invariant, char_type is char, else we couldn't get here
|
|
|
|
if (__always_noconv_) // need to dump __intbuf_
|
|
|
|
{
|
|
|
|
if (__owns_eb_)
|
|
|
|
delete [] __extbuf_;
|
|
|
|
__owns_eb_ = __owns_ib_;
|
|
|
|
__ebs_ = __ibs_;
|
|
|
|
__extbuf_ = (char*)__intbuf_;
|
|
|
|
__ibs_ = 0;
|
|
|
|
__intbuf_ = 0;
|
|
|
|
__owns_ib_ = false;
|
|
|
|
}
|
|
|
|
else // need to obtain an __intbuf_.
|
|
|
|
{ // If __extbuf_ is user-supplied, use it, else new __intbuf_
|
|
|
|
if (!__owns_eb_ && __extbuf_ != __extbuf_min_)
|
|
|
|
{
|
|
|
|
__ibs_ = __ebs_;
|
|
|
|
__intbuf_ = (char_type*)__extbuf_;
|
|
|
|
__owns_ib_ = false;
|
|
|
|
__extbuf_ = new char[__ebs_];
|
|
|
|
__owns_eb_ = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
__ibs_ = __ebs_;
|
|
|
|
__intbuf_ = new char_type[__ibs_];
|
|
|
|
__owns_ib_ = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
bool
|
|
|
|
basic_filebuf<_CharT, _Traits>::__read_mode()
|
|
|
|
{
|
|
|
|
if (!(__cm_ & ios_base::in))
|
|
|
|
{
|
|
|
|
this->setp(0, 0);
|
|
|
|
if (__always_noconv_)
|
|
|
|
this->setg((char_type*)__extbuf_,
|
|
|
|
(char_type*)__extbuf_ + __ebs_,
|
|
|
|
(char_type*)__extbuf_ + __ebs_);
|
|
|
|
else
|
|
|
|
this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_);
|
|
|
|
__cm_ = ios_base::in;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
void
|
|
|
|
basic_filebuf<_CharT, _Traits>::__write_mode()
|
|
|
|
{
|
|
|
|
if (!(__cm_ & ios_base::out))
|
|
|
|
{
|
|
|
|
this->setg(0, 0, 0);
|
|
|
|
if (__ebs_ > sizeof(__extbuf_min_))
|
|
|
|
{
|
|
|
|
if (__always_noconv_)
|
|
|
|
this->setp((char_type*)__extbuf_,
|
|
|
|
(char_type*)__extbuf_ + (__ebs_ - 1));
|
|
|
|
else
|
|
|
|
this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
this->setp(0, 0);
|
|
|
|
__cm_ = ios_base::out;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// basic_ifstream
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
2017-01-05 07:56:00 +08:00
|
|
|
class _LIBCPP_TEMPLATE_VIS basic_ifstream
|
2010-05-12 03:42:16 +08:00
|
|
|
: public basic_istream<_CharT, _Traits>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
typedef _CharT char_type;
|
|
|
|
typedef _Traits traits_type;
|
|
|
|
typedef typename traits_type::int_type int_type;
|
|
|
|
typedef typename traits_type::pos_type pos_type;
|
|
|
|
typedef typename traits_type::off_type off_type;
|
|
|
|
|
2016-04-22 09:04:55 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_ifstream();
|
Add option to disable access to the global filesystem namespace.
Systems like FreeBSD's Capsicum and Nuxi CloudABI apply the concept of
capability-based security on the way processes can interact with the
filesystem API. It is no longer possible to interact with the VFS
through calls like open(), unlink(), rename(), etc. Instead, processes
are only allowed to interact with files and directories to which they
have been granted access. The *at() functions can be used for this
purpose.
This change adds a new config switch called
_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE. If set, all functionality
that requires the global filesystem namespace will be disabled. More
concretely:
- fstream's open() function will be removed.
- cstdio will no longer pull in fopen(), rename(), etc.
- The test suite's get_temp_file_name() will be removed. This will cause
all tests that use the global filesystem namespace to break, but will
at least make all the other tests run (as get_temp_file_name will not
build anyway).
It is important to mention that this change will make fstream rather
useless on those systems for now. Still, I'd rather not have fstream
disabled entirely, as it is of course possible to come up with an
extension for fstream that would allow access to local filesystem
namespaces (e.g., by adding an openat() member function).
Differential revision: http://reviews.llvm.org/D8194
Reviewed by: jroelofs (thanks!)
llvm-svn: 232049
2015-03-12 23:44:39 +08:00
|
|
|
#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
|
2016-04-22 09:04:55 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
explicit basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in);
|
2018-01-23 10:07:27 +08:00
|
|
|
#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
explicit basic_ifstream(const wchar_t* __s, ios_base::openmode __mode = ios_base::in);
|
|
|
|
#endif
|
2016-04-22 09:04:55 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
explicit basic_ifstream(const string& __s, ios_base::openmode __mode = ios_base::in);
|
Implement <filesystem>
This patch implements the <filesystem> header and uses that
to provide <experimental/filesystem>.
Unlike other standard headers, the symbols needed for <filesystem>
have not yet been placed in libc++.so. Instead they live in the
new libc++fs.a library. Users of filesystem are required to link this
library. (Also note that libc++experimental no longer contains the
definition of <experimental/filesystem>, which now requires linking libc++fs).
The reason for keeping <filesystem> out of the dylib for now is that
it's still somewhat experimental, and the possibility of requiring an
ABI breaking change is very real. In the future the symbols will likely
be moved into the dylib, or the dylib will be made to link libc++fs automagically).
Note that moving the symbols out of libc++experimental may break user builds
until they update to -lc++fs. This should be OK, because the experimental
library provides no stability guarantees. However, I plan on looking into
ways we can force libc++experimental to automagically link libc++fs.
In order to use a single implementation and set of tests for <filesystem>, it
has been placed in a special `__fs` namespace. This namespace is inline in
C++17 onward, but not before that. As such implementation is available
in C++11 onward, but no filesystem namespace is present "directly", and
as such name conflicts shouldn't occur in C++11 or C++14.
llvm-svn: 338093
2018-07-27 11:07:09 +08:00
|
|
|
#if _LIBCPP_STD_VER >= 17
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
explicit basic_ifstream(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in)
|
|
|
|
: basic_ifstream(__p.c_str(), __mode) {}
|
|
|
|
#endif // _LIBCPP_STD_VER >= 17
|
Add option to disable access to the global filesystem namespace.
Systems like FreeBSD's Capsicum and Nuxi CloudABI apply the concept of
capability-based security on the way processes can interact with the
filesystem API. It is no longer possible to interact with the VFS
through calls like open(), unlink(), rename(), etc. Instead, processes
are only allowed to interact with files and directories to which they
have been granted access. The *at() functions can be used for this
purpose.
This change adds a new config switch called
_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE. If set, all functionality
that requires the global filesystem namespace will be disabled. More
concretely:
- fstream's open() function will be removed.
- cstdio will no longer pull in fopen(), rename(), etc.
- The test suite's get_temp_file_name() will be removed. This will cause
all tests that use the global filesystem namespace to break, but will
at least make all the other tests run (as get_temp_file_name will not
build anyway).
It is important to mention that this change will make fstream rather
useless on those systems for now. Still, I'd rather not have fstream
disabled entirely, as it is of course possible to come up with an
extension for fstream that would allow access to local filesystem
namespaces (e.g., by adding an openat() member function).
Differential revision: http://reviews.llvm.org/D8194
Reviewed by: jroelofs (thanks!)
llvm-svn: 232049
2015-03-12 23:44:39 +08:00
|
|
|
#endif
|
2017-04-19 07:38:41 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2016-04-22 09:04:55 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_ifstream(basic_ifstream&& __rhs);
|
|
|
|
|
2016-04-22 09:04:55 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_ifstream& operator=(basic_ifstream&& __rhs);
|
|
|
|
#endif
|
2016-04-22 09:04:55 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
void swap(basic_ifstream& __rhs);
|
|
|
|
|
2016-04-22 09:04:55 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_filebuf<char_type, traits_type>* rdbuf() const;
|
2016-04-22 09:04:55 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
bool is_open() const;
|
Add option to disable access to the global filesystem namespace.
Systems like FreeBSD's Capsicum and Nuxi CloudABI apply the concept of
capability-based security on the way processes can interact with the
filesystem API. It is no longer possible to interact with the VFS
through calls like open(), unlink(), rename(), etc. Instead, processes
are only allowed to interact with files and directories to which they
have been granted access. The *at() functions can be used for this
purpose.
This change adds a new config switch called
_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE. If set, all functionality
that requires the global filesystem namespace will be disabled. More
concretely:
- fstream's open() function will be removed.
- cstdio will no longer pull in fopen(), rename(), etc.
- The test suite's get_temp_file_name() will be removed. This will cause
all tests that use the global filesystem namespace to break, but will
at least make all the other tests run (as get_temp_file_name will not
build anyway).
It is important to mention that this change will make fstream rather
useless on those systems for now. Still, I'd rather not have fstream
disabled entirely, as it is of course possible to come up with an
extension for fstream that would allow access to local filesystem
namespaces (e.g., by adding an openat() member function).
Differential revision: http://reviews.llvm.org/D8194
Reviewed by: jroelofs (thanks!)
llvm-svn: 232049
2015-03-12 23:44:39 +08:00
|
|
|
#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
|
2010-05-12 03:42:16 +08:00
|
|
|
void open(const char* __s, ios_base::openmode __mode = ios_base::in);
|
2018-01-23 10:07:27 +08:00
|
|
|
#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
|
|
|
|
void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in);
|
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
void open(const string& __s, ios_base::openmode __mode = ios_base::in);
|
Implement <filesystem>
This patch implements the <filesystem> header and uses that
to provide <experimental/filesystem>.
Unlike other standard headers, the symbols needed for <filesystem>
have not yet been placed in libc++.so. Instead they live in the
new libc++fs.a library. Users of filesystem are required to link this
library. (Also note that libc++experimental no longer contains the
definition of <experimental/filesystem>, which now requires linking libc++fs).
The reason for keeping <filesystem> out of the dylib for now is that
it's still somewhat experimental, and the possibility of requiring an
ABI breaking change is very real. In the future the symbols will likely
be moved into the dylib, or the dylib will be made to link libc++fs automagically).
Note that moving the symbols out of libc++experimental may break user builds
until they update to -lc++fs. This should be OK, because the experimental
library provides no stability guarantees. However, I plan on looking into
ways we can force libc++experimental to automagically link libc++fs.
In order to use a single implementation and set of tests for <filesystem>, it
has been placed in a special `__fs` namespace. This namespace is inline in
C++17 onward, but not before that. As such implementation is available
in C++11 onward, but no filesystem namespace is present "directly", and
as such name conflicts shouldn't occur in C++11 or C++14.
llvm-svn: 338093
2018-07-27 11:07:09 +08:00
|
|
|
#if _LIBCPP_STD_VER >= 17
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
void open(const filesystem::path& __p,
|
|
|
|
ios_base::openmode __mode = ios_base::in) {
|
|
|
|
return open(__p.c_str(), __mode);
|
|
|
|
}
|
|
|
|
#endif // _LIBCPP_STD_VER >= 17
|
2018-07-22 10:00:53 +08:00
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
void __open(int __fd, ios_base::openmode __mode);
|
Add option to disable access to the global filesystem namespace.
Systems like FreeBSD's Capsicum and Nuxi CloudABI apply the concept of
capability-based security on the way processes can interact with the
filesystem API. It is no longer possible to interact with the VFS
through calls like open(), unlink(), rename(), etc. Instead, processes
are only allowed to interact with files and directories to which they
have been granted access. The *at() functions can be used for this
purpose.
This change adds a new config switch called
_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE. If set, all functionality
that requires the global filesystem namespace will be disabled. More
concretely:
- fstream's open() function will be removed.
- cstdio will no longer pull in fopen(), rename(), etc.
- The test suite's get_temp_file_name() will be removed. This will cause
all tests that use the global filesystem namespace to break, but will
at least make all the other tests run (as get_temp_file_name will not
build anyway).
It is important to mention that this change will make fstream rather
useless on those systems for now. Still, I'd rather not have fstream
disabled entirely, as it is of course possible to come up with an
extension for fstream that would allow access to local filesystem
namespaces (e.g., by adding an openat() member function).
Differential revision: http://reviews.llvm.org/D8194
Reviewed by: jroelofs (thanks!)
llvm-svn: 232049
2015-03-12 23:44:39 +08:00
|
|
|
#endif
|
2016-04-22 09:04:55 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
void close();
|
|
|
|
|
|
|
|
private:
|
|
|
|
basic_filebuf<char_type, traits_type> __sb_;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
2016-04-22 09:04:55 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_ifstream<_CharT, _Traits>::basic_ifstream()
|
|
|
|
: basic_istream<char_type, traits_type>(&__sb_)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
Add option to disable access to the global filesystem namespace.
Systems like FreeBSD's Capsicum and Nuxi CloudABI apply the concept of
capability-based security on the way processes can interact with the
filesystem API. It is no longer possible to interact with the VFS
through calls like open(), unlink(), rename(), etc. Instead, processes
are only allowed to interact with files and directories to which they
have been granted access. The *at() functions can be used for this
purpose.
This change adds a new config switch called
_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE. If set, all functionality
that requires the global filesystem namespace will be disabled. More
concretely:
- fstream's open() function will be removed.
- cstdio will no longer pull in fopen(), rename(), etc.
- The test suite's get_temp_file_name() will be removed. This will cause
all tests that use the global filesystem namespace to break, but will
at least make all the other tests run (as get_temp_file_name will not
build anyway).
It is important to mention that this change will make fstream rather
useless on those systems for now. Still, I'd rather not have fstream
disabled entirely, as it is of course possible to come up with an
extension for fstream that would allow access to local filesystem
namespaces (e.g., by adding an openat() member function).
Differential revision: http://reviews.llvm.org/D8194
Reviewed by: jroelofs (thanks!)
llvm-svn: 232049
2015-03-12 23:44:39 +08:00
|
|
|
#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _CharT, class _Traits>
|
2016-04-22 09:04:55 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_ifstream<_CharT, _Traits>::basic_ifstream(const char* __s, ios_base::openmode __mode)
|
|
|
|
: basic_istream<char_type, traits_type>(&__sb_)
|
|
|
|
{
|
|
|
|
if (__sb_.open(__s, __mode | ios_base::in) == 0)
|
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
|
|
|
|
2018-01-23 10:07:27 +08:00
|
|
|
#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline
|
|
|
|
basic_ifstream<_CharT, _Traits>::basic_ifstream(const wchar_t* __s, ios_base::openmode __mode)
|
|
|
|
: basic_istream<char_type, traits_type>(&__sb_)
|
|
|
|
{
|
|
|
|
if (__sb_.open(__s, __mode | ios_base::in) == 0)
|
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _CharT, class _Traits>
|
2016-04-22 09:04:55 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_ifstream<_CharT, _Traits>::basic_ifstream(const string& __s, ios_base::openmode __mode)
|
|
|
|
: basic_istream<char_type, traits_type>(&__sb_)
|
|
|
|
{
|
|
|
|
if (__sb_.open(__s, __mode | ios_base::in) == 0)
|
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
Add option to disable access to the global filesystem namespace.
Systems like FreeBSD's Capsicum and Nuxi CloudABI apply the concept of
capability-based security on the way processes can interact with the
filesystem API. It is no longer possible to interact with the VFS
through calls like open(), unlink(), rename(), etc. Instead, processes
are only allowed to interact with files and directories to which they
have been granted access. The *at() functions can be used for this
purpose.
This change adds a new config switch called
_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE. If set, all functionality
that requires the global filesystem namespace will be disabled. More
concretely:
- fstream's open() function will be removed.
- cstdio will no longer pull in fopen(), rename(), etc.
- The test suite's get_temp_file_name() will be removed. This will cause
all tests that use the global filesystem namespace to break, but will
at least make all the other tests run (as get_temp_file_name will not
build anyway).
It is important to mention that this change will make fstream rather
useless on those systems for now. Still, I'd rather not have fstream
disabled entirely, as it is of course possible to come up with an
extension for fstream that would allow access to local filesystem
namespaces (e.g., by adding an openat() member function).
Differential revision: http://reviews.llvm.org/D8194
Reviewed by: jroelofs (thanks!)
llvm-svn: 232049
2015-03-12 23:44:39 +08:00
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2017-04-19 07:38:41 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
2016-04-22 09:04:55 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_ifstream<_CharT, _Traits>::basic_ifstream(basic_ifstream&& __rhs)
|
2011-07-01 05:18:19 +08:00
|
|
|
: basic_istream<char_type, traits_type>(_VSTD::move(__rhs)),
|
|
|
|
__sb_(_VSTD::move(__rhs.__sb_))
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
this->set_rdbuf(&__sb_);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
2016-04-22 09:04:55 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_ifstream<_CharT, _Traits>&
|
|
|
|
basic_ifstream<_CharT, _Traits>::operator=(basic_ifstream&& __rhs)
|
|
|
|
{
|
2011-07-01 05:18:19 +08:00
|
|
|
basic_istream<char_type, traits_type>::operator=(_VSTD::move(__rhs));
|
|
|
|
__sb_ = _VSTD::move(__rhs.__sb_);
|
2010-05-12 03:42:16 +08:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2017-04-19 07:38:41 +08:00
|
|
|
#endif // _LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
2016-04-22 09:04:55 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
void
|
|
|
|
basic_ifstream<_CharT, _Traits>::swap(basic_ifstream& __rhs)
|
|
|
|
{
|
|
|
|
basic_istream<char_type, traits_type>::swap(__rhs);
|
|
|
|
__sb_.swap(__rhs.__sb_);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
|
|
void
|
|
|
|
swap(basic_ifstream<_CharT, _Traits>& __x, basic_ifstream<_CharT, _Traits>& __y)
|
|
|
|
{
|
|
|
|
__x.swap(__y);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
2016-04-22 09:04:55 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_filebuf<_CharT, _Traits>*
|
|
|
|
basic_ifstream<_CharT, _Traits>::rdbuf() const
|
|
|
|
{
|
|
|
|
return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
2016-04-22 09:04:55 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
|
|
|
basic_ifstream<_CharT, _Traits>::is_open() const
|
|
|
|
{
|
|
|
|
return __sb_.is_open();
|
|
|
|
}
|
|
|
|
|
Add option to disable access to the global filesystem namespace.
Systems like FreeBSD's Capsicum and Nuxi CloudABI apply the concept of
capability-based security on the way processes can interact with the
filesystem API. It is no longer possible to interact with the VFS
through calls like open(), unlink(), rename(), etc. Instead, processes
are only allowed to interact with files and directories to which they
have been granted access. The *at() functions can be used for this
purpose.
This change adds a new config switch called
_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE. If set, all functionality
that requires the global filesystem namespace will be disabled. More
concretely:
- fstream's open() function will be removed.
- cstdio will no longer pull in fopen(), rename(), etc.
- The test suite's get_temp_file_name() will be removed. This will cause
all tests that use the global filesystem namespace to break, but will
at least make all the other tests run (as get_temp_file_name will not
build anyway).
It is important to mention that this change will make fstream rather
useless on those systems for now. Still, I'd rather not have fstream
disabled entirely, as it is of course possible to come up with an
extension for fstream that would allow access to local filesystem
namespaces (e.g., by adding an openat() member function).
Differential revision: http://reviews.llvm.org/D8194
Reviewed by: jroelofs (thanks!)
llvm-svn: 232049
2015-03-12 23:44:39 +08:00
|
|
|
#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
void
|
|
|
|
basic_ifstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode)
|
|
|
|
{
|
|
|
|
if (__sb_.open(__s, __mode | ios_base::in))
|
|
|
|
this->clear();
|
|
|
|
else
|
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
|
|
|
|
2018-01-23 10:07:27 +08:00
|
|
|
#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
void
|
|
|
|
basic_ifstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode)
|
|
|
|
{
|
|
|
|
if (__sb_.open(__s, __mode | ios_base::in))
|
|
|
|
this->clear();
|
|
|
|
else
|
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
void
|
|
|
|
basic_ifstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode)
|
|
|
|
{
|
|
|
|
if (__sb_.open(__s, __mode | ios_base::in))
|
|
|
|
this->clear();
|
|
|
|
else
|
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
2018-07-22 10:00:53 +08:00
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
void basic_ifstream<_CharT, _Traits>::__open(int __fd,
|
|
|
|
ios_base::openmode __mode) {
|
|
|
|
if (__sb_.__open(__fd, __mode | ios_base::in))
|
|
|
|
this->clear();
|
|
|
|
else
|
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
Add option to disable access to the global filesystem namespace.
Systems like FreeBSD's Capsicum and Nuxi CloudABI apply the concept of
capability-based security on the way processes can interact with the
filesystem API. It is no longer possible to interact with the VFS
through calls like open(), unlink(), rename(), etc. Instead, processes
are only allowed to interact with files and directories to which they
have been granted access. The *at() functions can be used for this
purpose.
This change adds a new config switch called
_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE. If set, all functionality
that requires the global filesystem namespace will be disabled. More
concretely:
- fstream's open() function will be removed.
- cstdio will no longer pull in fopen(), rename(), etc.
- The test suite's get_temp_file_name() will be removed. This will cause
all tests that use the global filesystem namespace to break, but will
at least make all the other tests run (as get_temp_file_name will not
build anyway).
It is important to mention that this change will make fstream rather
useless on those systems for now. Still, I'd rather not have fstream
disabled entirely, as it is of course possible to come up with an
extension for fstream that would allow access to local filesystem
namespaces (e.g., by adding an openat() member function).
Differential revision: http://reviews.llvm.org/D8194
Reviewed by: jroelofs (thanks!)
llvm-svn: 232049
2015-03-12 23:44:39 +08:00
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
2016-04-22 09:04:55 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
void
|
|
|
|
basic_ifstream<_CharT, _Traits>::close()
|
|
|
|
{
|
|
|
|
if (__sb_.close() == 0)
|
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
|
|
|
|
|
|
|
// basic_ofstream
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
2017-01-05 07:56:00 +08:00
|
|
|
class _LIBCPP_TEMPLATE_VIS basic_ofstream
|
2010-05-12 03:42:16 +08:00
|
|
|
: public basic_ostream<_CharT, _Traits>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
typedef _CharT char_type;
|
|
|
|
typedef _Traits traits_type;
|
|
|
|
typedef typename traits_type::int_type int_type;
|
|
|
|
typedef typename traits_type::pos_type pos_type;
|
|
|
|
typedef typename traits_type::off_type off_type;
|
|
|
|
|
2016-04-22 09:04:55 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_ofstream();
|
2016-04-22 09:04:55 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
explicit basic_ofstream(const char* __s, ios_base::openmode __mode = ios_base::out);
|
2018-01-23 10:07:27 +08:00
|
|
|
#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
explicit basic_ofstream(const wchar_t* __s, ios_base::openmode __mode = ios_base::out);
|
|
|
|
#endif
|
2016-04-22 09:04:55 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
explicit basic_ofstream(const string& __s, ios_base::openmode __mode = ios_base::out);
|
Implement <filesystem>
This patch implements the <filesystem> header and uses that
to provide <experimental/filesystem>.
Unlike other standard headers, the symbols needed for <filesystem>
have not yet been placed in libc++.so. Instead they live in the
new libc++fs.a library. Users of filesystem are required to link this
library. (Also note that libc++experimental no longer contains the
definition of <experimental/filesystem>, which now requires linking libc++fs).
The reason for keeping <filesystem> out of the dylib for now is that
it's still somewhat experimental, and the possibility of requiring an
ABI breaking change is very real. In the future the symbols will likely
be moved into the dylib, or the dylib will be made to link libc++fs automagically).
Note that moving the symbols out of libc++experimental may break user builds
until they update to -lc++fs. This should be OK, because the experimental
library provides no stability guarantees. However, I plan on looking into
ways we can force libc++experimental to automagically link libc++fs.
In order to use a single implementation and set of tests for <filesystem>, it
has been placed in a special `__fs` namespace. This namespace is inline in
C++17 onward, but not before that. As such implementation is available
in C++11 onward, but no filesystem namespace is present "directly", and
as such name conflicts shouldn't occur in C++11 or C++14.
llvm-svn: 338093
2018-07-27 11:07:09 +08:00
|
|
|
|
|
|
|
#if _LIBCPP_STD_VER >= 17
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
explicit basic_ofstream(const filesystem::path& __p, ios_base::openmode __mode = ios_base::out)
|
|
|
|
: basic_ofstream(__p.c_str(), __mode) {}
|
|
|
|
#endif // _LIBCPP_STD_VER >= 17
|
|
|
|
|
2017-04-19 07:38:41 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2016-04-22 09:04:55 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_ofstream(basic_ofstream&& __rhs);
|
|
|
|
|
2016-04-22 09:04:55 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_ofstream& operator=(basic_ofstream&& __rhs);
|
|
|
|
#endif
|
2016-04-22 09:04:55 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
void swap(basic_ofstream& __rhs);
|
|
|
|
|
2016-04-22 09:04:55 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_filebuf<char_type, traits_type>* rdbuf() const;
|
2016-04-22 09:04:55 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
bool is_open() const;
|
Add option to disable access to the global filesystem namespace.
Systems like FreeBSD's Capsicum and Nuxi CloudABI apply the concept of
capability-based security on the way processes can interact with the
filesystem API. It is no longer possible to interact with the VFS
through calls like open(), unlink(), rename(), etc. Instead, processes
are only allowed to interact with files and directories to which they
have been granted access. The *at() functions can be used for this
purpose.
This change adds a new config switch called
_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE. If set, all functionality
that requires the global filesystem namespace will be disabled. More
concretely:
- fstream's open() function will be removed.
- cstdio will no longer pull in fopen(), rename(), etc.
- The test suite's get_temp_file_name() will be removed. This will cause
all tests that use the global filesystem namespace to break, but will
at least make all the other tests run (as get_temp_file_name will not
build anyway).
It is important to mention that this change will make fstream rather
useless on those systems for now. Still, I'd rather not have fstream
disabled entirely, as it is of course possible to come up with an
extension for fstream that would allow access to local filesystem
namespaces (e.g., by adding an openat() member function).
Differential revision: http://reviews.llvm.org/D8194
Reviewed by: jroelofs (thanks!)
llvm-svn: 232049
2015-03-12 23:44:39 +08:00
|
|
|
#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
|
2010-05-12 03:42:16 +08:00
|
|
|
void open(const char* __s, ios_base::openmode __mode = ios_base::out);
|
2018-01-23 10:07:27 +08:00
|
|
|
#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
|
|
|
|
void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::out);
|
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
void open(const string& __s, ios_base::openmode __mode = ios_base::out);
|
2018-07-22 10:00:53 +08:00
|
|
|
|
Implement <filesystem>
This patch implements the <filesystem> header and uses that
to provide <experimental/filesystem>.
Unlike other standard headers, the symbols needed for <filesystem>
have not yet been placed in libc++.so. Instead they live in the
new libc++fs.a library. Users of filesystem are required to link this
library. (Also note that libc++experimental no longer contains the
definition of <experimental/filesystem>, which now requires linking libc++fs).
The reason for keeping <filesystem> out of the dylib for now is that
it's still somewhat experimental, and the possibility of requiring an
ABI breaking change is very real. In the future the symbols will likely
be moved into the dylib, or the dylib will be made to link libc++fs automagically).
Note that moving the symbols out of libc++experimental may break user builds
until they update to -lc++fs. This should be OK, because the experimental
library provides no stability guarantees. However, I plan on looking into
ways we can force libc++experimental to automagically link libc++fs.
In order to use a single implementation and set of tests for <filesystem>, it
has been placed in a special `__fs` namespace. This namespace is inline in
C++17 onward, but not before that. As such implementation is available
in C++11 onward, but no filesystem namespace is present "directly", and
as such name conflicts shouldn't occur in C++11 or C++14.
llvm-svn: 338093
2018-07-27 11:07:09 +08:00
|
|
|
#if _LIBCPP_STD_VER >= 17
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
void open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::out)
|
|
|
|
{ return open(__p.c_str(), __mode); }
|
|
|
|
#endif // _LIBCPP_STD_VER >= 17
|
|
|
|
|
2018-07-22 10:00:53 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
void __open(int __fd, ios_base::openmode __mode);
|
Add option to disable access to the global filesystem namespace.
Systems like FreeBSD's Capsicum and Nuxi CloudABI apply the concept of
capability-based security on the way processes can interact with the
filesystem API. It is no longer possible to interact with the VFS
through calls like open(), unlink(), rename(), etc. Instead, processes
are only allowed to interact with files and directories to which they
have been granted access. The *at() functions can be used for this
purpose.
This change adds a new config switch called
_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE. If set, all functionality
that requires the global filesystem namespace will be disabled. More
concretely:
- fstream's open() function will be removed.
- cstdio will no longer pull in fopen(), rename(), etc.
- The test suite's get_temp_file_name() will be removed. This will cause
all tests that use the global filesystem namespace to break, but will
at least make all the other tests run (as get_temp_file_name will not
build anyway).
It is important to mention that this change will make fstream rather
useless on those systems for now. Still, I'd rather not have fstream
disabled entirely, as it is of course possible to come up with an
extension for fstream that would allow access to local filesystem
namespaces (e.g., by adding an openat() member function).
Differential revision: http://reviews.llvm.org/D8194
Reviewed by: jroelofs (thanks!)
llvm-svn: 232049
2015-03-12 23:44:39 +08:00
|
|
|
#endif
|
2016-04-22 09:04:55 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
void close();
|
|
|
|
|
|
|
|
private:
|
|
|
|
basic_filebuf<char_type, traits_type> __sb_;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
2016-04-22 09:04:55 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_ofstream<_CharT, _Traits>::basic_ofstream()
|
|
|
|
: basic_ostream<char_type, traits_type>(&__sb_)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
Add option to disable access to the global filesystem namespace.
Systems like FreeBSD's Capsicum and Nuxi CloudABI apply the concept of
capability-based security on the way processes can interact with the
filesystem API. It is no longer possible to interact with the VFS
through calls like open(), unlink(), rename(), etc. Instead, processes
are only allowed to interact with files and directories to which they
have been granted access. The *at() functions can be used for this
purpose.
This change adds a new config switch called
_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE. If set, all functionality
that requires the global filesystem namespace will be disabled. More
concretely:
- fstream's open() function will be removed.
- cstdio will no longer pull in fopen(), rename(), etc.
- The test suite's get_temp_file_name() will be removed. This will cause
all tests that use the global filesystem namespace to break, but will
at least make all the other tests run (as get_temp_file_name will not
build anyway).
It is important to mention that this change will make fstream rather
useless on those systems for now. Still, I'd rather not have fstream
disabled entirely, as it is of course possible to come up with an
extension for fstream that would allow access to local filesystem
namespaces (e.g., by adding an openat() member function).
Differential revision: http://reviews.llvm.org/D8194
Reviewed by: jroelofs (thanks!)
llvm-svn: 232049
2015-03-12 23:44:39 +08:00
|
|
|
#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _CharT, class _Traits>
|
2016-04-22 09:04:55 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_ofstream<_CharT, _Traits>::basic_ofstream(const char* __s, ios_base::openmode __mode)
|
|
|
|
: basic_ostream<char_type, traits_type>(&__sb_)
|
|
|
|
{
|
|
|
|
if (__sb_.open(__s, __mode | ios_base::out) == 0)
|
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
|
|
|
|
2018-01-23 10:07:27 +08:00
|
|
|
#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline
|
|
|
|
basic_ofstream<_CharT, _Traits>::basic_ofstream(const wchar_t* __s, ios_base::openmode __mode)
|
|
|
|
: basic_ostream<char_type, traits_type>(&__sb_)
|
|
|
|
{
|
|
|
|
if (__sb_.open(__s, __mode | ios_base::out) == 0)
|
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _CharT, class _Traits>
|
2016-04-22 09:04:55 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_ofstream<_CharT, _Traits>::basic_ofstream(const string& __s, ios_base::openmode __mode)
|
|
|
|
: basic_ostream<char_type, traits_type>(&__sb_)
|
|
|
|
{
|
|
|
|
if (__sb_.open(__s, __mode | ios_base::out) == 0)
|
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
Add option to disable access to the global filesystem namespace.
Systems like FreeBSD's Capsicum and Nuxi CloudABI apply the concept of
capability-based security on the way processes can interact with the
filesystem API. It is no longer possible to interact with the VFS
through calls like open(), unlink(), rename(), etc. Instead, processes
are only allowed to interact with files and directories to which they
have been granted access. The *at() functions can be used for this
purpose.
This change adds a new config switch called
_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE. If set, all functionality
that requires the global filesystem namespace will be disabled. More
concretely:
- fstream's open() function will be removed.
- cstdio will no longer pull in fopen(), rename(), etc.
- The test suite's get_temp_file_name() will be removed. This will cause
all tests that use the global filesystem namespace to break, but will
at least make all the other tests run (as get_temp_file_name will not
build anyway).
It is important to mention that this change will make fstream rather
useless on those systems for now. Still, I'd rather not have fstream
disabled entirely, as it is of course possible to come up with an
extension for fstream that would allow access to local filesystem
namespaces (e.g., by adding an openat() member function).
Differential revision: http://reviews.llvm.org/D8194
Reviewed by: jroelofs (thanks!)
llvm-svn: 232049
2015-03-12 23:44:39 +08:00
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2017-04-19 07:38:41 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
2016-04-22 09:04:55 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_ofstream<_CharT, _Traits>::basic_ofstream(basic_ofstream&& __rhs)
|
2011-07-01 05:18:19 +08:00
|
|
|
: basic_ostream<char_type, traits_type>(_VSTD::move(__rhs)),
|
|
|
|
__sb_(_VSTD::move(__rhs.__sb_))
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
this->set_rdbuf(&__sb_);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
2016-04-22 09:04:55 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_ofstream<_CharT, _Traits>&
|
|
|
|
basic_ofstream<_CharT, _Traits>::operator=(basic_ofstream&& __rhs)
|
|
|
|
{
|
2011-07-01 05:18:19 +08:00
|
|
|
basic_ostream<char_type, traits_type>::operator=(_VSTD::move(__rhs));
|
|
|
|
__sb_ = _VSTD::move(__rhs.__sb_);
|
2010-05-12 03:42:16 +08:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2017-04-19 07:38:41 +08:00
|
|
|
#endif // _LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
2016-04-22 09:04:55 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
void
|
|
|
|
basic_ofstream<_CharT, _Traits>::swap(basic_ofstream& __rhs)
|
|
|
|
{
|
|
|
|
basic_ostream<char_type, traits_type>::swap(__rhs);
|
|
|
|
__sb_.swap(__rhs.__sb_);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
|
|
void
|
|
|
|
swap(basic_ofstream<_CharT, _Traits>& __x, basic_ofstream<_CharT, _Traits>& __y)
|
|
|
|
{
|
|
|
|
__x.swap(__y);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
2016-04-22 09:04:55 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_filebuf<_CharT, _Traits>*
|
|
|
|
basic_ofstream<_CharT, _Traits>::rdbuf() const
|
|
|
|
{
|
|
|
|
return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
2016-04-22 09:04:55 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
|
|
|
basic_ofstream<_CharT, _Traits>::is_open() const
|
|
|
|
{
|
|
|
|
return __sb_.is_open();
|
|
|
|
}
|
|
|
|
|
Add option to disable access to the global filesystem namespace.
Systems like FreeBSD's Capsicum and Nuxi CloudABI apply the concept of
capability-based security on the way processes can interact with the
filesystem API. It is no longer possible to interact with the VFS
through calls like open(), unlink(), rename(), etc. Instead, processes
are only allowed to interact with files and directories to which they
have been granted access. The *at() functions can be used for this
purpose.
This change adds a new config switch called
_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE. If set, all functionality
that requires the global filesystem namespace will be disabled. More
concretely:
- fstream's open() function will be removed.
- cstdio will no longer pull in fopen(), rename(), etc.
- The test suite's get_temp_file_name() will be removed. This will cause
all tests that use the global filesystem namespace to break, but will
at least make all the other tests run (as get_temp_file_name will not
build anyway).
It is important to mention that this change will make fstream rather
useless on those systems for now. Still, I'd rather not have fstream
disabled entirely, as it is of course possible to come up with an
extension for fstream that would allow access to local filesystem
namespaces (e.g., by adding an openat() member function).
Differential revision: http://reviews.llvm.org/D8194
Reviewed by: jroelofs (thanks!)
llvm-svn: 232049
2015-03-12 23:44:39 +08:00
|
|
|
#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
void
|
|
|
|
basic_ofstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode)
|
|
|
|
{
|
|
|
|
if (__sb_.open(__s, __mode | ios_base::out))
|
|
|
|
this->clear();
|
|
|
|
else
|
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
|
|
|
|
2018-01-23 10:07:27 +08:00
|
|
|
#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
void
|
|
|
|
basic_ofstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode)
|
|
|
|
{
|
|
|
|
if (__sb_.open(__s, __mode | ios_base::out))
|
|
|
|
this->clear();
|
|
|
|
else
|
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
void
|
|
|
|
basic_ofstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode)
|
|
|
|
{
|
|
|
|
if (__sb_.open(__s, __mode | ios_base::out))
|
|
|
|
this->clear();
|
|
|
|
else
|
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
2018-07-22 10:00:53 +08:00
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
void basic_ofstream<_CharT, _Traits>::__open(int __fd,
|
|
|
|
ios_base::openmode __mode) {
|
|
|
|
if (__sb_.__open(__fd, __mode | ios_base::out))
|
|
|
|
this->clear();
|
|
|
|
else
|
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
Add option to disable access to the global filesystem namespace.
Systems like FreeBSD's Capsicum and Nuxi CloudABI apply the concept of
capability-based security on the way processes can interact with the
filesystem API. It is no longer possible to interact with the VFS
through calls like open(), unlink(), rename(), etc. Instead, processes
are only allowed to interact with files and directories to which they
have been granted access. The *at() functions can be used for this
purpose.
This change adds a new config switch called
_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE. If set, all functionality
that requires the global filesystem namespace will be disabled. More
concretely:
- fstream's open() function will be removed.
- cstdio will no longer pull in fopen(), rename(), etc.
- The test suite's get_temp_file_name() will be removed. This will cause
all tests that use the global filesystem namespace to break, but will
at least make all the other tests run (as get_temp_file_name will not
build anyway).
It is important to mention that this change will make fstream rather
useless on those systems for now. Still, I'd rather not have fstream
disabled entirely, as it is of course possible to come up with an
extension for fstream that would allow access to local filesystem
namespaces (e.g., by adding an openat() member function).
Differential revision: http://reviews.llvm.org/D8194
Reviewed by: jroelofs (thanks!)
llvm-svn: 232049
2015-03-12 23:44:39 +08:00
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
2016-04-22 09:04:55 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
void
|
|
|
|
basic_ofstream<_CharT, _Traits>::close()
|
|
|
|
{
|
|
|
|
if (__sb_.close() == 0)
|
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
|
|
|
|
|
|
|
// basic_fstream
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
2017-01-05 07:56:00 +08:00
|
|
|
class _LIBCPP_TEMPLATE_VIS basic_fstream
|
2010-05-12 03:42:16 +08:00
|
|
|
: public basic_iostream<_CharT, _Traits>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
typedef _CharT char_type;
|
|
|
|
typedef _Traits traits_type;
|
|
|
|
typedef typename traits_type::int_type int_type;
|
|
|
|
typedef typename traits_type::pos_type pos_type;
|
|
|
|
typedef typename traits_type::off_type off_type;
|
|
|
|
|
2016-04-22 09:04:55 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_fstream();
|
Add option to disable access to the global filesystem namespace.
Systems like FreeBSD's Capsicum and Nuxi CloudABI apply the concept of
capability-based security on the way processes can interact with the
filesystem API. It is no longer possible to interact with the VFS
through calls like open(), unlink(), rename(), etc. Instead, processes
are only allowed to interact with files and directories to which they
have been granted access. The *at() functions can be used for this
purpose.
This change adds a new config switch called
_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE. If set, all functionality
that requires the global filesystem namespace will be disabled. More
concretely:
- fstream's open() function will be removed.
- cstdio will no longer pull in fopen(), rename(), etc.
- The test suite's get_temp_file_name() will be removed. This will cause
all tests that use the global filesystem namespace to break, but will
at least make all the other tests run (as get_temp_file_name will not
build anyway).
It is important to mention that this change will make fstream rather
useless on those systems for now. Still, I'd rather not have fstream
disabled entirely, as it is of course possible to come up with an
extension for fstream that would allow access to local filesystem
namespaces (e.g., by adding an openat() member function).
Differential revision: http://reviews.llvm.org/D8194
Reviewed by: jroelofs (thanks!)
llvm-svn: 232049
2015-03-12 23:44:39 +08:00
|
|
|
#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
|
2016-04-22 09:04:55 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
explicit basic_fstream(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
|
2018-01-23 10:07:27 +08:00
|
|
|
#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
explicit basic_fstream(const wchar_t* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
|
|
|
|
#endif
|
2016-04-22 09:04:55 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
explicit basic_fstream(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
|
Implement <filesystem>
This patch implements the <filesystem> header and uses that
to provide <experimental/filesystem>.
Unlike other standard headers, the symbols needed for <filesystem>
have not yet been placed in libc++.so. Instead they live in the
new libc++fs.a library. Users of filesystem are required to link this
library. (Also note that libc++experimental no longer contains the
definition of <experimental/filesystem>, which now requires linking libc++fs).
The reason for keeping <filesystem> out of the dylib for now is that
it's still somewhat experimental, and the possibility of requiring an
ABI breaking change is very real. In the future the symbols will likely
be moved into the dylib, or the dylib will be made to link libc++fs automagically).
Note that moving the symbols out of libc++experimental may break user builds
until they update to -lc++fs. This should be OK, because the experimental
library provides no stability guarantees. However, I plan on looking into
ways we can force libc++experimental to automagically link libc++fs.
In order to use a single implementation and set of tests for <filesystem>, it
has been placed in a special `__fs` namespace. This namespace is inline in
C++17 onward, but not before that. As such implementation is available
in C++11 onward, but no filesystem namespace is present "directly", and
as such name conflicts shouldn't occur in C++11 or C++14.
llvm-svn: 338093
2018-07-27 11:07:09 +08:00
|
|
|
|
|
|
|
#if _LIBCPP_STD_VER >= 17
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
explicit basic_fstream(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in | ios_base::out)
|
|
|
|
: basic_fstream(__p.c_str(), __mode) {}
|
|
|
|
#endif // _LIBCPP_STD_VER >= 17
|
|
|
|
|
Add option to disable access to the global filesystem namespace.
Systems like FreeBSD's Capsicum and Nuxi CloudABI apply the concept of
capability-based security on the way processes can interact with the
filesystem API. It is no longer possible to interact with the VFS
through calls like open(), unlink(), rename(), etc. Instead, processes
are only allowed to interact with files and directories to which they
have been granted access. The *at() functions can be used for this
purpose.
This change adds a new config switch called
_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE. If set, all functionality
that requires the global filesystem namespace will be disabled. More
concretely:
- fstream's open() function will be removed.
- cstdio will no longer pull in fopen(), rename(), etc.
- The test suite's get_temp_file_name() will be removed. This will cause
all tests that use the global filesystem namespace to break, but will
at least make all the other tests run (as get_temp_file_name will not
build anyway).
It is important to mention that this change will make fstream rather
useless on those systems for now. Still, I'd rather not have fstream
disabled entirely, as it is of course possible to come up with an
extension for fstream that would allow access to local filesystem
namespaces (e.g., by adding an openat() member function).
Differential revision: http://reviews.llvm.org/D8194
Reviewed by: jroelofs (thanks!)
llvm-svn: 232049
2015-03-12 23:44:39 +08:00
|
|
|
#endif
|
2017-04-19 07:38:41 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2016-04-22 09:04:55 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_fstream(basic_fstream&& __rhs);
|
|
|
|
|
2016-04-22 09:04:55 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_fstream& operator=(basic_fstream&& __rhs);
|
|
|
|
#endif
|
2016-04-22 09:04:55 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
void swap(basic_fstream& __rhs);
|
|
|
|
|
2016-04-22 09:04:55 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_filebuf<char_type, traits_type>* rdbuf() const;
|
2016-04-22 09:04:55 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
bool is_open() const;
|
Add option to disable access to the global filesystem namespace.
Systems like FreeBSD's Capsicum and Nuxi CloudABI apply the concept of
capability-based security on the way processes can interact with the
filesystem API. It is no longer possible to interact with the VFS
through calls like open(), unlink(), rename(), etc. Instead, processes
are only allowed to interact with files and directories to which they
have been granted access. The *at() functions can be used for this
purpose.
This change adds a new config switch called
_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE. If set, all functionality
that requires the global filesystem namespace will be disabled. More
concretely:
- fstream's open() function will be removed.
- cstdio will no longer pull in fopen(), rename(), etc.
- The test suite's get_temp_file_name() will be removed. This will cause
all tests that use the global filesystem namespace to break, but will
at least make all the other tests run (as get_temp_file_name will not
build anyway).
It is important to mention that this change will make fstream rather
useless on those systems for now. Still, I'd rather not have fstream
disabled entirely, as it is of course possible to come up with an
extension for fstream that would allow access to local filesystem
namespaces (e.g., by adding an openat() member function).
Differential revision: http://reviews.llvm.org/D8194
Reviewed by: jroelofs (thanks!)
llvm-svn: 232049
2015-03-12 23:44:39 +08:00
|
|
|
#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
|
2010-05-12 03:42:16 +08:00
|
|
|
void open(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
|
2018-01-23 10:07:27 +08:00
|
|
|
#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
|
|
|
|
void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
|
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
void open(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
|
Implement <filesystem>
This patch implements the <filesystem> header and uses that
to provide <experimental/filesystem>.
Unlike other standard headers, the symbols needed for <filesystem>
have not yet been placed in libc++.so. Instead they live in the
new libc++fs.a library. Users of filesystem are required to link this
library. (Also note that libc++experimental no longer contains the
definition of <experimental/filesystem>, which now requires linking libc++fs).
The reason for keeping <filesystem> out of the dylib for now is that
it's still somewhat experimental, and the possibility of requiring an
ABI breaking change is very real. In the future the symbols will likely
be moved into the dylib, or the dylib will be made to link libc++fs automagically).
Note that moving the symbols out of libc++experimental may break user builds
until they update to -lc++fs. This should be OK, because the experimental
library provides no stability guarantees. However, I plan on looking into
ways we can force libc++experimental to automagically link libc++fs.
In order to use a single implementation and set of tests for <filesystem>, it
has been placed in a special `__fs` namespace. This namespace is inline in
C++17 onward, but not before that. As such implementation is available
in C++11 onward, but no filesystem namespace is present "directly", and
as such name conflicts shouldn't occur in C++11 or C++14.
llvm-svn: 338093
2018-07-27 11:07:09 +08:00
|
|
|
|
|
|
|
#if _LIBCPP_STD_VER >= 17
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
void open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in|ios_base::out)
|
|
|
|
{ return open(__p.c_str(), __mode); }
|
|
|
|
#endif // _LIBCPP_STD_VER >= 17
|
|
|
|
|
Add option to disable access to the global filesystem namespace.
Systems like FreeBSD's Capsicum and Nuxi CloudABI apply the concept of
capability-based security on the way processes can interact with the
filesystem API. It is no longer possible to interact with the VFS
through calls like open(), unlink(), rename(), etc. Instead, processes
are only allowed to interact with files and directories to which they
have been granted access. The *at() functions can be used for this
purpose.
This change adds a new config switch called
_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE. If set, all functionality
that requires the global filesystem namespace will be disabled. More
concretely:
- fstream's open() function will be removed.
- cstdio will no longer pull in fopen(), rename(), etc.
- The test suite's get_temp_file_name() will be removed. This will cause
all tests that use the global filesystem namespace to break, but will
at least make all the other tests run (as get_temp_file_name will not
build anyway).
It is important to mention that this change will make fstream rather
useless on those systems for now. Still, I'd rather not have fstream
disabled entirely, as it is of course possible to come up with an
extension for fstream that would allow access to local filesystem
namespaces (e.g., by adding an openat() member function).
Differential revision: http://reviews.llvm.org/D8194
Reviewed by: jroelofs (thanks!)
llvm-svn: 232049
2015-03-12 23:44:39 +08:00
|
|
|
#endif
|
2016-04-22 09:04:55 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
void close();
|
|
|
|
|
|
|
|
private:
|
|
|
|
basic_filebuf<char_type, traits_type> __sb_;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
2016-04-22 09:04:55 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_fstream<_CharT, _Traits>::basic_fstream()
|
|
|
|
: basic_iostream<char_type, traits_type>(&__sb_)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
Add option to disable access to the global filesystem namespace.
Systems like FreeBSD's Capsicum and Nuxi CloudABI apply the concept of
capability-based security on the way processes can interact with the
filesystem API. It is no longer possible to interact with the VFS
through calls like open(), unlink(), rename(), etc. Instead, processes
are only allowed to interact with files and directories to which they
have been granted access. The *at() functions can be used for this
purpose.
This change adds a new config switch called
_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE. If set, all functionality
that requires the global filesystem namespace will be disabled. More
concretely:
- fstream's open() function will be removed.
- cstdio will no longer pull in fopen(), rename(), etc.
- The test suite's get_temp_file_name() will be removed. This will cause
all tests that use the global filesystem namespace to break, but will
at least make all the other tests run (as get_temp_file_name will not
build anyway).
It is important to mention that this change will make fstream rather
useless on those systems for now. Still, I'd rather not have fstream
disabled entirely, as it is of course possible to come up with an
extension for fstream that would allow access to local filesystem
namespaces (e.g., by adding an openat() member function).
Differential revision: http://reviews.llvm.org/D8194
Reviewed by: jroelofs (thanks!)
llvm-svn: 232049
2015-03-12 23:44:39 +08:00
|
|
|
#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _CharT, class _Traits>
|
2016-04-22 09:04:55 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_fstream<_CharT, _Traits>::basic_fstream(const char* __s, ios_base::openmode __mode)
|
|
|
|
: basic_iostream<char_type, traits_type>(&__sb_)
|
|
|
|
{
|
|
|
|
if (__sb_.open(__s, __mode) == 0)
|
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
|
|
|
|
2018-01-23 10:07:27 +08:00
|
|
|
#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline
|
|
|
|
basic_fstream<_CharT, _Traits>::basic_fstream(const wchar_t* __s, ios_base::openmode __mode)
|
|
|
|
: basic_iostream<char_type, traits_type>(&__sb_)
|
|
|
|
{
|
|
|
|
if (__sb_.open(__s, __mode) == 0)
|
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _CharT, class _Traits>
|
2016-04-22 09:04:55 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_fstream<_CharT, _Traits>::basic_fstream(const string& __s, ios_base::openmode __mode)
|
|
|
|
: basic_iostream<char_type, traits_type>(&__sb_)
|
|
|
|
{
|
|
|
|
if (__sb_.open(__s, __mode) == 0)
|
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
Add option to disable access to the global filesystem namespace.
Systems like FreeBSD's Capsicum and Nuxi CloudABI apply the concept of
capability-based security on the way processes can interact with the
filesystem API. It is no longer possible to interact with the VFS
through calls like open(), unlink(), rename(), etc. Instead, processes
are only allowed to interact with files and directories to which they
have been granted access. The *at() functions can be used for this
purpose.
This change adds a new config switch called
_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE. If set, all functionality
that requires the global filesystem namespace will be disabled. More
concretely:
- fstream's open() function will be removed.
- cstdio will no longer pull in fopen(), rename(), etc.
- The test suite's get_temp_file_name() will be removed. This will cause
all tests that use the global filesystem namespace to break, but will
at least make all the other tests run (as get_temp_file_name will not
build anyway).
It is important to mention that this change will make fstream rather
useless on those systems for now. Still, I'd rather not have fstream
disabled entirely, as it is of course possible to come up with an
extension for fstream that would allow access to local filesystem
namespaces (e.g., by adding an openat() member function).
Differential revision: http://reviews.llvm.org/D8194
Reviewed by: jroelofs (thanks!)
llvm-svn: 232049
2015-03-12 23:44:39 +08:00
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2017-04-19 07:38:41 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
2016-04-22 09:04:55 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_fstream<_CharT, _Traits>::basic_fstream(basic_fstream&& __rhs)
|
2011-07-01 05:18:19 +08:00
|
|
|
: basic_iostream<char_type, traits_type>(_VSTD::move(__rhs)),
|
|
|
|
__sb_(_VSTD::move(__rhs.__sb_))
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
this->set_rdbuf(&__sb_);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
2016-04-22 09:04:55 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_fstream<_CharT, _Traits>&
|
|
|
|
basic_fstream<_CharT, _Traits>::operator=(basic_fstream&& __rhs)
|
|
|
|
{
|
2011-07-01 05:18:19 +08:00
|
|
|
basic_iostream<char_type, traits_type>::operator=(_VSTD::move(__rhs));
|
|
|
|
__sb_ = _VSTD::move(__rhs.__sb_);
|
2010-05-12 03:42:16 +08:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2017-04-19 07:38:41 +08:00
|
|
|
#endif // _LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
2016-04-22 09:04:55 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
void
|
|
|
|
basic_fstream<_CharT, _Traits>::swap(basic_fstream& __rhs)
|
|
|
|
{
|
|
|
|
basic_iostream<char_type, traits_type>::swap(__rhs);
|
|
|
|
__sb_.swap(__rhs.__sb_);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
|
|
void
|
|
|
|
swap(basic_fstream<_CharT, _Traits>& __x, basic_fstream<_CharT, _Traits>& __y)
|
|
|
|
{
|
|
|
|
__x.swap(__y);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
2016-04-22 09:04:55 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_filebuf<_CharT, _Traits>*
|
|
|
|
basic_fstream<_CharT, _Traits>::rdbuf() const
|
|
|
|
{
|
|
|
|
return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
2016-04-22 09:04:55 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
|
|
|
basic_fstream<_CharT, _Traits>::is_open() const
|
|
|
|
{
|
|
|
|
return __sb_.is_open();
|
|
|
|
}
|
|
|
|
|
Add option to disable access to the global filesystem namespace.
Systems like FreeBSD's Capsicum and Nuxi CloudABI apply the concept of
capability-based security on the way processes can interact with the
filesystem API. It is no longer possible to interact with the VFS
through calls like open(), unlink(), rename(), etc. Instead, processes
are only allowed to interact with files and directories to which they
have been granted access. The *at() functions can be used for this
purpose.
This change adds a new config switch called
_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE. If set, all functionality
that requires the global filesystem namespace will be disabled. More
concretely:
- fstream's open() function will be removed.
- cstdio will no longer pull in fopen(), rename(), etc.
- The test suite's get_temp_file_name() will be removed. This will cause
all tests that use the global filesystem namespace to break, but will
at least make all the other tests run (as get_temp_file_name will not
build anyway).
It is important to mention that this change will make fstream rather
useless on those systems for now. Still, I'd rather not have fstream
disabled entirely, as it is of course possible to come up with an
extension for fstream that would allow access to local filesystem
namespaces (e.g., by adding an openat() member function).
Differential revision: http://reviews.llvm.org/D8194
Reviewed by: jroelofs (thanks!)
llvm-svn: 232049
2015-03-12 23:44:39 +08:00
|
|
|
#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
void
|
|
|
|
basic_fstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode)
|
|
|
|
{
|
|
|
|
if (__sb_.open(__s, __mode))
|
|
|
|
this->clear();
|
|
|
|
else
|
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
|
|
|
|
2018-01-23 10:07:27 +08:00
|
|
|
#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
|
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
void
|
|
|
|
basic_fstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode)
|
|
|
|
{
|
|
|
|
if (__sb_.open(__s, __mode))
|
|
|
|
this->clear();
|
|
|
|
else
|
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _CharT, class _Traits>
|
|
|
|
void
|
|
|
|
basic_fstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode)
|
|
|
|
{
|
|
|
|
if (__sb_.open(__s, __mode))
|
|
|
|
this->clear();
|
|
|
|
else
|
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
Add option to disable access to the global filesystem namespace.
Systems like FreeBSD's Capsicum and Nuxi CloudABI apply the concept of
capability-based security on the way processes can interact with the
filesystem API. It is no longer possible to interact with the VFS
through calls like open(), unlink(), rename(), etc. Instead, processes
are only allowed to interact with files and directories to which they
have been granted access. The *at() functions can be used for this
purpose.
This change adds a new config switch called
_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE. If set, all functionality
that requires the global filesystem namespace will be disabled. More
concretely:
- fstream's open() function will be removed.
- cstdio will no longer pull in fopen(), rename(), etc.
- The test suite's get_temp_file_name() will be removed. This will cause
all tests that use the global filesystem namespace to break, but will
at least make all the other tests run (as get_temp_file_name will not
build anyway).
It is important to mention that this change will make fstream rather
useless on those systems for now. Still, I'd rather not have fstream
disabled entirely, as it is of course possible to come up with an
extension for fstream that would allow access to local filesystem
namespaces (e.g., by adding an openat() member function).
Differential revision: http://reviews.llvm.org/D8194
Reviewed by: jroelofs (thanks!)
llvm-svn: 232049
2015-03-12 23:44:39 +08:00
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _CharT, class _Traits>
|
2016-04-22 09:04:55 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
void
|
|
|
|
basic_fstream<_CharT, _Traits>::close()
|
|
|
|
{
|
|
|
|
if (__sb_.close() == 0)
|
|
|
|
this->setstate(ios_base::failbit);
|
|
|
|
}
|
|
|
|
|
|
|
|
_LIBCPP_END_NAMESPACE_STD
|
|
|
|
|
2017-06-01 06:07:49 +08:00
|
|
|
_LIBCPP_POP_MACROS
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
#endif // _LIBCPP_FSTREAM
|