⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 file.cpp

📁 UPX 源代码
💻 CPP
字号:
/* file.cpp --   This file is part of the UPX executable compressor.   Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer   Copyright (C) 1996-2007 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   <mfx@users.sourceforge.net>          <ml1050@users.sourceforge.net> */#include "conf.h"#include "file.h"#include "mem.h"/*************************************************************************//**************************************************************************/void File::chmod(const char *name, int mode){#if defined(HAVE_CHMOD)    if (::chmod(name,mode) != 0)        throwIOException(name,errno);#else    UNUSED(name); UNUSED(mode);#endif}void File::rename(const char *old_, const char *new_){#if defined(__DJGPP__)    if (::_rename(old_,new_) != 0)#else    if (::rename(old_,new_) != 0)#endif        throwIOException("rename error",errno);}void File::unlink(const char *name){    if (::unlink(name) != 0)        throwIOException(name,errno);}/*************************************************************************//**************************************************************************/FileBase::FileBase() :    _fd(-1), _flags(0), _shflags(0), _mode(0), _name(NULL), _offset(0), _length(0){    memset(&st,0,sizeof(st));}FileBase::~FileBase(){#if 0 && defined(__GNUC__)    // debug    if (isOpen())        fprintf(stderr,"%s: %s\n", _name, __PRETTY_FUNCTION__);#endif    // FIXME: we should use close() during exception unwinding but    //        closex() otherwise    closex();}bool FileBase::do_sopen(){    if (_shflags < 0)        _fd = ::open(_name, _flags, _mode);    else    {#if defined(__DJGPP__)        _fd = ::open(_name,_flags | _shflags, _mode);#elif defined(__MINT__)        _fd = ::open(_name,_flags | (_shflags & O_SHMODE), _mode);#elif defined(SH_DENYRW)        _fd = ::sopen(_name, _flags, _shflags, _mode);#else        throwInternalError("bad usage of do_sopen()");#endif    }    if (_fd < 0)        return false;    if (::fstat(_fd, &st) != 0)        throwIOException(_name, errno);    _length = st.st_size;    return true;}bool FileBase::close(){    bool ok = true;    if (isOpen() && _fd != STDIN_FILENO && _fd != STDOUT_FILENO && _fd != STDERR_FILENO)        if (::close(_fd) == -1)            ok = false;    _fd = -1;    _flags = 0;    _mode = 0;    _name = NULL;    _offset = 0;    _length = 0;    return ok;}void FileBase::closex(){    if (!close())        throwIOException("close failed",errno);}int FileBase::read(void *buf, int len){    if (!isOpen() || len < 0)        throwIOException("bad read");    errno = 0;    long l = acc_safe_hread(_fd, buf, len);    if (errno)        throwIOException("read error",errno);    return (int) l;}int FileBase::readx(void *buf, int len){    int l = this->read(buf, len);    if (l != len)        throwEOFException();    return l;}void FileBase::write(const void *buf, int len){    if (!isOpen() || len < 0)        throwIOException("bad write");    errno = 0;    long l = acc_safe_hwrite(_fd, buf, len);    if (l != len)        throwIOException("write error",errno);}void FileBase::seek(off_t off, int whence){    if (!isOpen())        throwIOException("bad seek 1");    if (whence == SEEK_SET) {        if (off < 0)            throwIOException("bad seek 2");        off += _offset;    }    if (whence == SEEK_END) {        if (off > 0)            throwIOException("bad seek 3");        off += _offset + _length;        whence = SEEK_SET;    }    if (::lseek(_fd,off,whence) < 0)        throwIOException("seek error",errno);}off_t FileBase::tell() const{    if (!isOpen())        throwIOException("bad tell");    off_t l = ::lseek(_fd, 0, SEEK_CUR);    if (l < 0)        throwIOException("tell error",errno);    return l - _offset;}void FileBase::set_extent(off_t offset, off_t length){    _offset = offset;    _length = length;}off_t FileBase::st_size() const{    return _length;}/*************************************************************************//**************************************************************************/InputFile::InputFile(){}InputFile::~InputFile(){}void InputFile::sopen(const char *name, int flags, int shflags){    close();    _name = name;    _flags = flags;    _shflags = shflags;    _mode = 0;    _offset = 0;    _length = 0;    if (!FileBase::do_sopen())    {        if (errno == ENOENT)            throw FileNotFoundException(_name, errno);        else if (errno == EEXIST)            throw FileAlreadyExistsException(_name, errno);        else            throwIOException(_name, errno);    }}int InputFile::read(void *buf, int len){    return super::read(buf, len);}int InputFile::readx(void *buf, int len){    return super::readx(buf, len);}int InputFile::read(MemBuffer *buf, int len){    buf->checkState();    assert((unsigned)len <= buf->getSize());    return read(buf->getVoidPtr(), len);}int InputFile::readx(MemBuffer *buf, int len){    buf->checkState();    assert((unsigned)len <= buf->getSize());    return read(buf->getVoidPtr(), len);}int InputFile::read(MemBuffer &buf, int len){    return read(&buf, len);}int InputFile::readx(MemBuffer &buf, int len){    return readx(&buf, len);}void InputFile::seek(off_t off, int whence){    super::seek(off,whence);}off_t InputFile::tell() const{    return super::tell();}/*************************************************************************//**************************************************************************/OutputFile::OutputFile() :    bytes_written(0){}OutputFile::~OutputFile(){}void OutputFile::sopen(const char *name, int flags, int shflags, int mode){    close();    _name = name;    _flags = flags;    _shflags = shflags;    _mode = mode;    _offset = 0;    _length = 0;    if (!FileBase::do_sopen())    {#if 0        // don't throw FileNotFound here -- this is confusing        if (errno == ENOENT)            throw FileNotFoundException(_name,errno);        else#endif        if (errno == EEXIST)            throw FileAlreadyExistsException(_name,errno);        else            throwIOException(_name,errno);    }}bool OutputFile::openStdout(int flags, bool force){    close();    int fd = STDOUT_FILENO;    if (!force && acc_isatty(fd))        return false;    _name = "<stdout>";    _flags = flags;    _shflags = -1;    _mode = 0;    _offset = 0;    _length = 0;    if (flags && acc_set_binmode(fd, 1) == -1)        throwIOException(_name, errno);    _fd = fd;    return true;}void OutputFile::write(const void *buf, int len){    super::write(buf, len);    bytes_written += len;}off_t OutputFile::st_size() const{    if (opt->to_stdout) {  // might be a pipe ==> .st_size is invalid        return bytes_written;  // too big if seek()+write() instead of rewrite()    }    struct stat my_st;    if (::fstat(_fd, &my_st) != 0)        throwIOException(_name, errno);    return my_st.st_size;}void OutputFile::write(const MemBuffer *buf, int len){    buf->checkState();    assert((unsigned)len <= buf->getSize());    write(buf->getVoidPtr(), len);}void OutputFile::write(const MemBuffer &buf, int len){    write(&buf, len);}void OutputFile::rewrite(const void *buf, int len){    assert(!opt->to_stdout);    write(buf, len);    bytes_written -= len;       // restore}void OutputFile::seek(off_t off, int whence){    assert(!opt->to_stdout);    super::seek(off,whence);}void OutputFile::set_extent(off_t offset, off_t length){    super::set_extent(offset, length);    bytes_written = 0;    if (0==offset && (off_t)~0u==length) {        if (::fstat(_fd, &st) != 0)            throwIOException(_name, errno);        _length = st.st_size - offset;    }}off_t OutputFile::unset_extent(){    off_t l = ::lseek(_fd, 0, SEEK_END);    if (l < 0)        throwIOException("lseek error", errno);    _offset = 0;    _length = l;    bytes_written = _length;    return _length;}void OutputFile::dump(const char *name, const void *buf, int len, int flags){    if (flags < 0)         flags = O_CREAT | O_BINARY | O_TRUNC;    flags |= O_WRONLY;    OutputFile f;    f.open(name, flags, 0600);    f.write(buf, len);    f.closex();}/*************************************************************************//**************************************************************************/#if 0MemoryOutputFile::MemoryOutputFile() :    b(NULL), b_size(0), b_pos(0), bytes_written(0){}void MemoryOutputFile::write(const void *buf, int len){    if (!isOpen() || len < 0)        throwIOException("bad write");    if (len == 0)        return;    if (b_pos + len > b_size)        throwIOException("write error",ENOSPC);    memcpy(b + b_pos, buf, len);    b_pos += len;    bytes_written += len;}#endif /* if 0 *//*vi:ts=4:et*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -