/* file.h -- This file is part of the UPX executable compressor. Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Laszlo Molnar All Rights Reserved. UPX and the UCL library are free software; you can redistribute them and/or modify them under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Markus F.X.J. Oberhumer Laszlo Molnar */ #pragma once /************************************************************************* // **************************************************************************/ class FileBase { protected: explicit FileBase() noexcept = default; virtual ~FileBase() may_throw; public: bool close_noexcept() noexcept; void closex() may_throw; bool isOpen() const noexcept { return _fd >= 0; } int getFd() const noexcept { return _fd; } const char *getName() const noexcept { return _name; } virtual upx_off_t seek(upx_off_t off, int whence); upx_off_t tell() const; virtual upx_off_t st_size() const; // { return _length; } virtual void set_extent(upx_off_t offset, upx_off_t length); public: // static file-related util functions; will throw on error static void chmod(const char *name, int mode) may_throw; static void rename(const char *old_, const char *new_) may_throw; static void unlink(const char *name) may_throw; static bool unlink_noexcept(const char *name) noexcept; protected: bool do_sopen(); int _fd = -1; int _flags = 0; int _shflags = 0; int _mode = 0; const char *_name = nullptr; upx_off_t _offset = 0; upx_off_t _length = 0; public: struct stat st = {}; }; /************************************************************************* // **************************************************************************/ class InputFile final : public FileBase { typedef FileBase super; public: explicit InputFile() noexcept = default; void sopen(const char *name, int flags, int shflags); void open(const char *name, int flags) { sopen(name, flags, -1); } int read(SPAN_P(void) buf, upx_int64_t blen); int readx(SPAN_P(void) buf, upx_int64_t blen); virtual upx_off_t seek(upx_off_t off, int whence) override; upx_off_t st_size_orig() const; noinline int dupFd() may_throw; protected: upx_off_t _length_orig = 0; }; /************************************************************************* // **************************************************************************/ class OutputFile final : public FileBase { typedef FileBase super; public: explicit OutputFile() noexcept = default; void sopen(const char *name, int flags, int shflags, int mode); void open(const char *name, int flags, int mode) { sopen(name, flags, -1, mode); } bool openStdout(int flags = 0, bool force = false); // info: allow nullptr if blen == 0 void write(SPAN_0(const void) buf, upx_int64_t blen); virtual upx_off_t seek(upx_off_t off, int whence) override; virtual upx_off_t st_size() const override; // { return _length; } virtual void set_extent(upx_off_t offset, upx_off_t length) override; upx_off_t unset_extent(); // returns actual length upx_off_t getBytesWritten() const { return bytes_written; } // FIXME - this won't work when using the '--stdout' option void rewrite(SPAN_P(const void) buf, int len); // util static void dump(const char *name, SPAN_P(const void) buf, int len, int flags = -1); protected: upx_off_t bytes_written = 0; }; /* vim:set ts=4 sw=4 et: */