summaryrefslogtreecommitdiff
path: root/klm/util/file.hh
diff options
context:
space:
mode:
Diffstat (limited to 'klm/util/file.hh')
-rw-r--r--klm/util/file.hh70
1 files changed, 51 insertions, 19 deletions
diff --git a/klm/util/file.hh b/klm/util/file.hh
index 8af1ff4f..be88431d 100644
--- a/klm/util/file.hh
+++ b/klm/util/file.hh
@@ -1,6 +1,8 @@
#ifndef UTIL_FILE__
#define UTIL_FILE__
+#include "util/exception.hh"
+
#include <cstddef>
#include <cstdio>
#include <string>
@@ -17,7 +19,7 @@ class scoped_fd {
~scoped_fd();
- void reset(int to) {
+ void reset(int to = -1) {
scoped_fd other(fd_);
fd_ = to;
}
@@ -32,8 +34,6 @@ class scoped_fd {
return ret;
}
- operator bool() { return fd_ != -1; }
-
private:
int fd_;
@@ -65,6 +65,32 @@ class scoped_FILE {
std::FILE *file_;
};
+/* Thrown for any operation where the fd is known. */
+class FDException : public ErrnoException {
+ public:
+ explicit FDException(int fd) throw();
+
+ virtual ~FDException() throw();
+
+ // This may no longer be valid if the exception was thrown past open.
+ int FD() const { return fd_; }
+
+ // Guess from NameFromFD.
+ const std::string &NameGuess() const { return name_guess_; }
+
+ private:
+ int fd_;
+
+ std::string name_guess_;
+};
+
+// End of file reached.
+class EndOfFileException : public Exception {
+ public:
+ EndOfFileException() throw();
+ ~EndOfFileException() throw();
+};
+
// Open for read only.
int OpenReadOrThrow(const char *name);
// Create file if it doesn't exist, truncate if it does. Opened for write.
@@ -73,13 +99,18 @@ int CreateOrThrow(const char *name);
// Return value for SizeFile when it can't size properly.
const uint64_t kBadSize = (uint64_t)-1;
uint64_t SizeFile(int fd);
+uint64_t SizeOrThrow(int fd);
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 amount);
+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);
void FSyncOrThrow(int fd);
@@ -89,21 +120,22 @@ void AdvanceOrThrow(int fd, int64_t off);
void SeekEnd(int fd);
std::FILE *FDOpenOrThrow(scoped_fd &file);
-
-class TempMaker {
- public:
- explicit TempMaker(const std::string &prefix);
-
- // These will already be unlinked for you.
- int Make() const;
- std::FILE *MakeFile() const;
-
- // This will force you to close the fd instead of leaving it open.
- std::string Name(scoped_fd &opened) const;
-
- private:
- std::string base_;
-};
+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);
+
+// dup an fd.
+int DupOrThrow(int fd);
+
+/* Attempt get file name from fd. This won't always work (i.e. on Windows or
+ * a pipe). The file might have been renamed. It's intended for diagnostics
+ * and logging only.
+ */
+std::string NameFromFD(int fd);
} // namespace util