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 $@
|
||||
|
||||
|
||||
ifneq ($(wildcard .hg/data/.),)
|
||||
ifneq ($(wildcard .hg/.),)
|
||||
# automatically generate ChangeLog from local Mercurial repo
|
||||
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)
|
||||
_fd = ::open(_name, _flags, _mode);
|
||||
|
@ -101,13 +101,15 @@ void FileBase::sopen()
|
|||
#elif defined(SH_DENYRW)
|
||||
_fd = ::sopen(_name, _flags, _shflags, _mode);
|
||||
#else
|
||||
assert(0);
|
||||
throwInternalError("bad usage of do_sopen()");
|
||||
#endif
|
||||
}
|
||||
if (!(_fd < 0)) {
|
||||
::fstat(_fd, &st);
|
||||
_length = st.st_size;
|
||||
}
|
||||
if (_fd < 0)
|
||||
return false;
|
||||
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;
|
||||
_offset = 0;
|
||||
_length = 0;
|
||||
FileBase::sopen();
|
||||
if (!isOpen())
|
||||
if (!FileBase::do_sopen())
|
||||
{
|
||||
if (errno == ENOENT)
|
||||
throw FileNotFoundException(_name, errno);
|
||||
|
@ -318,8 +319,7 @@ void OutputFile::sopen(const char *name, int flags, int shflags, int mode)
|
|||
_mode = mode;
|
||||
_offset = 0;
|
||||
_length = 0;
|
||||
FileBase::sopen();
|
||||
if (!isOpen())
|
||||
if (!FileBase::do_sopen())
|
||||
{
|
||||
#if 0
|
||||
// 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()
|
||||
}
|
||||
struct stat my_st;
|
||||
::fstat(_fd, &my_st);
|
||||
if (::fstat(_fd, &my_st) != 0)
|
||||
throwIOException(_name, errno);
|
||||
return my_st.st_size;
|
||||
}
|
||||
|
||||
|
@ -402,15 +403,19 @@ 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) {
|
||||
::fstat(_fd, &st);
|
||||
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 = ::lseek(_fd, 0, SEEK_END);
|
||||
_length = l;
|
||||
bytes_written = _length;
|
||||
return _length;
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ public:
|
|||
virtual void set_extent(off_t offset, off_t length);
|
||||
|
||||
protected:
|
||||
void sopen();
|
||||
bool do_sopen();
|
||||
virtual int read(void *buf, int len);
|
||||
virtual int readx(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)
|
||||
#endif
|
||||
|
||||
// ignore errors in some cases and silence __attribute__((__warn_unused_result__))
|
||||
#define IGNORE_ERROR(var) ACC_UNUSED(var)
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// 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);
|
||||
|
||||
#if defined(USE_FTIME)
|
||||
struct ftime fit;
|
||||
getftime(fi.getFd(),&fit);
|
||||
struct ftime fi_ftime;
|
||||
memset(&fi_ftime, 0, sizeof(fi_ftime));
|
||||
if (opt->preserve_timestamp)
|
||||
{
|
||||
if (getftime(fi.getFd(), &fi_ftime) != 0)
|
||||
throwIOException("cannot determine file timestamp");
|
||||
}
|
||||
#endif
|
||||
|
||||
// open output file
|
||||
|
@ -124,9 +132,11 @@ void do_one_file(const char *iname, char *oname)
|
|||
if (opt->force >= 2)
|
||||
{
|
||||
#if defined(HAVE_CHMOD)
|
||||
(void) ::chmod(tname, 0777);
|
||||
r = chmod(tname, 0777);
|
||||
IGNORE_ERROR(r);
|
||||
#endif
|
||||
(void) ::unlink(tname);
|
||||
r = unlink(tname);
|
||||
IGNORE_ERROR(r);
|
||||
}
|
||||
int flags = O_CREAT | O_WRONLY | O_BINARY;
|
||||
if (opt->force)
|
||||
|
@ -165,15 +175,17 @@ void do_one_file(const char *iname, char *oname)
|
|||
throwInternalError("invalid command");
|
||||
|
||||
// copy time stamp
|
||||
if (oname[0] && fo.isOpen())
|
||||
if (opt->preserve_timestamp && oname[0] && fo.isOpen())
|
||||
{
|
||||
#if defined(USE_FTIME)
|
||||
setftime(fo.getFd(),&fit);
|
||||
r = setftime(fo.getFd(), &fi_ftime);
|
||||
IGNORE_ERROR(r);
|
||||
#elif defined(USE__FUTIME)
|
||||
struct _utimbuf u;
|
||||
u.actime = st.st_atime;
|
||||
u.modtime = st.st_mtime;
|
||||
(void) _futime(fo.getFd(),&u);
|
||||
r = _futime(fo.getFd(), &u);
|
||||
IGNORE_ERROR(r);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -188,7 +200,8 @@ void do_one_file(const char *iname, char *oname)
|
|||
if (!opt->backup)
|
||||
{
|
||||
#if defined(HAVE_CHMOD)
|
||||
(void) ::chmod(iname, 0777);
|
||||
r = chmod(iname, 0777);
|
||||
IGNORE_ERROR(r);
|
||||
#endif
|
||||
File::unlink(iname);
|
||||
}
|
||||
|
@ -217,7 +230,7 @@ void do_one_file(const char *iname, char *oname)
|
|||
u.actime = st.st_atime;
|
||||
u.modtime = st.st_mtime;
|
||||
r = utime(name, &u);
|
||||
UNUSED(r);
|
||||
IGNORE_ERROR(r);
|
||||
}
|
||||
#endif
|
||||
#if defined(HAVE_CHMOD)
|
||||
|
@ -225,7 +238,7 @@ void do_one_file(const char *iname, char *oname)
|
|||
if (opt->preserve_mode)
|
||||
{
|
||||
r = chmod(name, st.st_mode);
|
||||
UNUSED(r);
|
||||
IGNORE_ERROR(r);
|
||||
}
|
||||
#endif
|
||||
#if defined(HAVE_CHOWN)
|
||||
|
@ -233,7 +246,7 @@ void do_one_file(const char *iname, char *oname)
|
|||
if (opt->preserve_ownership)
|
||||
{
|
||||
r = chown(name, st.st_uid, st.st_gid);
|
||||
UNUSED(r);
|
||||
IGNORE_ERROR(r);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -251,9 +264,11 @@ static void unlink_ofile(char *oname)
|
|||
if (oname && oname[0])
|
||||
{
|
||||
#if defined(HAVE_CHMOD)
|
||||
(void) ::chmod(oname, 0777);
|
||||
int r;
|
||||
r = chmod(oname, 0777);
|
||||
IGNORE_ERROR(r);
|
||||
#endif
|
||||
if (::unlink(oname) == 0)
|
||||
if (unlink(oname) == 0)
|
||||
oname[0] = 0;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue