E-MailRelay

gfile.h
Go to the documentation of this file.
1//
2// Copyright (C) 2001-2021 Graeme Walker <graeme_walker@users.sourceforge.net>
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16// ===
17///
18/// \file gfile.h
19///
20
21#ifndef G_FILE_H
22#define G_FILE_H
23
24#include "gdef.h"
25#include "gpath.h"
26#include "gexception.h"
27#include "gdatetime.h"
28#include <cstdio> // std::remove()
29#include <new> // std::nothrow
30#include <fstream>
31
32 namespace G
33{
34 class File ;
35 class DirectoryIteratorImp ;
36}
37
38//| \class G::File
39/// A simple static class for dealing with files.
40/// \see G::Path, G::FileSystem, G::Directory
41///
42 class G::File
43{
44 public:
45 G_EXCEPTION( StatError , "cannot access file" ) ;
46 G_EXCEPTION( CannotRemove , "cannot delete file" ) ;
47 G_EXCEPTION( CannotRename , "cannot rename file" ) ;
48 G_EXCEPTION( CannotCopy , "cannot copy file" ) ;
49 G_EXCEPTION( CannotMkdir , "cannot create directory" ) ;
50 G_EXCEPTION( CannotChmod , "cannot chmod file" ) ;
51 G_EXCEPTION( CannotChgrp , "cannot chgrp file" ) ;
52 G_EXCEPTION( CannotLink , "cannot create symlink" ) ;
53 G_EXCEPTION( CannotCreate , "cannot create file" ) ;
54 G_EXCEPTION( CannotReadLink , "cannot read symlink" ) ;
55 G_EXCEPTION( SizeOverflow , "file size overflow" ) ;
56 G_EXCEPTION( TimeError , "cannot get file modification time" ) ;
57 enum class InOut { In , Out } ;
58 enum class InOutAppend { In , Out , Append } ;
59 class Append /// An overload discriminator for G::File::open().
60 {} ;
61 class Text /// An overload discriminator for G::File::open().
62 {} ;
63 struct Stat /// A portable 'struct stat'.
64 {
65 int error {0} ;
66 bool enoent {false} ;
67 bool eaccess {false} ;
68 bool is_dir {false} ;
69 bool is_link {false} ;
70 bool is_executable {false} ;
71 bool is_empty {false} ;
72 std::time_t mtime_s {0} ;
73 unsigned int mtime_us {0} ;
74 unsigned long mode {0} ;
75 unsigned long long size {0} ;
76 unsigned long long blocks {0} ;
77 } ;
78
79 static bool remove( const Path & path , std::nothrow_t ) noexcept ;
80 ///< Deletes the file or directory. Returns false on error.
81
82 static void remove( const Path & path ) ;
83 ///< Deletes the file or directory. Throws an exception on error.
84
85 static bool rename( const Path & from , const Path & to , std::nothrow_t ) noexcept ;
86 ///< Renames the file. Returns false on error. Tries to
87 ///< delete the target 'to' file if necessary.
88
89 static void rename( const Path & from , const Path & to , bool ignore_missing = false ) ;
90 ///< Renames the file. Throws on error, but optionally
91 ///< ignores errors caused by a missing 'from' file or
92 ///< missing 'to' directory component.
93
94 static bool copy( const Path & from , const Path & to , std::nothrow_t ) ;
95 ///< Copies a file. Returns false on error.
96
97 static void copy( const Path & from , const Path & to ) ;
98 ///< Copies a file.
99
100 static void copy( std::istream & from , std::ostream & to ,
101 std::streamsize limit = 0U , std::string::size_type block = 0U ) ;
102 ///< Copies a stream with an optional size limit.
103
104 static bool copyInto( const Path & from , const Path & to_dir , std::nothrow_t ) ;
105 ///< Copies a file into a directory and does a chmodx()
106 ///< if necessary. Returns false on error.
107
108 static bool mkdirs( const Path & dir , std::nothrow_t , int = 100 ) ;
109 ///< Creates a directory and all necessary parents.
110 ///< Does chmodx() on all created directories.
111 ///< Returns false on error, but EEXIST is not
112 ///< an error and chmod errors are also ignored.
113 ///<
114 ///< Note that the EEXIST result is ignored even if
115 ///< the target path already exists as a non-directory.
116 ///< This is a feature not a bug because it can avoid
117 ///< races.
118
119 static void mkdirs( const Path & dir , int = 100 ) ;
120 ///< Creates a directory and all necessary parents.
121 ///< Does chmodx() on all created directories.
122 ///< Throws on error, but EEXIST is not an error
123 ///< and chmod errors are also ignored.
124
125 static bool mkdir( const Path & dir , std::nothrow_t ) ;
126 ///< Creates a directory. Returns false on error
127 ///< (including EEXIST).
128
129 static void mkdir( const Path & dir ) ;
130 ///< Creates a directory. Throws on error (including
131 ///< EEXIST).
132
133 static bool isEmpty( const Path & file , std::nothrow_t ) ;
134 ///< Returns true if the file size is zero.
135 ///< Returns false on error.
136
137 static std::string sizeString( const Path & file ) ;
138 ///< Returns the file's size in string format.
139 ///< Returns the empty string on error.
140
141 static bool exists( const Path & file ) ;
142 ///< Returns true if the file (directory, device etc.)
143 ///< exists. Symlinks are followed. Throws an exception
144 ///< if permission denied or too many symlinks etc.
145
146 static bool exists( const Path & file , std::nothrow_t ) ;
147 ///< Returns true if the file (directory, device etc.)
148 ///< exists. Symlinks are followed. Returns false on error.
149
150 static bool isExecutable( const Path & , std::nothrow_t ) ;
151 ///< Returns true if the path is probably executable by the
152 ///< calling process. Because of portability and implementation
153 ///< difficulties this does not return a definitive result so
154 ///< it should only used for generating warnings on a
155 ///< false return. Returns false on error.
156
157 static bool isLink( const Path & path , std::nothrow_t ) ;
158 ///< Returns true if the path is an existing symlink.
159 ///< Returns false on error.
160
161 static bool isDirectory( const Path & path , std::nothrow_t ) ;
162 ///< Returns true if the path exists() and is a directory.
163 ///< Symlinks are followed. Returns false on error.
164
165 static SystemTime time( const Path & file ) ;
166 ///< Returns the file's timestamp. Throws on error.
167
168 static SystemTime time( const Path & file , std::nothrow_t ) ;
169 ///< Returns the file's timestamp. Returns SystemTime(0)
170 ///< on error.
171
172 static void chmodx( const Path & file ) ;
173 ///< Makes the file executable. Throws on error.
174
175 static bool chmodx( const Path & file , std::nothrow_t ) ;
176 ///< Makes the file executable.
177
178 static void chmod( const Path & file , const std::string & spec ) ;
179 ///< Sets the file permissions. Throws on error. The
180 ///< spec is a simplified sub-set of the /bin/chmod
181 ///< command syntax. The umask is ignored.
182
183 static void chgrp( const Path & file , const std::string & group ) ;
184 ///< Sets the file group ownership. Throws on error.
185
186 static bool chgrp( const Path & file , const std::string & group , std::nothrow_t ) ;
187 ///< Sets the file group ownership. Returns false on error.
188
189 static G::Path readlink( const Path & link ) ;
190 ///< Reads a symlink. Throws on error.
191
192 static G::Path readlink( const Path & link , std::nothrow_t ) ;
193 ///< Reads a symlink. Returns the empty path on error.
194
195 static void link( const Path & target , const Path & new_link ) ;
196 ///< Creates a symlink. If the link already exists but is
197 ///< not not pointing at the correct target then the link
198 ///< is deleted and recreated. Throws on error.
199
200 static bool link( const Path & target , const Path & new_link , std::nothrow_t ) ;
201 ///< Creates a symlink. Returns false on error.
202
203 static void create( const Path & ) ;
204 ///< Creates the file if it does not exist. Leaves it
205 ///< alone if it does. Throws on error.
206
207 static int compare( const Path & , const Path & , bool ignore_whitespace = false ) ;
208 ///< Compares the contents of the two files. Returns 0, 1 or -1.
209
210 static void open( std::ofstream & , const Path & ) ;
211 ///< Calls open() on the given output file stream.
212 ///< Uses SH_DENYNO and O_BINARY on windows.
213
214 static void open( std::ofstream & , const Path & , Append ) ;
215 ///< Calls open() on the given output file stream.
216 ///< This overload is for append-on-every-write mode.
217 ///< Uses SH_DENYNO and O_BINARY on windows.
218
219 static void open( std::ofstream & , const Path & , Text ) ;
220 ///< Calls open() on the given output file stream.
221 ///< This overload is for native end-of-line conversion.
222 ///< Uses SH_DENYNO and O_BINARY on windows.
223
224 static void open( std::ifstream & , const Path & ) ;
225 ///< Calls open() on the given input file stream.
226 ///< Uses SH_DENYNO and O_BINARY on windows.
227
228 static void open( std::ifstream & , const Path & , Text ) ;
229 ///< Calls open() on the given input file stream.
230 ///< This overload is for native end-of-line conversion.
231 ///< Uses SH_DENYNO and O_BINARY on windows.
232
233 static std::filebuf * open( std::filebuf & , const Path & , InOut ) ;
234 ///< Calls open() on the given filebuf. Returns the address
235 ///< of the given filebuf, or nullptr on failure.
236 ///< Uses SH_DENYNO and O_BINARY on windows.
237
238 static int open( const char * , InOutAppend ) noexcept ;
239 ///< Opens a file descriptor. Returns -1 on error.
240 ///< Uses SH_DENYNO and O_BINARY on windows.
241
242 static bool probe( const char * ) noexcept ;
243 ///< Creates and deletes a temporary probe file. Fails if
244 ///< the file already exists. Returns false on error.
245
246 static ssize_t read( int fd , char * , std::size_t ) noexcept ;
247 ///< Calls ::read() or equivalent.
248
249 static ssize_t write( int fd , const char * , std::size_t ) noexcept ;
250 ///< Calls ::write() or equivalent.
251
252 static void close( int fd ) noexcept ;
253 ///< Calls ::close() or equivalent.
254
255 public:
256 File() = delete ;
257
258 private:
259 static const int rdonly = 1<<0 ;
260 static const int wronly = 1<<1 ;
261 static const int rdwr = 1<<2 ;
262 static const int trunc = 1<<3 ;
263 static const int creat = 1<<4 ;
264 static const int append = 1<<5 ;
265 friend class G::DirectoryIteratorImp ;
266 static std::string copy( const Path & , const Path & , int ) ;
267 static bool exists( const Path & , bool , bool ) ;
268 static bool existsImp( const char * , bool & , bool & ) noexcept ;
269 static Stat statImp( const char * , bool = false ) noexcept ;
270 static bool rename( const char * , const char * to , bool & enoent ) noexcept ;
271 static bool chmodx( const Path & file , bool ) ;
272 static int linkImp( const char * , const char * ) ;
273 static bool linked( const Path & , const Path & ) ;
274 static int mkdirImp( const Path & dir ) noexcept ;
275 static bool mkdirsr( int * , const Path & dir , int ) ;
276 static bool chmod( const Path & , const std::string & , std::nothrow_t ) ;
277} ;
278
279#endif
G::DirectoryIteratorImp
A pimple-pattern implementation class for DirectoryIterator using opendir()/readdir().
Definition: gdirectory_unix.cpp:44
G::File::Append
An overload discriminator for G::File::open().
Definition: gfile.h:60
G::File::Text
An overload discriminator for G::File::open().
Definition: gfile.h:62
G::File
A simple static class for dealing with files.
Definition: gfile.h:43
G::File::probe
static bool probe(const char *) noexcept
Creates and deletes a temporary probe file.
Definition: gfile_unix.cpp:98
G::File::open
static void open(std::ofstream &, const Path &)
Calls open() on the given output file stream.
Definition: gfile_unix.cpp:55
G::File::isExecutable
static bool isExecutable(const Path &, std::nothrow_t)
Returns true if the path is probably executable by the calling process.
Definition: gfile.cpp:193
G::File::close
static void close(int fd) noexcept
Calls ::close() or equivalent.
Definition: gfile_unix.cpp:126
G::File::time
static SystemTime time(const Path &file)
Returns the file's timestamp. Throws on error.
Definition: gfile.cpp:211
G::File::isEmpty
static bool isEmpty(const Path &file, std::nothrow_t)
Returns true if the file size is zero.
Definition: gfile.cpp:199
G::File::link
static void link(const Path &target, const Path &new_link)
Creates a symlink.
Definition: gfile_unix.cpp:313
G::File::isDirectory
static bool isDirectory(const Path &path, std::nothrow_t)
Returns true if the path exists() and is a directory.
Definition: gfile.cpp:187
G::File::sizeString
static std::string sizeString(const Path &file)
Returns the file's size in string format.
Definition: gfile.cpp:205
G::File::rename
static bool rename(const Path &from, const Path &to, std::nothrow_t) noexcept
Renames the file.
Definition: gfile.cpp:46
G::File::write
static ssize_t write(int fd, const char *, std::size_t) noexcept
Calls ::write() or equivalent.
Definition: gfile_unix.cpp:121
G::File::chmod
static void chmod(const Path &file, const std::string &spec)
Sets the file permissions.
Definition: gfile_unix.cpp:205
G::File::remove
static bool remove(const Path &path, std::nothrow_t) noexcept
Deletes the file or directory. Returns false on error.
Definition: gfile.cpp:29
G::File::exists
static bool exists(const Path &file)
Returns true if the file (directory, device etc.) exists.
Definition: gfile.cpp:151
G::File::chmodx
static void chmodx(const Path &file)
Makes the file executable. Throws on error.
Definition: gfile.cpp:232
G::File::isLink
static bool isLink(const Path &path, std::nothrow_t)
Returns true if the path is an existing symlink.
Definition: gfile.cpp:181
G::File::read
static ssize_t read(int fd, char *, std::size_t) noexcept
Calls ::read() or equivalent.
Definition: gfile_unix.cpp:116
G::File::mkdirs
static bool mkdirs(const Path &dir, std::nothrow_t, int=100)
Creates a directory and all necessary parents.
Definition: gfile.cpp:274
G::File::copy
static bool copy(const Path &from, const Path &to, std::nothrow_t)
Copies a file. Returns false on error.
Definition: gfile.cpp:83
G::File::copyInto
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.
Definition: gfile.cpp:88
G::File::mkdir
static bool mkdir(const Path &dir, std::nothrow_t)
Creates a directory.
Definition: gfile.cpp:237
G::File::create
static void create(const Path &)
Creates the file if it does not exist.
Definition: gfile_unix.cpp:108
G::File::readlink
static G::Path readlink(const Path &link)
Reads a symlink. Throws on error.
Definition: gfile_unix.cpp:349
G::File::compare
static int compare(const Path &, const Path &, bool ignore_whitespace=false)
Compares the contents of the two files. Returns 0, 1 or -1.
Definition: gfile.cpp:288
G::File::chgrp
static void chgrp(const Path &file, const std::string &group)
Sets the file group ownership. Throws on error.
Definition: gfile_unix.cpp:301
G::Path
A Path object represents a file system path.
Definition: gpath.h:72
G::SystemTime
Represents a unix-epoch time with microsecond resolution.
Definition: gdatetime.h:125
gdatetime.h
gexception.h
gpath.h
G
Low-level classes.
Definition: galign.h:28
G::File::Stat
A portable 'struct stat'.
Definition: gfile.h:64