1
0
mirror of https://github.com/upx/upx synced 2025-09-28 19:06:07 +08:00
upx/src/file.cpp
Markus F.X.J. Oberhumer 3e785008d3 Avoid warnings.
committer: mfx <mfx> 1119613856 +0000
2005-06-24 11:50:56 +00:00

392 lines
7.9 KiB
C++

/* file.cpp --
This file is part of the UPX executable compressor.
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2004 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)
{
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();
}
void FileBase::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
assert(0);
#endif
}
}
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;
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 && off < 0)
throwIOException("bad seek 2");
if (whence == SEEK_END && off > 0)
throwIOException("bad seek 3");
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;
}
/*************************************************************************
//
**************************************************************************/
InputFile::InputFile()
{
}
InputFile::~InputFile()
{
}
void InputFile::sopen(const char *name, int flags, int shflags)
{
close();
_name = name;
_flags = flags;
_shflags = shflags;
_mode = 0;
FileBase::sopen();
if (!isOpen())
{
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;
FileBase::sopen();
if (!isOpen())
{
#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;
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;
}
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::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 0
MemoryOutputFile::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
*/