// See the file "COPYING" in the main distribution directory for copyright. #pragma once #include #include #include #include #include "zeek/Val.h" #include "zeek/util.h" namespace zeek { namespace detail { class PrintStmt; class Attributes; extern void do_print_stmt(const std::vector& vals); } // namespace detail class RecordVal; class Type; using TypePtr = IntrusivePtr; class File; using FilePtr = IntrusivePtr; class File final : public Obj { public: explicit File(FILE* arg_f); File(FILE* arg_f, const char* filename, const char* access); File(const char* filename, const char* access); ~File() override; const char* Name() const; // Returns false if an error occurred. bool Write(const char* data, int len = 0); void Flush() { fflush(f); } FILE* Seek(long position); // seek to absolute position void SetBuf(bool buffered); // false=line buffered, true=fully buffered const TypePtr& GetType() const { return t; } // Whether the file is open in a general sense; it might // not be open as a Unix file due to our management of // a finite number of FDs. bool IsOpen() const { return is_open; } // Returns true if the close made sense, false if it was already // closed, not active, or whatever. bool Close(); void Describe(ODesc* d) const override; // Rotates the logfile. Returns rotate_info. RecordVal* Rotate(); // Set &raw_output attribute. void SetAttrs(detail::Attributes* attrs); // Returns the current size of the file, after fresh stat'ing. double Size(); // Close all files which are currently open. static void CloseOpenFiles(); // Get the file with the given name, opening it if it doesn't yet exist. static FilePtr Get(const char* name); void EnableRawOutput() { raw_output = true; } bool IsRawOutput() const { return raw_output; } protected: friend void detail::do_print_stmt(const std::vector& vals); File() { Init(); } void Init(); /** * If file is given, it's an open file to use already. * If file is not given and mode is, the filename will be opened with that * access mode. */ bool Open(FILE* f = nullptr, const char* mode = nullptr); void Unlink(); // Returns nil if the file is not active, was in error, etc. // (Protected because we do not want anyone to write directly // to the file, but the PrintStmt friend uses this to check whether // it's really stdout.) FILE* FileHandle(); // Raises a file_opened event. void RaiseOpenEvent(); FILE* f = nullptr; TypePtr t; char* name = nullptr; char* access = nullptr; detail::Attributes* attrs = nullptr; double open_time = 0.0; bool is_open = false; // whether the file is open in a general sense bool buffered = false; bool raw_output = false; static constexpr int MIN_BUFFER_SIZE = 1024; private: static std::list> open_files; }; } // namespace zeek