mirror of https://github.com/upx/upx.git
Improved IO error checking.
This commit is contained in:
parent
eab5da075a
commit
07baed1581
2
Makefile
2
Makefile
|
@ -36,7 +36,7 @@ endif
|
||||||
$(MAKE) -C doc $@
|
$(MAKE) -C doc $@
|
||||||
|
|
||||||
|
|
||||||
ifneq ($(wildcard .hg/data/.),)
|
ifneq ($(wildcard .hg/.),)
|
||||||
# automatically generate ChangeLog from local Mercurial repo
|
# automatically generate ChangeLog from local Mercurial repo
|
||||||
ChangeLog:
|
ChangeLog:
|
||||||
hg log --style=changelog > $@
|
hg log --style=changelog > $@
|
||||||
|
|
31
src/file.cpp
31
src/file.cpp
|
@ -88,7 +88,7 @@ FileBase::~FileBase()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void FileBase::sopen()
|
bool FileBase::do_sopen()
|
||||||
{
|
{
|
||||||
if (_shflags < 0)
|
if (_shflags < 0)
|
||||||
_fd = ::open(_name, _flags, _mode);
|
_fd = ::open(_name, _flags, _mode);
|
||||||
|
@ -101,13 +101,15 @@ void FileBase::sopen()
|
||||||
#elif defined(SH_DENYRW)
|
#elif defined(SH_DENYRW)
|
||||||
_fd = ::sopen(_name, _flags, _shflags, _mode);
|
_fd = ::sopen(_name, _flags, _shflags, _mode);
|
||||||
#else
|
#else
|
||||||
assert(0);
|
throwInternalError("bad usage of do_sopen()");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (!(_fd < 0)) {
|
if (_fd < 0)
|
||||||
::fstat(_fd, &st);
|
return false;
|
||||||
_length = st.st_size;
|
if (::fstat(_fd, &st) != 0)
|
||||||
}
|
throwIOException(_name, errno);
|
||||||
|
_length = st.st_size;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -232,8 +234,7 @@ void InputFile::sopen(const char *name, int flags, int shflags)
|
||||||
_mode = 0;
|
_mode = 0;
|
||||||
_offset = 0;
|
_offset = 0;
|
||||||
_length = 0;
|
_length = 0;
|
||||||
FileBase::sopen();
|
if (!FileBase::do_sopen())
|
||||||
if (!isOpen())
|
|
||||||
{
|
{
|
||||||
if (errno == ENOENT)
|
if (errno == ENOENT)
|
||||||
throw FileNotFoundException(_name, errno);
|
throw FileNotFoundException(_name, errno);
|
||||||
|
@ -318,8 +319,7 @@ void OutputFile::sopen(const char *name, int flags, int shflags, int mode)
|
||||||
_mode = mode;
|
_mode = mode;
|
||||||
_offset = 0;
|
_offset = 0;
|
||||||
_length = 0;
|
_length = 0;
|
||||||
FileBase::sopen();
|
if (!FileBase::do_sopen())
|
||||||
if (!isOpen())
|
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
// don't throw FileNotFound here -- this is confusing
|
// don't throw FileNotFound here -- this is confusing
|
||||||
|
@ -366,7 +366,8 @@ off_t OutputFile::st_size() const
|
||||||
return bytes_written; // too big if seek()+write() instead of rewrite()
|
return bytes_written; // too big if seek()+write() instead of rewrite()
|
||||||
}
|
}
|
||||||
struct stat my_st;
|
struct stat my_st;
|
||||||
::fstat(_fd, &my_st);
|
if (::fstat(_fd, &my_st) != 0)
|
||||||
|
throwIOException(_name, errno);
|
||||||
return my_st.st_size;
|
return my_st.st_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -402,15 +403,19 @@ void OutputFile::set_extent(off_t offset, off_t length)
|
||||||
super::set_extent(offset, length);
|
super::set_extent(offset, length);
|
||||||
bytes_written = 0;
|
bytes_written = 0;
|
||||||
if (0==offset && (off_t)~0u==length) {
|
if (0==offset && (off_t)~0u==length) {
|
||||||
::fstat(_fd, &st);
|
if (::fstat(_fd, &st) != 0)
|
||||||
|
throwIOException(_name, errno);
|
||||||
_length = st.st_size - offset;
|
_length = st.st_size - offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
off_t OutputFile::unset_extent()
|
off_t OutputFile::unset_extent()
|
||||||
{
|
{
|
||||||
|
off_t l = ::lseek(_fd, 0, SEEK_END);
|
||||||
|
if (l < 0)
|
||||||
|
throwIOException("lseek error", errno);
|
||||||
_offset = 0;
|
_offset = 0;
|
||||||
_length = ::lseek(_fd, 0, SEEK_END);
|
_length = l;
|
||||||
bytes_written = _length;
|
bytes_written = _length;
|
||||||
return _length;
|
return _length;
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ public:
|
||||||
virtual void set_extent(off_t offset, off_t length);
|
virtual void set_extent(off_t offset, off_t length);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void sopen();
|
bool do_sopen();
|
||||||
virtual int read(void *buf, int len);
|
virtual int read(void *buf, int len);
|
||||||
virtual int readx(void *buf, int len);
|
virtual int readx(void *buf, int len);
|
||||||
virtual void write(const void *buf, int len);
|
virtual void write(const void *buf, int len);
|
||||||
|
|
41
src/work.cpp
41
src/work.cpp
|
@ -51,6 +51,9 @@
|
||||||
# define SH_DENYWR (-1)
|
# define SH_DENYWR (-1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// ignore errors in some cases and silence __attribute__((__warn_unused_result__))
|
||||||
|
#define IGNORE_ERROR(var) ACC_UNUSED(var)
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// process one file
|
// process one file
|
||||||
|
@ -98,8 +101,13 @@ void do_one_file(const char *iname, char *oname)
|
||||||
fi.sopen(iname, O_RDONLY | O_BINARY, SH_DENYWR);
|
fi.sopen(iname, O_RDONLY | O_BINARY, SH_DENYWR);
|
||||||
|
|
||||||
#if defined(USE_FTIME)
|
#if defined(USE_FTIME)
|
||||||
struct ftime fit;
|
struct ftime fi_ftime;
|
||||||
getftime(fi.getFd(),&fit);
|
memset(&fi_ftime, 0, sizeof(fi_ftime));
|
||||||
|
if (opt->preserve_timestamp)
|
||||||
|
{
|
||||||
|
if (getftime(fi.getFd(), &fi_ftime) != 0)
|
||||||
|
throwIOException("cannot determine file timestamp");
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// open output file
|
// open output file
|
||||||
|
@ -124,9 +132,11 @@ void do_one_file(const char *iname, char *oname)
|
||||||
if (opt->force >= 2)
|
if (opt->force >= 2)
|
||||||
{
|
{
|
||||||
#if defined(HAVE_CHMOD)
|
#if defined(HAVE_CHMOD)
|
||||||
(void) ::chmod(tname, 0777);
|
r = chmod(tname, 0777);
|
||||||
|
IGNORE_ERROR(r);
|
||||||
#endif
|
#endif
|
||||||
(void) ::unlink(tname);
|
r = unlink(tname);
|
||||||
|
IGNORE_ERROR(r);
|
||||||
}
|
}
|
||||||
int flags = O_CREAT | O_WRONLY | O_BINARY;
|
int flags = O_CREAT | O_WRONLY | O_BINARY;
|
||||||
if (opt->force)
|
if (opt->force)
|
||||||
|
@ -165,15 +175,17 @@ void do_one_file(const char *iname, char *oname)
|
||||||
throwInternalError("invalid command");
|
throwInternalError("invalid command");
|
||||||
|
|
||||||
// copy time stamp
|
// copy time stamp
|
||||||
if (oname[0] && fo.isOpen())
|
if (opt->preserve_timestamp && oname[0] && fo.isOpen())
|
||||||
{
|
{
|
||||||
#if defined(USE_FTIME)
|
#if defined(USE_FTIME)
|
||||||
setftime(fo.getFd(),&fit);
|
r = setftime(fo.getFd(), &fi_ftime);
|
||||||
|
IGNORE_ERROR(r);
|
||||||
#elif defined(USE__FUTIME)
|
#elif defined(USE__FUTIME)
|
||||||
struct _utimbuf u;
|
struct _utimbuf u;
|
||||||
u.actime = st.st_atime;
|
u.actime = st.st_atime;
|
||||||
u.modtime = st.st_mtime;
|
u.modtime = st.st_mtime;
|
||||||
(void) _futime(fo.getFd(),&u);
|
r = _futime(fo.getFd(), &u);
|
||||||
|
IGNORE_ERROR(r);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,7 +200,8 @@ void do_one_file(const char *iname, char *oname)
|
||||||
if (!opt->backup)
|
if (!opt->backup)
|
||||||
{
|
{
|
||||||
#if defined(HAVE_CHMOD)
|
#if defined(HAVE_CHMOD)
|
||||||
(void) ::chmod(iname, 0777);
|
r = chmod(iname, 0777);
|
||||||
|
IGNORE_ERROR(r);
|
||||||
#endif
|
#endif
|
||||||
File::unlink(iname);
|
File::unlink(iname);
|
||||||
}
|
}
|
||||||
|
@ -217,7 +230,7 @@ void do_one_file(const char *iname, char *oname)
|
||||||
u.actime = st.st_atime;
|
u.actime = st.st_atime;
|
||||||
u.modtime = st.st_mtime;
|
u.modtime = st.st_mtime;
|
||||||
r = utime(name, &u);
|
r = utime(name, &u);
|
||||||
UNUSED(r);
|
IGNORE_ERROR(r);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(HAVE_CHMOD)
|
#if defined(HAVE_CHMOD)
|
||||||
|
@ -225,7 +238,7 @@ void do_one_file(const char *iname, char *oname)
|
||||||
if (opt->preserve_mode)
|
if (opt->preserve_mode)
|
||||||
{
|
{
|
||||||
r = chmod(name, st.st_mode);
|
r = chmod(name, st.st_mode);
|
||||||
UNUSED(r);
|
IGNORE_ERROR(r);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(HAVE_CHOWN)
|
#if defined(HAVE_CHOWN)
|
||||||
|
@ -233,7 +246,7 @@ void do_one_file(const char *iname, char *oname)
|
||||||
if (opt->preserve_ownership)
|
if (opt->preserve_ownership)
|
||||||
{
|
{
|
||||||
r = chown(name, st.st_uid, st.st_gid);
|
r = chown(name, st.st_uid, st.st_gid);
|
||||||
UNUSED(r);
|
IGNORE_ERROR(r);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -251,9 +264,11 @@ static void unlink_ofile(char *oname)
|
||||||
if (oname && oname[0])
|
if (oname && oname[0])
|
||||||
{
|
{
|
||||||
#if defined(HAVE_CHMOD)
|
#if defined(HAVE_CHMOD)
|
||||||
(void) ::chmod(oname, 0777);
|
int r;
|
||||||
|
r = chmod(oname, 0777);
|
||||||
|
IGNORE_ERROR(r);
|
||||||
#endif
|
#endif
|
||||||
if (::unlink(oname) == 0)
|
if (unlink(oname) == 0)
|
||||||
oname[0] = 0;
|
oname[0] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue