32bool G::File::renameImp(
const char * from ,
const char * to ,
int * e )
noexcept
34 bool ok = from && to && 0 == std::rename( from , to ) ;
36 *e = ok ? 0 : ( (from && to) ? Process::errno_() : EINVAL ) ;
42 static_assert(
noexcept(from.cstr()) ,
"" ) ;
43 return renameImp( from.cstr() , to.cstr() ,
nullptr ) ;
49 bool ok = renameImp( from.cstr() , to.
cstr() , &e ) ;
50 bool is_missing = !ok && e == ENOENT ;
51 if( !ok && !(is_missing && ignore_missing) )
53 throw CannotRename( std::string() +
"[" + from.str() +
"] to [" + to.
str() +
"]" ) ;
55 G_DEBUG(
"G::File::rename: \"" << from <<
"\" -> \"" << to <<
"\": success=" << ok ) ;
61 std::string reason = copy( from , to , 0 ) ;
63 throw CannotCopy( std::string() +
"[" + from.str() +
"] to [" + to.
str() +
"]: " + reason ) ;
69 return copy(from,to,0).empty() ;
75 G::Path to = to_dir / from.basename() ;
76 bool ok = copy(from,to,0).empty() ;
77 if( ok && isExecutable(from,std::nothrow) )
78 ok = chmodx( to , std::nothrow ) ;
85 std::ifstream in ; open( in , from ) ;
87 return "cannot open input file" ;
89 std::ofstream out ; open( out , to ) ;
91 return "cannot open output file" ;
104 if( out.fail() && !empty )
105 return "write error" ;
110void G::File::copy( std::istream & in , std::ostream & out , std::streamsize limit , std::size_t block )
112 std::ios_base::iostate in_state = in.rdstate() ;
115 std::vector<char> buffer( block ) ;
117 const auto b =
static_cast<std::streamsize
>(block) ;
118 std::streamsize size = 0U ;
119 while( ( limit == 0U || size < limit ) && in.good() && out.good() )
121 std::streamsize request = limit == 0U || (limit-size) > b ? b : (limit-size) ;
122 in.read( buffer.data() , request ) ;
123 std::streamsize result = in.gcount() ;
126 out.write( buffer.data() , result ) ;
133 in.clear( (in.rdstate() &
~std::ios_base::failbit) | (in_state & std::ios_base::failbit) ) ;
138 return path.
empty() ? false : exists( path ,
false ,
true ) ;
143 return path.
empty() ? false : exists( path ,
false ,
false ) ;
148 bool enoent = false ;
149 bool eaccess = false ;
150 bool rc = existsImp( path.
cstr() , enoent , eaccess ) ;
155 else if( !rc && do_throw )
157 throw StatError( path.
str() , eaccess?
"permission denied":
"" ) ;
161 return error_return_value ;
169 Stat s = statImp( path.
cstr() ,
true ) ;
170 return 0 == s.error && s.is_link ;
176 return statImp( path.
cstr() , symlink_nofollow ) ;
182 return 0 == s.error && s.is_dir ;
188 return 0 == s.error && s.is_executable ;
195 return 0 == s.error && s.is_empty ;
202 return s.error ? std::string() : std::to_string(s.size) ;
225 return chmodx( path ,
false ) ;
231 chmodx( path ,
true ) ;
237 return 0 == mkdirImp( dir ) ;
243 int e = mkdirImp( dir ) ;
249bool G::File::mkdirsImp(
const Path & path_in ,
int & e ,
int limit )
251 if( path_in.
empty() )
254 auto parts = path_in.
split() ;
256 for(
const auto & part : parts )
261 e = mkdirImp( path ) ;
272 return e == 0 || e == EEXIST ;
279 return mkdirsImp( path , e , limit ) ;
287 if( !mkdirsImp(path,e,limit) )
295 std::ifstream file_1 ; open( file_1 , path_1 ) ;
296 std::ifstream file_2 ; open( file_2 , path_2 ) ;
297 constexpr int eof = std::char_traits<char>::eof() ;
298 if( !file_1.good() && !file_2.good() )
return -1 ;
299 if( !file_1.good() )
return -1 ;
300 if( !file_2.good() )
return 1 ;
304 auto isspace = [](
int c){
return c ==
' ' || c ==
'\t' || c ==
'\n' || c ==
'\r' ; } ;
307 do { a = file_1.get() ; }
while( ignore_whitespace && isspace(a) ) ;
308 do { b = file_2.get() ; }
while( ignore_whitespace && isspace(b) ) ;
309 if( a == eof && b == eof )
313 result = a < b ? -1 : 1 ;
324 constexpr char prefix = G::is_windows() ?
'~' :
'.' ;
325 constexpr char sep =
'~' ;
326 constexpr unsigned int limit = 100U ;
328 for(
unsigned int version = 1U ; version <= limit ; version++ )
331 std::string(1U,prefix).append(path.
basename()).append(1U,sep).append(std::to_string(version==limit?1:version)) ;
332 if( !exists( backup_path , std::nothrow ) || version == limit )
336 bool copied =
File::copy( path , backup_path , std::nothrow ) ;
337 return copied ? backup_path :
G::Path() ;
static bool isExecutable(const Path &, std::nothrow_t)
Returns true if the path is probably executable by the calling process.
static SystemTime time(const Path &file)
Returns the file's timestamp. Throws on error.
static bool isEmpty(const Path &file, std::nothrow_t)
Returns true if the file size is zero.
static bool isDirectory(const Path &path, std::nothrow_t)
Returns true if the path exists() and is a directory.
static std::string sizeString(const Path &file)
Returns the file's size in string format.
static bool rename(const Path &from, const Path &to, std::nothrow_t) noexcept
Renames the file.
static Stat stat(const Path &path, bool symlink_nofollow=false)
Returns a file status structure.
static bool exists(const Path &file)
Returns true if the file (directory, device etc.) exists.
static void chmodx(const Path &file)
Makes the file executable. Throws on error.
static bool isLink(const Path &path, std::nothrow_t)
Returns true if the path is an existing symlink.
static Path backup(const Path &from, std::nothrow_t)
Creates a backup copy of the given file in the same directory and with a lightly-mangled filename.
static bool mkdirs(const Path &dir, std::nothrow_t, int=100)
Creates a directory and all necessary parents.
static bool copy(const Path &from, const Path &to, std::nothrow_t)
Copies a file. Returns false on error.
static bool copyInto(const Path &from, const Path &to_dir, std::nothrow_t)
Copies a file into a directory and does a chmodx() if necessary.
static bool mkdir(const Path &dir, std::nothrow_t)
Creates a directory.
static int compare(const Path &, const Path &, bool ignore_whitespace=false)
Compares the contents of the two files. Returns 0, 1 or -1.
A Path object represents a file system path.
const value_type * cstr() const noexcept
Returns the path's c-string.
bool isRoot() const noexcept
Returns true if the path is a root, like "/", "c:", "c:/", "\\server\volume" etc.
std::string basename() const
Returns the rightmost part of the path, ignoring "." parts.
Path dirname() const
Returns the path without the rightmost part, ignoring "." parts.
Path & pathAppend(const std::string &tail)
Appends a filename or a relative path to this path.
std::string str() const
Returns the path string.
StringArray split() const
Spits the path into a list of component parts (ignoring "." parts unless the whole path is "....
bool empty() const noexcept
Returns true if the path is empty.
Used to temporarily modify the process umask.
static std::string strerror(int errno_)
Translates an 'errno' value into a meaningful diagnostic string.
Represents a unix-epoch time with microsecond resolution.
A portable 'struct stat'.
A set of compile-time buffer sizes.