diff options
Diffstat (limited to 'klm/util/file.hh')
-rw-r--r-- | klm/util/file.hh | 49 |
1 files changed, 20 insertions, 29 deletions
diff --git a/klm/util/file.hh b/klm/util/file.hh index be88431d..7204b6a0 100644 --- a/klm/util/file.hh +++ b/klm/util/file.hh @@ -1,7 +1,9 @@ -#ifndef UTIL_FILE__ -#define UTIL_FILE__ +#ifndef UTIL_FILE_H +#define UTIL_FILE_H #include "util/exception.hh" +#include "util/scoped.hh" +#include "util/string_piece.hh" #include <cstddef> #include <cstdio> @@ -41,29 +43,10 @@ class scoped_fd { scoped_fd &operator=(const scoped_fd &); }; -class scoped_FILE { - public: - explicit scoped_FILE(std::FILE *file = NULL) : file_(file) {} - - ~scoped_FILE(); - - std::FILE *get() { return file_; } - const std::FILE *get() const { return file_; } - - void reset(std::FILE *to = NULL) { - scoped_FILE other(file_); - file_ = to; - } - - std::FILE *release() { - std::FILE *ret = file_; - file_ = NULL; - return ret; - } - - private: - std::FILE *file_; +struct scoped_FILE_closer { + static void Close(std::FILE *file); }; +typedef scoped<std::FILE, scoped_FILE_closer> scoped_FILE; /* Thrown for any operation where the fd is known. */ class FDException : public ErrnoException { @@ -106,12 +89,20 @@ void ResizeOrThrow(int fd, uint64_t to); std::size_t PartialRead(int fd, void *to, std::size_t size); void ReadOrThrow(int fd, void *to, std::size_t size); std::size_t ReadOrEOF(int fd, void *to_void, std::size_t size); -// Positioned: unix only for now. -void PReadOrThrow(int fd, void *to, std::size_t size, uint64_t off); void WriteOrThrow(int fd, const void *data_void, std::size_t size); void WriteOrThrow(FILE *to, const void *data, std::size_t size); +/* These call pread/pwrite in a loop. However, on Windows they call ReadFile/ + * WriteFile which changes the file pointer. So it's safe to call ErsatzPRead + * and ErsatzPWrite concurrently (or any combination thereof). But it changes + * the file pointer on windows, so it's not safe to call concurrently with + * anything that uses the implicit file pointer e.g. the Read/Write functions + * above. + */ +void ErsatzPRead(int fd, void *to, std::size_t size, uint64_t off); +void ErsatzPWrite(int fd, const void *data_void, std::size_t size, uint64_t off); + void FSyncOrThrow(int fd); // Seeking @@ -125,8 +116,8 @@ std::FILE *FDOpenReadOrThrow(scoped_fd &file); // Temporary files // Append a / if base is a directory. void NormalizeTempPrefix(std::string &base); -int MakeTemp(const std::string &prefix); -std::FILE *FMakeTemp(const std::string &prefix); +int MakeTemp(const StringPiece &prefix); +std::FILE *FMakeTemp(const StringPiece &prefix); // dup an fd. int DupOrThrow(int fd); @@ -139,4 +130,4 @@ std::string NameFromFD(int fd); } // namespace util -#endif // UTIL_FILE__ +#endif // UTIL_FILE_H |