E-MailRelay
gfile.h
Go to the documentation of this file.
1//
2// Copyright (C) 2001-2023 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(), std::FILE
29#include <new> // std::nothrow
30#include <fstream>
31
32namespace 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///
43{
44public:
45 G_EXCEPTION( StatError , tx("cannot access file") ) ;
46 G_EXCEPTION( CannotRemove , tx("cannot delete file") ) ;
47 G_EXCEPTION( CannotRename , tx("cannot rename file") ) ;
48 G_EXCEPTION( CannotCopy , tx("cannot copy file") ) ;
49 G_EXCEPTION( CannotMkdir , tx("cannot create directory") ) ;
50 G_EXCEPTION( CannotChmod , tx("cannot chmod file") ) ;
51 G_EXCEPTION( CannotChgrp , tx("cannot chgrp file") ) ;
52 G_EXCEPTION( CannotLink , tx("cannot create symlink") ) ;
53 G_EXCEPTION( CannotCreate , tx("cannot create file") ) ;
54 G_EXCEPTION( CannotReadLink , tx("cannot read symlink") ) ;
55 G_EXCEPTION( SizeOverflow , tx("file size overflow") ) ;
56 G_EXCEPTION( TimeError , tx("cannot get file modification time") ) ;
57 enum class InOut { In , Out } ;
58 enum class InOutAppend { In , Out , Append } ;
59 enum class Seek { Start , Current , End } ;
60 class Append /// An overload discriminator for G::File::open().
61 {} ;
62 class Text /// An overload discriminator for G::File::open().
63 {} ;
64 struct CreateExclusive /// An overload discriminator for G::File::open().
65 {} ;
66 struct Stat /// A portable 'struct stat'.
67 {
68 int error {0} ;
69 bool enoent {false} ;
70 bool eaccess {false} ;
71 bool is_dir {false} ;
72 bool is_link {false} ;
73 bool is_executable {false} ;
74 bool is_empty {false} ;
75 std::time_t mtime_s {0} ;
76 unsigned int mtime_us {0} ;
77 unsigned long mode {0} ;
78 unsigned long long size {0} ;
79 unsigned long long blocks {0} ;
80 uid_t uid {0} ; // unix
81 gid_t gid {0} ; // unix
82 bool inherit {false} ; // unix, directory group ownership passed on to new files
83 } ;
84
85 static bool remove( const Path & path , std::nothrow_t ) noexcept ;
86 ///< Deletes the file or directory. Returns false on error.
87
88 static void remove( const Path & path ) ;
89 ///< Deletes the file or directory. Throws an exception on error.
90
91 static bool rename( const Path & from , const Path & to , std::nothrow_t ) noexcept ;
92 ///< Renames the file. Whether it fails if 'to' already
93 ///< exists depends on the o/s (see also renameOnto()).
94 ///< Returns false on error.
95
96 static void rename( const Path & from , const Path & to , bool ignore_missing = false ) ;
97 ///< Renames the file. Throws on error, but optionally
98 ///< ignores errors caused by a missing 'from' file or
99 ///< missing 'to' directory component.
100
101 static bool renameOnto( const Path & from , const Path & to , std::nothrow_t ) noexcept ;
102 ///< Renames the file, deleting 'to' first if necessary.
103 ///< Returns false on error.
104
105 static bool copy( const Path & from , const Path & to , std::nothrow_t ) ;
106 ///< Copies a file. Returns false on error.
107
108 static void copy( const Path & from , const Path & to ) ;
109 ///< Copies a file.
110
111 static void copy( std::istream & from , std::ostream & to ,
112 std::streamsize limit = 0U , std::size_t block = 0U ) ;
113 ///< Copies a stream with an optional size limit.
114
115 static bool copyInto( const Path & from , const Path & to_dir , std::nothrow_t ) ;
116 ///< Copies a file into a directory and does a chmodx()
117 ///< if necessary. Returns false on error.
118
119 static bool mkdirs( const Path & dir , std::nothrow_t , int = 100 ) ;
120 ///< Creates a directory and all necessary parents.
121 ///< Returns false on error, but EEXIST is not
122 ///< an error and chmod errors are also ignored.
123 ///<
124 ///< Note that the EEXIST result is ignored even if
125 ///< the target path already exists as a non-directory.
126 ///< This is a feature not a bug because it can avoid
127 ///< races.
128
129 static void mkdirs( const Path & dir , int = 100 ) ;
130 ///< Creates a directory and all necessary parents.
131 ///< Throws on error, but EEXIST is not an error.
132
133 static bool mkdir( const Path & dir , std::nothrow_t ) ;
134 ///< Creates a directory. Returns false on error
135 ///< (including EEXIST).
136
137 static void mkdir( const Path & dir ) ;
138 ///< Creates a directory. Throws on error (including
139 ///< EEXIST).
140
141 static bool isEmpty( const Path & file , std::nothrow_t ) ;
142 ///< Returns true if the file size is zero.
143 ///< Returns false on error.
144
145 static std::string sizeString( const Path & file ) ;
146 ///< Returns the file's size in string format.
147 ///< Returns the empty string on error.
148
149 static bool exists( const Path & file ) ;
150 ///< Returns true if the file (directory, device etc.)
151 ///< exists. Symlinks are followed. Throws an exception
152 ///< if permission denied or too many symlinks etc.
153
154 static bool exists( const Path & file , std::nothrow_t ) ;
155 ///< Returns true if the file (directory, device etc.)
156 ///< exists. Symlinks are followed. Returns false on error.
157
158 static bool isExecutable( const Path & , std::nothrow_t ) ;
159 ///< Returns true if the path is probably executable by the
160 ///< calling process. Because of portability and implementation
161 ///< difficulties this does not return a definitive result so
162 ///< it should only used for generating warnings on a
163 ///< false return. Returns false on error.
164
165 static bool isLink( const Path & path , std::nothrow_t ) ;
166 ///< Returns true if the path is an existing symlink.
167 ///< Returns false on error.
168
169 static bool isDirectory( const Path & path , std::nothrow_t ) ;
170 ///< Returns true if the path exists() and is a directory.
171 ///< Symlinks are followed. Returns false on error.
172
173 static Stat stat( const Path & path , bool read_symlink = false ) ;
174 ///< Returns a file status structure. Returns with
175 ///< the 'error' field set on error. Always fails if
176 ///< 'read-link' on Windows.
177
178 static SystemTime time( const Path & file ) ;
179 ///< Returns the file's timestamp. Throws on error.
180
181 static SystemTime time( const Path & file , std::nothrow_t ) ;
182 ///< Returns the file's timestamp. Returns SystemTime(0)
183 ///< on error.
184
185 static void chmodx( const Path & file ) ;
186 ///< Makes the file executable. Throws on error.
187
188 static bool chmodx( const Path & file , std::nothrow_t ) ;
189 ///< Makes the file executable.
190
191 static void chmod( const Path & file , const std::string & spec ) ;
192 ///< Sets the file permissions. Throws on error. The
193 ///< spec is a simplified sub-set of the /bin/chmod
194 ///< command syntax. The umask is ignored.
195
196 static void chgrp( const Path & file , const std::string & group ) ;
197 ///< Sets the file group ownership. Throws on error.
198
199 static bool chgrp( const Path & file , const std::string & group , std::nothrow_t ) ;
200 ///< Sets the file group ownership. Returns false on error.
201
202 static bool chgrp( const Path & file , gid_t group_id , std::nothrow_t ) ;
203 ///< Sets the file group ownership. Returns false on error.
204
205 static G::Path readlink( const Path & link ) ;
206 ///< Reads a symlink. Throws on error.
207
208 static G::Path readlink( const Path & link , std::nothrow_t ) ;
209 ///< Reads a symlink. Returns the empty path on error.
210
211 static void link( const Path & target , const Path & new_link ) ;
212 ///< Creates a symlink. If the link already exists but is
213 ///< not not pointing at the correct target then the link
214 ///< is deleted and recreated. Throws on error.
215
216 static bool link( const Path & target , const Path & new_link , std::nothrow_t ) ;
217 ///< Creates a symlink. Returns false on error.
218
219 static bool hardlink( const Path & src , const Path & dst , std::nothrow_t ) ;
220 ///< Creates a hard link. Returns false on error or if
221 ///< not implemented.
222
223 static void create( const Path & ) ;
224 ///< Creates the file if it does not exist. Leaves it
225 ///< alone if it does. Throws on error.
226
227 static int compare( const Path & , const Path & , bool ignore_whitespace = false ) ;
228 ///< Compares the contents of the two files. Returns 0, 1 or -1.
229
230 static void open( std::ofstream & , const Path & ) ;
231 ///< Calls open() on the given output file stream.
232 ///< Uses SH_DENYNO and O_BINARY on windows.
233
234 static void open( std::ofstream & , const Path & , Append ) ;
235 ///< Calls open() on the given output file stream.
236 ///< This overload is for append-on-every-write mode.
237 ///< Uses SH_DENYNO and O_BINARY on windows.
238
239 static void open( std::ofstream & , const Path & , Text ) ;
240 ///< Calls open() on the given output file stream.
241 ///< This overload is for native end-of-line conversion.
242 ///< Uses SH_DENYNO and O_BINARY on windows.
243
244 static void open( std::ifstream & , const Path & ) ;
245 ///< Calls open() on the given input file stream.
246 ///< Uses SH_DENYNO and O_BINARY on windows.
247
248 static void open( std::ifstream & , const Path & , Text ) ;
249 ///< Calls open() on the given input file stream.
250 ///< This overload is for native end-of-line conversion.
251 ///< Uses SH_DENYNO and O_BINARY on windows.
252
253 static std::filebuf * open( std::filebuf & , const Path & , InOut ) ;
254 ///< Calls open() on the given filebuf. Returns the address
255 ///< of the given filebuf, or nullptr on failure.
256 ///< Uses SH_DENYNO and O_BINARY on windows.
257
258 static int open( const char * , InOutAppend ) noexcept ;
259 ///< Opens a file descriptor. Returns -1 on error.
260 ///< Uses SH_DENYNO and O_BINARY on windows.
261
262 static int open( const char * , CreateExclusive ) noexcept ;
263 ///< Creates a file and returns a writable file descriptor.
264 ///< Fails if the file already exists. Returns -1 on error.
265 ///< Uses SH_DENYNO and O_BINARY on windows.
266
267 static std::FILE * fopen( const char * , const char * mode ) noexcept ;
268 ///< Calls std::fopen().
269
270 static bool probe( const char * ) noexcept ;
271 ///< Creates and deletes a temporary probe file. Fails if
272 ///< the file already exists. Returns false on error.
273
274 static ssize_t read( int fd , char * , std::size_t ) noexcept ;
275 ///< Calls ::read() or equivalent.
276
277 static ssize_t write( int fd , const char * , std::size_t ) noexcept ;
278 ///< Calls ::write() or equivalent.
279
280 static void close( int fd ) noexcept ;
281 ///< Calls ::close() or equivalent.
282
283 static std::streamoff seek( int fd , std::streamoff offset , Seek ) noexcept ;
284 ///< Does ::lseek() or equivalent.
285
286 static void setNonBlocking( int fd ) noexcept ;
287 ///< Sets the file descriptor to non-blocking mode.
288
289public:
290 File() = delete ;
291
292private:
293 static const int rdonly = 1<<0 ;
294 static const int wronly = 1<<1 ;
295 static const int rdwr = 1<<2 ;
296 static const int trunc = 1<<3 ;
297 static const int creat = 1<<4 ;
298 static const int append = 1<<5 ;
299 friend class G::DirectoryIteratorImp ;
300 static std::string copy( const Path & , const Path & , int ) ;
301 static bool exists( const Path & , bool , bool ) ;
302 static bool existsImp( const char * , bool & , bool & ) noexcept ;
303 static Stat statImp( const char * , bool = false ) noexcept ;
304 static bool rename( const char * , const char * to , bool & enoent ) noexcept ;
305 static bool chmodx( const Path & file , bool ) ;
306 static int linkImp( const char * , const char * ) ;
307 static bool linked( const Path & , const Path & ) ;
308 static int mkdirImp( const Path & dir ) noexcept ;
309 static bool mkdirsr( const Path & dir , int & , int & ) ;
310 static bool chmod( const Path & , const std::string & , std::nothrow_t ) ;
311} ;
312
313#endif
An overload discriminator for G::File::open().
Definition: gfile.h:61
An overload discriminator for G::File::open().
Definition: gfile.h:63
A simple static class for dealing with files.
Definition: gfile.h:43
static std::FILE * fopen(const char *, const char *mode) noexcept
Calls std::fopen().
Definition: gfile_unix.cpp:108
static bool probe(const char *) noexcept
Creates and deletes a temporary probe file.
Definition: gfile_unix.cpp:114
static void open(std::ofstream &, const Path &)
Calls open() on the given output file stream.
Definition: gfile_unix.cpp:55
static bool isExecutable(const Path &, std::nothrow_t)
Returns true if the path is probably executable by the calling process.
Definition: gfile.cpp:195
static void close(int fd) noexcept
Calls ::close() or equivalent.
Definition: gfile_unix.cpp:149
static SystemTime time(const Path &file)
Returns the file's timestamp. Throws on error.
Definition: gfile.cpp:215
static bool isEmpty(const Path &file, std::nothrow_t)
Returns true if the file size is zero.
Definition: gfile.cpp:202
static void link(const Path &target, const Path &new_link)
Creates a symlink.
Definition: gfile_unix.cpp:356
static bool isDirectory(const Path &path, std::nothrow_t)
Returns true if the path exists() and is a directory.
Definition: gfile.cpp:189
static std::string sizeString(const Path &file)
Returns the file's size in string format.
Definition: gfile.cpp:209
static std::streamoff seek(int fd, std::streamoff offset, Seek) noexcept
Does ::lseek() or equivalent.
Definition: gfile_unix.cpp:432
static void setNonBlocking(int fd) noexcept
Sets the file descriptor to non-blocking mode.
Definition: gfile_unix.cpp:440
static bool rename(const Path &from, const Path &to, std::nothrow_t) noexcept
Renames the file.
Definition: gfile.cpp:46
static ssize_t write(int fd, const char *, std::size_t) noexcept
Calls ::write() or equivalent.
Definition: gfile_unix.cpp:144
static void chmod(const Path &file, const std::string &spec)
Sets the file permissions.
Definition: gfile_unix.cpp:232
static bool remove(const Path &path, std::nothrow_t) noexcept
Deletes the file or directory. Returns false on error.
Definition: gfile.cpp:29
static bool exists(const Path &file)
Returns true if the file (directory, device etc.) exists.
Definition: gfile.cpp:148
static void chmodx(const Path &file)
Makes the file executable. Throws on error.
Definition: gfile.cpp:239
static bool isLink(const Path &path, std::nothrow_t)
Returns true if the path is an existing symlink.
Definition: gfile.cpp:178
static ssize_t read(int fd, char *, std::size_t) noexcept
Calls ::read() or equivalent.
Definition: gfile_unix.cpp:139
static bool mkdirs(const Path &dir, std::nothrow_t, int=100)
Creates a directory and all necessary parents.
Definition: gfile.cpp:284
static bool renameOnto(const Path &from, const Path &to, std::nothrow_t) noexcept
Renames the file, deleting 'to' first if necessary.
Definition: gfile_unix.cpp:134
static bool copy(const Path &from, const Path &to, std::nothrow_t)
Copies a file. Returns false on error.
Definition: gfile.cpp:79
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:85
static Stat stat(const Path &path, bool read_symlink=false)
Returns a file status structure.
Definition: gfile.cpp:184
static bool mkdir(const Path &dir, std::nothrow_t)
Creates a directory.
Definition: gfile.cpp:245
static void create(const Path &)
Creates the file if it does not exist.
Definition: gfile_unix.cpp:125
static G::Path readlink(const Path &link)
Reads a symlink. Throws on error.
Definition: gfile_unix.cpp:396
static bool hardlink(const Path &src, const Path &dst, std::nothrow_t)
Creates a hard link.
Definition: gfile_unix.cpp:350
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:301
static void chgrp(const Path &file, const std::string &group)
Sets the file group ownership. Throws on error.
Definition: gfile_unix.cpp:330
A Path object represents a file system path.
Definition: gpath.h:73
Represents a unix-epoch time with microsecond resolution.
Definition: gdatetime.h:134
Low-level classes.
Definition: garg.h:30
constexpr const char * tx(const char *p)
A briefer alternative to G::gettext_noop().
Definition: ggettext.h:84
STL namespace.
An overload discriminator for G::File::open().
Definition: gfile.h:65
A portable 'struct stat'.
Definition: gfile.h:67