mirror of https://github.com/aria2/aria2
2010-11-09 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Capture errno right after system/library call to avoid it to get overwritten. Use util::safeStrerror instead of strerror directly because strerror might return NULL. We don't check errno for std::fstream anymore. * src/AbstractDiskWriter.cc * src/CookieStorage.cc * src/DHTAutoSaveCommand.cc * src/DHTRoutingTableDeserializer.cc * src/DHTRoutingTableSerializer.cc * src/DefaultBtProgressInfoFile.cc * src/EpollEventPoll.cc * src/IteratableChunkChecksumValidator.cc * src/KqueueEventPoll.cc * src/Logger.cc * src/MessageDigestHelper.cc * src/PortEventPoll.cc * src/SelectEventPoll.cc * src/SocketCore.cc * src/message.h * src/util.cc * src/util.hpull/1/head
parent
02f725cab5
commit
228b4c50d7
24
ChangeLog
24
ChangeLog
|
@ -1,3 +1,27 @@
|
||||||
|
2010-11-09 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||||
|
|
||||||
|
Capture errno right after system/library call to avoid it to get
|
||||||
|
overwritten. Use util::safeStrerror instead of strerror directly
|
||||||
|
because strerror might return NULL. We don't check errno for
|
||||||
|
std::fstream anymore.
|
||||||
|
* src/AbstractDiskWriter.cc
|
||||||
|
* src/CookieStorage.cc
|
||||||
|
* src/DHTAutoSaveCommand.cc
|
||||||
|
* src/DHTRoutingTableDeserializer.cc
|
||||||
|
* src/DHTRoutingTableSerializer.cc
|
||||||
|
* src/DefaultBtProgressInfoFile.cc
|
||||||
|
* src/EpollEventPoll.cc
|
||||||
|
* src/IteratableChunkChecksumValidator.cc
|
||||||
|
* src/KqueueEventPoll.cc
|
||||||
|
* src/Logger.cc
|
||||||
|
* src/MessageDigestHelper.cc
|
||||||
|
* src/PortEventPoll.cc
|
||||||
|
* src/SelectEventPoll.cc
|
||||||
|
* src/SocketCore.cc
|
||||||
|
* src/message.h
|
||||||
|
* src/util.cc
|
||||||
|
* src/util.h
|
||||||
|
|
||||||
2010-11-07 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
2010-11-07 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||||
|
|
||||||
Use const reference
|
Use const reference
|
||||||
|
|
|
@ -99,10 +99,12 @@ void AbstractDiskWriter::openExistingFile(uint64_t totalLength)
|
||||||
}
|
}
|
||||||
|
|
||||||
if((fd_ = open(filename_.c_str(), flags, OPEN_MODE)) < 0) {
|
if((fd_ = open(filename_.c_str(), flags, OPEN_MODE)) < 0) {
|
||||||
|
int errNum = errno;
|
||||||
throw DL_ABORT_EX2
|
throw DL_ABORT_EX2
|
||||||
(errno,
|
(errNum,
|
||||||
StringFormat
|
StringFormat(EX_FILE_OPEN,
|
||||||
(EX_FILE_OPEN, filename_.c_str(), strerror(errno)).str());
|
filename_.c_str(),
|
||||||
|
util::safeStrerror(errNum).c_str()).str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,9 +114,12 @@ void AbstractDiskWriter::createFile(int addFlags)
|
||||||
util::mkdirs(File(filename_).getDirname());
|
util::mkdirs(File(filename_).getDirname());
|
||||||
if((fd_ = open(filename_.c_str(), O_CREAT|O_RDWR|O_TRUNC|O_BINARY|addFlags,
|
if((fd_ = open(filename_.c_str(), O_CREAT|O_RDWR|O_TRUNC|O_BINARY|addFlags,
|
||||||
OPEN_MODE)) < 0) {
|
OPEN_MODE)) < 0) {
|
||||||
|
int errNum = errno;
|
||||||
throw DL_ABORT_EX2
|
throw DL_ABORT_EX2
|
||||||
(errno,
|
(errNum,
|
||||||
StringFormat(EX_FILE_OPEN, filename_.c_str(), strerror(errno)).str());
|
StringFormat(EX_FILE_OPEN,
|
||||||
|
filename_.c_str(),
|
||||||
|
util::safeStrerror(errNum).c_str()).str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,8 +147,11 @@ ssize_t AbstractDiskWriter::readDataInternal(unsigned char* data, size_t len)
|
||||||
void AbstractDiskWriter::seek(off_t offset)
|
void AbstractDiskWriter::seek(off_t offset)
|
||||||
{
|
{
|
||||||
if(a2lseek(fd_, offset, SEEK_SET) == (off_t)-1) {
|
if(a2lseek(fd_, offset, SEEK_SET) == (off_t)-1) {
|
||||||
|
int errNum = errno;
|
||||||
throw DL_ABORT_EX
|
throw DL_ABORT_EX
|
||||||
(StringFormat(EX_FILE_SEEK, filename_.c_str(), strerror(errno)).str());
|
(StringFormat(EX_FILE_SEEK,
|
||||||
|
filename_.c_str(),
|
||||||
|
util::safeStrerror(errNum).c_str()).str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,14 +159,20 @@ void AbstractDiskWriter::writeData(const unsigned char* data, size_t len, off_t
|
||||||
{
|
{
|
||||||
seek(offset);
|
seek(offset);
|
||||||
if(writeDataInternal(data, len) < 0) {
|
if(writeDataInternal(data, len) < 0) {
|
||||||
|
int errNum = errno;
|
||||||
// If errno is ENOSPC(not enough space in device), throw
|
// If errno is ENOSPC(not enough space in device), throw
|
||||||
// DownloadFailureException and abort download instantly.
|
// DownloadFailureException and abort download instantly.
|
||||||
if(errno == ENOSPC) {
|
if(errNum == ENOSPC) {
|
||||||
throw DOWNLOAD_FAILURE_EXCEPTION
|
throw DOWNLOAD_FAILURE_EXCEPTION
|
||||||
(StringFormat(EX_FILE_WRITE, filename_.c_str(), strerror(errno)).str());
|
(StringFormat(EX_FILE_WRITE,
|
||||||
|
filename_.c_str(),
|
||||||
|
util::safeStrerror(errNum).c_str()).str());
|
||||||
|
} else {
|
||||||
|
throw DL_ABORT_EX
|
||||||
|
(StringFormat(EX_FILE_WRITE,
|
||||||
|
filename_.c_str(),
|
||||||
|
util::safeStrerror(errNum).c_str()).str());
|
||||||
}
|
}
|
||||||
throw DL_ABORT_EX(StringFormat(EX_FILE_WRITE,
|
|
||||||
filename_.c_str(), strerror(errno)).str());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,8 +181,11 @@ ssize_t AbstractDiskWriter::readData(unsigned char* data, size_t len, off_t offs
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
seek(offset);
|
seek(offset);
|
||||||
if((ret = readDataInternal(data, len)) < 0) {
|
if((ret = readDataInternal(data, len)) < 0) {
|
||||||
throw DL_ABORT_EX(StringFormat(EX_FILE_READ,
|
int errNum = errno;
|
||||||
filename_.c_str(), strerror(errno)).str());
|
throw DL_ABORT_EX
|
||||||
|
(StringFormat(EX_FILE_READ,
|
||||||
|
filename_.c_str(),
|
||||||
|
util::safeStrerror(errNum).c_str()).str());
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -189,8 +206,9 @@ void AbstractDiskWriter::truncate(uint64_t length)
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if(ftruncate(fd_, length) == -1) {
|
if(ftruncate(fd_, length) == -1) {
|
||||||
|
int errNum = errno;
|
||||||
throw DL_ABORT_EX(StringFormat("ftruncate failed. cause: %s",
|
throw DL_ABORT_EX(StringFormat("ftruncate failed. cause: %s",
|
||||||
strerror(errno)).str());
|
util::safeStrerror(errNum).c_str()).str());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -205,15 +223,16 @@ void AbstractDiskWriter::allocate(off_t offset, uint64_t length)
|
||||||
// For linux, we use fallocate to detect file system supports
|
// For linux, we use fallocate to detect file system supports
|
||||||
// fallocate or not.
|
// fallocate or not.
|
||||||
int r = fallocate(fd_, 0, offset, length);
|
int r = fallocate(fd_, 0, offset, length);
|
||||||
|
int errNum = errno;
|
||||||
if(r == -1) {
|
if(r == -1) {
|
||||||
throw DL_ABORT_EX(StringFormat("fallocate failed. cause: %s",
|
throw DL_ABORT_EX(StringFormat("fallocate failed. cause: %s",
|
||||||
strerror(errno)).str());
|
util::safeStrerror(errNum).c_str()).str());
|
||||||
}
|
}
|
||||||
# elif HAVE_POSIX_FALLOCATE
|
# elif HAVE_POSIX_FALLOCATE
|
||||||
int r = posix_fallocate(fd_, offset, length);
|
int r = posix_fallocate(fd_, offset, length);
|
||||||
if(r != 0) {
|
if(r != 0) {
|
||||||
throw DL_ABORT_EX(StringFormat("posix_fallocate failed. cause: %s",
|
throw DL_ABORT_EX(StringFormat("posix_fallocate failed. cause: %s",
|
||||||
strerror(r)).str());
|
util::safeStrerror(r).c_str()).str());
|
||||||
}
|
}
|
||||||
# else
|
# else
|
||||||
# error "no *_fallocate function available."
|
# error "no *_fallocate function available."
|
||||||
|
|
|
@ -343,8 +343,7 @@ bool CookieStorage::saveNsFormat(const std::string& filename)
|
||||||
{
|
{
|
||||||
std::ofstream o(tempfilename.c_str(), std::ios::binary);
|
std::ofstream o(tempfilename.c_str(), std::ios::binary);
|
||||||
if(!o) {
|
if(!o) {
|
||||||
logger_->error("Cannot create cookie file %s, cause %s",
|
logger_->error("Cannot create cookie file %s", filename.c_str());
|
||||||
filename.c_str(), strerror(errno));
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for(std::deque<DomainEntry>::const_iterator i = domains_.begin(),
|
for(std::deque<DomainEntry>::const_iterator i = domains_.begin(),
|
||||||
|
@ -353,8 +352,7 @@ bool CookieStorage::saveNsFormat(const std::string& filename)
|
||||||
}
|
}
|
||||||
o.flush();
|
o.flush();
|
||||||
if(!o) {
|
if(!o) {
|
||||||
logger_->error("Failed to save cookies to %s, cause %s",
|
logger_->error("Failed to save cookies to %s", filename.c_str());
|
||||||
filename.c_str(), strerror(errno));
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,6 @@
|
||||||
/* copyright --> */
|
/* copyright --> */
|
||||||
#include "DHTAutoSaveCommand.h"
|
#include "DHTAutoSaveCommand.h"
|
||||||
|
|
||||||
#include <cerrno>
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
|
@ -117,8 +116,8 @@ void DHTAutoSaveCommand::save()
|
||||||
std::ios::out|std::ios::binary);
|
std::ios::out|std::ios::binary);
|
||||||
if(!o) {
|
if(!o) {
|
||||||
throw DL_ABORT_EX
|
throw DL_ABORT_EX
|
||||||
(StringFormat("Failed to save DHT routing table to %s. cause:%s",
|
(StringFormat("Failed to save DHT routing table to %s.",
|
||||||
dhtFile.c_str(), strerror(errno)).str());
|
dhtFile.c_str()).str());
|
||||||
}
|
}
|
||||||
serializer.serialize(o);
|
serializer.serialize(o);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,6 @@
|
||||||
/* copyright --> */
|
/* copyright --> */
|
||||||
#include "DHTRoutingTableDeserializer.h"
|
#include "DHTRoutingTableDeserializer.h"
|
||||||
|
|
||||||
#include <cerrno>
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <istream>
|
#include <istream>
|
||||||
|
@ -73,9 +72,7 @@ void readBytes(unsigned char* buf, size_t buflen,
|
||||||
"Unexpected EOF").str()); \
|
"Unexpected EOF").str()); \
|
||||||
} \
|
} \
|
||||||
if(!in) { \
|
if(!in) { \
|
||||||
throw DL_ABORT_EX \
|
throw DL_ABORT_EX("Failed to load DHT routing table."); \
|
||||||
(StringFormat("Failed to load DHT routing table. cause:%s", \
|
|
||||||
strerror(errno)).str()); \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DHTRoutingTableDeserializer::deserialize(std::istream& in)
|
void DHTRoutingTableDeserializer::deserialize(std::istream& in)
|
||||||
|
|
|
@ -34,7 +34,6 @@
|
||||||
/* copyright --> */
|
/* copyright --> */
|
||||||
#include "DHTRoutingTableSerializer.h"
|
#include "DHTRoutingTableSerializer.h"
|
||||||
|
|
||||||
#include <cerrno>
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
|
||||||
|
@ -130,9 +129,7 @@ void DHTRoutingTableSerializer::serialize(std::ostream& o)
|
||||||
|
|
||||||
o.flush();
|
o.flush();
|
||||||
if(!o) {
|
if(!o) {
|
||||||
throw DL_ABORT_EX
|
throw DL_ABORT_EX("Failed to save DHT routing table.");
|
||||||
(StringFormat("Failed to save DHT routing table. cause:%s",
|
|
||||||
strerror(errno)).str());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,6 @@
|
||||||
/* copyright --> */
|
/* copyright --> */
|
||||||
#include "DefaultBtProgressInfoFile.h"
|
#include "DefaultBtProgressInfoFile.h"
|
||||||
|
|
||||||
#include <cerrno>
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
|
@ -111,8 +110,8 @@ void DefaultBtProgressInfoFile::save()
|
||||||
{
|
{
|
||||||
std::ofstream o(filenameTemp.c_str(), std::ios::out|std::ios::binary);
|
std::ofstream o(filenameTemp.c_str(), std::ios::out|std::ios::binary);
|
||||||
if(!o) {
|
if(!o) {
|
||||||
throw DL_ABORT_EX(StringFormat(EX_SEGMENT_FILE_WRITE,
|
throw DL_ABORT_EX
|
||||||
filename_.c_str(), strerror(errno)).str());
|
(StringFormat(EX_SEGMENT_FILE_WRITE, filename_.c_str()).str());
|
||||||
}
|
}
|
||||||
#ifdef ENABLE_BITTORRENT
|
#ifdef ENABLE_BITTORRENT
|
||||||
bool torrentDownload = isTorrentDownload();
|
bool torrentDownload = isTorrentDownload();
|
||||||
|
@ -199,25 +198,26 @@ void DefaultBtProgressInfoFile::save()
|
||||||
}
|
}
|
||||||
o.flush();
|
o.flush();
|
||||||
if(!o) {
|
if(!o) {
|
||||||
throw DL_ABORT_EX(StringFormat(EX_SEGMENT_FILE_WRITE,
|
throw DL_ABORT_EX
|
||||||
filename_.c_str(), strerror(errno)).str());
|
(StringFormat(EX_SEGMENT_FILE_WRITE, filename_.c_str()).str());
|
||||||
}
|
}
|
||||||
logger_->info(MSG_SAVED_SEGMENT_FILE);
|
logger_->info(MSG_SAVED_SEGMENT_FILE);
|
||||||
}
|
}
|
||||||
if(!File(filenameTemp).renameTo(filename_)) {
|
if(!File(filenameTemp).renameTo(filename_)) {
|
||||||
throw DL_ABORT_EX(StringFormat(EX_SEGMENT_FILE_WRITE,
|
throw DL_ABORT_EX
|
||||||
filename_.c_str(), strerror(errno)).str());
|
(StringFormat(EX_SEGMENT_FILE_WRITE, filename_.c_str()).str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CHECK_STREAM(in, length) \
|
#define CHECK_STREAM(in, length) \
|
||||||
if(in.gcount() != length) { \
|
if(in.gcount() != length) { \
|
||||||
throw DL_ABORT_EX(StringFormat(EX_SEGMENT_FILE_READ, \
|
throw DL_ABORT_EX(StringFormat("Failed to read segment file %s." \
|
||||||
filename_.c_str(),"Unexpected EOF").str()); \
|
" Unexpected EOF.", \
|
||||||
|
filename_.c_str()).str()); \
|
||||||
} \
|
} \
|
||||||
if(!in) { \
|
if(!in) { \
|
||||||
throw DL_ABORT_EX(StringFormat(EX_SEGMENT_FILE_READ, \
|
throw DL_ABORT_EX \
|
||||||
filename_.c_str(), strerror(errno)).str()); \
|
(StringFormat(EX_SEGMENT_FILE_READ, filename_.c_str()).str()); \
|
||||||
}
|
}
|
||||||
|
|
||||||
// It is assumed that integers are saved as:
|
// It is assumed that integers are saved as:
|
||||||
|
@ -227,9 +227,9 @@ void DefaultBtProgressInfoFile::load()
|
||||||
{
|
{
|
||||||
logger_->info(MSG_LOADING_SEGMENT_FILE, filename_.c_str());
|
logger_->info(MSG_LOADING_SEGMENT_FILE, filename_.c_str());
|
||||||
std::ifstream in(filename_.c_str(), std::ios::in|std::ios::binary);
|
std::ifstream in(filename_.c_str(), std::ios::in|std::ios::binary);
|
||||||
if(!in) { \
|
if(!in) {
|
||||||
throw DL_ABORT_EX(StringFormat(EX_SEGMENT_FILE_READ, \
|
throw DL_ABORT_EX
|
||||||
filename_.c_str(), strerror(errno)).str());
|
(StringFormat(EX_SEGMENT_FILE_READ, filename_.c_str()).str());
|
||||||
}
|
}
|
||||||
unsigned char versionBuf[2];
|
unsigned char versionBuf[2];
|
||||||
in.read(reinterpret_cast<char*>(versionBuf), sizeof(versionBuf));
|
in.read(reinterpret_cast<char*>(versionBuf), sizeof(versionBuf));
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
/* copyright --> */
|
/* copyright --> */
|
||||||
#include "EpollEventPoll.h"
|
#include "EpollEventPoll.h"
|
||||||
|
|
||||||
|
#include <cerrno>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
@ -41,6 +42,7 @@
|
||||||
#include "Command.h"
|
#include "Command.h"
|
||||||
#include "LogFactory.h"
|
#include "LogFactory.h"
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
@ -90,10 +92,11 @@ EpollEventPoll::~EpollEventPoll()
|
||||||
if(epfd_ != -1) {
|
if(epfd_ != -1) {
|
||||||
int r;
|
int r;
|
||||||
while((r = close(epfd_)) == -1 && errno == EINTR);
|
while((r = close(epfd_)) == -1 && errno == EINTR);
|
||||||
|
int errNum = errno;
|
||||||
if(r == -1) {
|
if(r == -1) {
|
||||||
logger_->error("Error occurred while closing epoll file descriptor"
|
logger_->error("Error occurred while closing epoll file descriptor"
|
||||||
" %d: %s",
|
" %d: %s",
|
||||||
epfd_, strerror(errno));
|
epfd_, util::safeStrerror(errNum).c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete [] epEvents_;
|
delete [] epEvents_;
|
||||||
|
@ -165,6 +168,7 @@ bool EpollEventPoll::addEvents(sock_t socket,
|
||||||
std::deque<SharedHandle<KSocketEntry> >::iterator i =
|
std::deque<SharedHandle<KSocketEntry> >::iterator i =
|
||||||
std::lower_bound(socketEntries_.begin(), socketEntries_.end(), socketEntry);
|
std::lower_bound(socketEntries_.begin(), socketEntries_.end(), socketEntry);
|
||||||
int r = 0;
|
int r = 0;
|
||||||
|
int errNum = 0;
|
||||||
if(i != socketEntries_.end() && (*i) == socketEntry) {
|
if(i != socketEntries_.end() && (*i) == socketEntry) {
|
||||||
|
|
||||||
event.addSelf(*i);
|
event.addSelf(*i);
|
||||||
|
@ -178,6 +182,7 @@ bool EpollEventPoll::addEvents(sock_t socket,
|
||||||
|
|
||||||
r = epoll_ctl(epfd_, EPOLL_CTL_ADD, (*i)->getSocket(),
|
r = epoll_ctl(epfd_, EPOLL_CTL_ADD, (*i)->getSocket(),
|
||||||
&epEvent);
|
&epEvent);
|
||||||
|
errNum = errno;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
socketEntries_.insert(i, socketEntry);
|
socketEntries_.insert(i, socketEntry);
|
||||||
|
@ -191,11 +196,12 @@ bool EpollEventPoll::addEvents(sock_t socket,
|
||||||
|
|
||||||
struct epoll_event epEvent = socketEntry->getEvents();
|
struct epoll_event epEvent = socketEntry->getEvents();
|
||||||
r = epoll_ctl(epfd_, EPOLL_CTL_ADD, socketEntry->getSocket(), &epEvent);
|
r = epoll_ctl(epfd_, EPOLL_CTL_ADD, socketEntry->getSocket(), &epEvent);
|
||||||
|
errNum = errno;
|
||||||
}
|
}
|
||||||
if(r == -1) {
|
if(r == -1) {
|
||||||
if(logger_->debug()) {
|
if(logger_->debug()) {
|
||||||
logger_->debug("Failed to add socket event %d:%s",
|
logger_->debug("Failed to add socket event %d:%s",
|
||||||
socket, strerror(errno));
|
socket, util::safeStrerror(errNum).c_str());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
@ -229,27 +235,31 @@ bool EpollEventPoll::deleteEvents(sock_t socket,
|
||||||
event.removeSelf(*i);
|
event.removeSelf(*i);
|
||||||
|
|
||||||
int r = 0;
|
int r = 0;
|
||||||
|
int errNum = 0;
|
||||||
if((*i)->eventEmpty()) {
|
if((*i)->eventEmpty()) {
|
||||||
// In kernel before 2.6.9, epoll_ctl with EPOLL_CTL_DEL requires non-null
|
// In kernel before 2.6.9, epoll_ctl with EPOLL_CTL_DEL requires non-null
|
||||||
// pointer of epoll_event.
|
// pointer of epoll_event.
|
||||||
struct epoll_event ev = {0,{0}};
|
struct epoll_event ev = {0,{0}};
|
||||||
r = epoll_ctl(epfd_, EPOLL_CTL_DEL, (*i)->getSocket(), &ev);
|
r = epoll_ctl(epfd_, EPOLL_CTL_DEL, (*i)->getSocket(), &ev);
|
||||||
|
errNum = r;
|
||||||
socketEntries_.erase(i);
|
socketEntries_.erase(i);
|
||||||
} else {
|
} else {
|
||||||
// If socket is closed, then it seems it is automatically removed from
|
// If socket is closed, then it seems it is automatically removed from
|
||||||
// epoll, so following EPOLL_CTL_MOD may fail.
|
// epoll, so following EPOLL_CTL_MOD may fail.
|
||||||
struct epoll_event epEvent = (*i)->getEvents();
|
struct epoll_event epEvent = (*i)->getEvents();
|
||||||
r = epoll_ctl(epfd_, EPOLL_CTL_MOD, (*i)->getSocket(), &epEvent);
|
r = epoll_ctl(epfd_, EPOLL_CTL_MOD, (*i)->getSocket(), &epEvent);
|
||||||
|
errNum = r;
|
||||||
if(r == -1) {
|
if(r == -1) {
|
||||||
if(logger_->debug()) {
|
if(logger_->debug()) {
|
||||||
logger_->debug("Failed to delete socket event, but may be ignored:%s",
|
logger_->debug("Failed to delete socket event, but may be ignored:%s",
|
||||||
strerror(errno));
|
util::safeStrerror(errNum).c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(r == -1) {
|
if(r == -1) {
|
||||||
if(logger_->debug()) {
|
if(logger_->debug()) {
|
||||||
logger_->debug("Failed to delete socket event:%s", strerror(errno));
|
logger_->debug("Failed to delete socket event:%s",
|
||||||
|
util::safeStrerror(errNum).c_str());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -34,7 +34,6 @@
|
||||||
/* copyright --> */
|
/* copyright --> */
|
||||||
#include "IteratableChunkChecksumValidator.h"
|
#include "IteratableChunkChecksumValidator.h"
|
||||||
|
|
||||||
#include <cerrno>
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
|
@ -161,7 +160,7 @@ std::string IteratableChunkChecksumValidator::digest(off_t offset, size_t length
|
||||||
if(r == 0 || r < static_cast<size_t>(woffset)) {
|
if(r == 0 || r < static_cast<size_t>(woffset)) {
|
||||||
throw DL_ABORT_EX
|
throw DL_ABORT_EX
|
||||||
(StringFormat(EX_FILE_READ, dctx_->getBasePath().c_str(),
|
(StringFormat(EX_FILE_READ, dctx_->getBasePath().c_str(),
|
||||||
strerror(errno)).str());
|
"data is too short").str());
|
||||||
}
|
}
|
||||||
size_t wlength;
|
size_t wlength;
|
||||||
if(max < static_cast<off_t>(curoffset+r)) {
|
if(max < static_cast<off_t>(curoffset+r)) {
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
/* copyright --> */
|
/* copyright --> */
|
||||||
#include "KqueueEventPoll.h"
|
#include "KqueueEventPoll.h"
|
||||||
|
|
||||||
|
#include <cerrno>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
@ -41,6 +42,7 @@
|
||||||
#include "Command.h"
|
#include "Command.h"
|
||||||
#include "LogFactory.h"
|
#include "LogFactory.h"
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
#ifdef KEVENT_UDATA_INTPTR_T
|
#ifdef KEVENT_UDATA_INTPTR_T
|
||||||
# define PTR_TO_UDATA(X) (reinterpret_cast<intptr_t>(X))
|
# define PTR_TO_UDATA(X) (reinterpret_cast<intptr_t>(X))
|
||||||
|
@ -96,10 +98,11 @@ KqueueEventPoll::~KqueueEventPoll()
|
||||||
if(kqfd_ != -1) {
|
if(kqfd_ != -1) {
|
||||||
int r;
|
int r;
|
||||||
while((r = close(kqfd_)) == -1 && errno == EINTR);
|
while((r = close(kqfd_)) == -1 && errno == EINTR);
|
||||||
|
int errNum = errno;
|
||||||
if(r == -1) {
|
if(r == -1) {
|
||||||
logger_->error("Error occurred while closing kqueue file descriptor"
|
logger_->error("Error occurred while closing kqueue file descriptor"
|
||||||
" %d: %s",
|
" %d: %s",
|
||||||
kqfd_, strerror(errno));
|
kqfd_, util::safeStrerror(errNum).c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete [] kqEvents_;
|
delete [] kqEvents_;
|
||||||
|
@ -186,10 +189,11 @@ bool KqueueEventPoll::addEvents
|
||||||
n = socketEntry->getEvents(changelist);
|
n = socketEntry->getEvents(changelist);
|
||||||
}
|
}
|
||||||
r = kevent(kqfd_, changelist, n, changelist, 0, &zeroTimeout);
|
r = kevent(kqfd_, changelist, n, changelist, 0, &zeroTimeout);
|
||||||
|
int errNum = errno;
|
||||||
if(r == -1) {
|
if(r == -1) {
|
||||||
if(logger_->debug()) {
|
if(logger_->debug()) {
|
||||||
logger_->debug("Failed to add socket event %d:%s",
|
logger_->debug("Failed to add socket event %d:%s",
|
||||||
socket, strerror(errno));
|
socket, util::safeStrerror(errNum).c_str());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
@ -225,12 +229,14 @@ bool KqueueEventPoll::deleteEvents(sock_t socket,
|
||||||
struct kevent changelist[2];
|
struct kevent changelist[2];
|
||||||
size_t n = (*i)->getEvents(changelist);
|
size_t n = (*i)->getEvents(changelist);
|
||||||
r = kevent(kqfd_, changelist, n, changelist, 0, &zeroTimeout);
|
r = kevent(kqfd_, changelist, n, changelist, 0, &zeroTimeout);
|
||||||
|
int errNum = errno;
|
||||||
if((*i)->eventEmpty()) {
|
if((*i)->eventEmpty()) {
|
||||||
socketEntries_.erase(i);
|
socketEntries_.erase(i);
|
||||||
}
|
}
|
||||||
if(r == -1) {
|
if(r == -1) {
|
||||||
if(logger_->debug()) {
|
if(logger_->debug()) {
|
||||||
logger_->debug("Failed to delete socket event:%s", strerror(errno));
|
logger_->debug("Failed to delete socket event:%s",
|
||||||
|
util::safeStrerror(errNum).c_str());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -34,7 +34,6 @@
|
||||||
/* copyright --> */
|
/* copyright --> */
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
|
|
||||||
#include <cerrno>
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "DlAbortEx.h"
|
#include "DlAbortEx.h"
|
||||||
|
@ -68,7 +67,7 @@ void Logger::openFile(const std::string& filename)
|
||||||
file_.open(filename.c_str(), std::ios::app|std::ios::binary);
|
file_.open(filename.c_str(), std::ios::app|std::ios::binary);
|
||||||
if(!file_) {
|
if(!file_) {
|
||||||
throw DL_ABORT_EX
|
throw DL_ABORT_EX
|
||||||
(StringFormat(EX_FILE_OPEN, filename.c_str(), strerror(errno)).str());
|
(StringFormat(EX_FILE_OPEN, filename.c_str(), "n/a").str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,15 +33,16 @@
|
||||||
*/
|
*/
|
||||||
/* copyright --> */
|
/* copyright --> */
|
||||||
#include "MessageDigestHelper.h"
|
#include "MessageDigestHelper.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
#include "messageDigest.h"
|
#include "messageDigest.h"
|
||||||
#include "DlAbortEx.h"
|
#include "DlAbortEx.h"
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
#include "DefaultDiskWriter.h"
|
#include "DefaultDiskWriter.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "StringFormat.h"
|
#include "StringFormat.h"
|
||||||
#include <cerrno>
|
|
||||||
#include <cstring>
|
|
||||||
#include <cstdlib>
|
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
@ -92,7 +93,7 @@ std::string MessageDigestHelper::digest(MessageDigestContext* ctx,
|
||||||
ssize_t readLength = bs->readData(BUF, BUFSIZE, offset);
|
ssize_t readLength = bs->readData(BUF, BUFSIZE, offset);
|
||||||
if((size_t)readLength != BUFSIZE) {
|
if((size_t)readLength != BUFSIZE) {
|
||||||
throw DL_ABORT_EX
|
throw DL_ABORT_EX
|
||||||
(StringFormat(EX_FILE_READ, "n/a", strerror(errno)).str());
|
(StringFormat(EX_FILE_READ, "n/a", "data is too short").str());
|
||||||
}
|
}
|
||||||
ctx->digestUpdate(BUF, readLength);
|
ctx->digestUpdate(BUF, readLength);
|
||||||
offset += readLength;
|
offset += readLength;
|
||||||
|
@ -101,7 +102,7 @@ std::string MessageDigestHelper::digest(MessageDigestContext* ctx,
|
||||||
ssize_t readLength = bs->readData(BUF, tail, offset);
|
ssize_t readLength = bs->readData(BUF, tail, offset);
|
||||||
if((size_t)readLength != tail) {
|
if((size_t)readLength != tail) {
|
||||||
throw DL_ABORT_EX
|
throw DL_ABORT_EX
|
||||||
(StringFormat(EX_FILE_READ, "n/a", strerror(errno)).str());
|
(StringFormat(EX_FILE_READ, "n/a", "data is too short").str());
|
||||||
}
|
}
|
||||||
ctx->digestUpdate(BUF, readLength);
|
ctx->digestUpdate(BUF, readLength);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
/* copyright --> */
|
/* copyright --> */
|
||||||
#include "PortEventPoll.h"
|
#include "PortEventPoll.h"
|
||||||
|
|
||||||
|
#include <cerrno>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
@ -41,6 +42,7 @@
|
||||||
#include "Command.h"
|
#include "Command.h"
|
||||||
#include "LogFactory.h"
|
#include "LogFactory.h"
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
@ -85,9 +87,10 @@ PortEventPoll::~PortEventPoll()
|
||||||
if(port_ != -1) {
|
if(port_ != -1) {
|
||||||
int r;
|
int r;
|
||||||
while((r = close(port_)) == -1 && errno == EINTR);
|
while((r = close(port_)) == -1 && errno == EINTR);
|
||||||
|
int errNum = errno;
|
||||||
if(r == -1) {
|
if(r == -1) {
|
||||||
logger_->error("Error occurred while closing port %d: %s",
|
logger_->error("Error occurred while closing port %d: %s",
|
||||||
port_, strerror(errno));
|
port_, util::safeStrerror(errNum).c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete [] portEvents_;
|
delete [] portEvents_;
|
||||||
|
@ -120,9 +123,10 @@ void PortEventPoll::poll(const struct timeval& tv)
|
||||||
p->processEvents(pev.portev_events);
|
p->processEvents(pev.portev_events);
|
||||||
int r = port_associate(port_, PORT_SOURCE_FD, pev.portev_object,
|
int r = port_associate(port_, PORT_SOURCE_FD, pev.portev_object,
|
||||||
p->getEvents().events, p);
|
p->getEvents().events, p);
|
||||||
|
int errNum = errno;
|
||||||
if(r == -1) {
|
if(r == -1) {
|
||||||
logger_->error("port_associate failed for file descriptor %d: cause %s",
|
logger_->error("port_associate failed for file descriptor %d: cause %s",
|
||||||
pev.portev_object, strerror(errno));
|
pev.portev_object, util::safeStrerror(errNum).c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -171,11 +175,13 @@ bool PortEventPoll::addEvents(sock_t socket,
|
||||||
std::deque<SharedHandle<KSocketEntry> >::iterator i =
|
std::deque<SharedHandle<KSocketEntry> >::iterator i =
|
||||||
std::lower_bound(socketEntries_.begin(), socketEntries_.end(), socketEntry);
|
std::lower_bound(socketEntries_.begin(), socketEntries_.end(), socketEntry);
|
||||||
int r = 0;
|
int r = 0;
|
||||||
|
int errNum = 0;
|
||||||
if(i != socketEntries_.end() && (*i) == socketEntry) {
|
if(i != socketEntries_.end() && (*i) == socketEntry) {
|
||||||
event.addSelf(*i);
|
event.addSelf(*i);
|
||||||
A2PortEvent pv = (*i)->getEvents();
|
A2PortEvent pv = (*i)->getEvents();
|
||||||
r = port_associate(port_, PORT_SOURCE_FD, (*i)->getSocket(),
|
r = port_associate(port_, PORT_SOURCE_FD, (*i)->getSocket(),
|
||||||
pv.events, pv.socketEntry);
|
pv.events, pv.socketEntry);
|
||||||
|
errNum = r;
|
||||||
} else {
|
} else {
|
||||||
socketEntries_.insert(i, socketEntry);
|
socketEntries_.insert(i, socketEntry);
|
||||||
if(socketEntries_.size() > portEventsSize_) {
|
if(socketEntries_.size() > portEventsSize_) {
|
||||||
|
@ -187,11 +193,12 @@ bool PortEventPoll::addEvents(sock_t socket,
|
||||||
A2PortEvent pv = socketEntry->getEvents();
|
A2PortEvent pv = socketEntry->getEvents();
|
||||||
r = port_associate(port_, PORT_SOURCE_FD, socketEntry->getSocket(),
|
r = port_associate(port_, PORT_SOURCE_FD, socketEntry->getSocket(),
|
||||||
pv.events, pv.socketEntry);
|
pv.events, pv.socketEntry);
|
||||||
|
errNum = r;
|
||||||
}
|
}
|
||||||
if(r == -1) {
|
if(r == -1) {
|
||||||
if(logger_->debug()) {
|
if(logger_->debug()) {
|
||||||
logger_->debug("Failed to add socket event %d:%s",
|
logger_->debug("Failed to add socket event %d:%s",
|
||||||
socket, strerror(errno));
|
socket, util::safeStrerror(errNum).c_str());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
@ -223,17 +230,21 @@ bool PortEventPoll::deleteEvents(sock_t socket,
|
||||||
if(i != socketEntries_.end() && (*i) == socketEntry) {
|
if(i != socketEntries_.end() && (*i) == socketEntry) {
|
||||||
event.removeSelf(*i);
|
event.removeSelf(*i);
|
||||||
int r = 0;
|
int r = 0;
|
||||||
|
int errNum = 0;
|
||||||
if((*i)->eventEmpty()) {
|
if((*i)->eventEmpty()) {
|
||||||
r = port_dissociate(port_, PORT_SOURCE_FD, (*i)->getSocket());
|
r = port_dissociate(port_, PORT_SOURCE_FD, (*i)->getSocket());
|
||||||
|
errNum = errno;
|
||||||
socketEntries_.erase(i);
|
socketEntries_.erase(i);
|
||||||
} else {
|
} else {
|
||||||
A2PortEvent pv = (*i)->getEvents();
|
A2PortEvent pv = (*i)->getEvents();
|
||||||
r = port_associate(port_, PORT_SOURCE_FD, (*i)->getSocket(),
|
r = port_associate(port_, PORT_SOURCE_FD, (*i)->getSocket(),
|
||||||
pv.events, pv.socketEntry);
|
pv.events, pv.socketEntry);
|
||||||
|
errNum = errno;
|
||||||
}
|
}
|
||||||
if(r == -1) {
|
if(r == -1) {
|
||||||
if(logger_->debug()) {
|
if(logger_->debug()) {
|
||||||
logger_->debug("Failed to delete socket event:%s", strerror(errno));
|
logger_->debug("Failed to delete socket event:%s",
|
||||||
|
util::safeStrerror(errNum).c_str());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -40,7 +40,6 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include "Command.h"
|
#include "Command.h"
|
||||||
#include "LogFactory.h"
|
#include "LogFactory.h"
|
||||||
|
@ -280,7 +279,6 @@ bool SelectEventPoll::addEvents(sock_t socket, Command* command,
|
||||||
SharedHandle<SocketEntry> socketEntry(new SocketEntry(socket));
|
SharedHandle<SocketEntry> socketEntry(new SocketEntry(socket));
|
||||||
std::deque<SharedHandle<SocketEntry> >::iterator i =
|
std::deque<SharedHandle<SocketEntry> >::iterator i =
|
||||||
std::lower_bound(socketEntries_.begin(), socketEntries_.end(), socketEntry);
|
std::lower_bound(socketEntries_.begin(), socketEntries_.end(), socketEntry);
|
||||||
int r = 0;
|
|
||||||
if(i != socketEntries_.end() && (*i) == socketEntry) {
|
if(i != socketEntries_.end() && (*i) == socketEntry) {
|
||||||
(*i)->addCommandEvent(command, events);
|
(*i)->addCommandEvent(command, events);
|
||||||
} else {
|
} else {
|
||||||
|
@ -288,15 +286,7 @@ bool SelectEventPoll::addEvents(sock_t socket, Command* command,
|
||||||
socketEntry->addCommandEvent(command, events);
|
socketEntry->addCommandEvent(command, events);
|
||||||
}
|
}
|
||||||
updateFdSet();
|
updateFdSet();
|
||||||
if(r == -1) {
|
|
||||||
if(logger_->debug()) {
|
|
||||||
logger_->debug("Failed to add socket event %d:%s",
|
|
||||||
socket, strerror(errno));
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SelectEventPoll::deleteEvents(sock_t socket, Command* command,
|
bool SelectEventPoll::deleteEvents(sock_t socket, Command* command,
|
||||||
|
@ -307,19 +297,11 @@ bool SelectEventPoll::deleteEvents(sock_t socket, Command* command,
|
||||||
std::lower_bound(socketEntries_.begin(), socketEntries_.end(), socketEntry);
|
std::lower_bound(socketEntries_.begin(), socketEntries_.end(), socketEntry);
|
||||||
if(i != socketEntries_.end() && (*i) == socketEntry) {
|
if(i != socketEntries_.end() && (*i) == socketEntry) {
|
||||||
(*i)->removeCommandEvent(command, events);
|
(*i)->removeCommandEvent(command, events);
|
||||||
int r = 0;
|
|
||||||
if((*i)->eventEmpty()) {
|
if((*i)->eventEmpty()) {
|
||||||
socketEntries_.erase(i);
|
socketEntries_.erase(i);
|
||||||
}
|
}
|
||||||
updateFdSet();
|
updateFdSet();
|
||||||
if(r == -1) {
|
|
||||||
if(logger_->debug()) {
|
|
||||||
logger_->debug("Failed to delete socket event:%s", strerror(errno));
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if(logger_->debug()) {
|
if(logger_->debug()) {
|
||||||
logger_->debug("Socket %d is not found in SocketEntries.", socket);
|
logger_->debug("Socket %d is not found in SocketEntries.", socket);
|
||||||
|
|
|
@ -92,32 +92,29 @@ namespace aria2 {
|
||||||
# define CLOSE(X) while(close(X) == -1 && errno == EINTR)
|
# define CLOSE(X) while(close(X) == -1 && errno == EINTR)
|
||||||
#endif // __MINGW32__
|
#endif // __MINGW32__
|
||||||
|
|
||||||
static const char *errorMsg(const int err)
|
namespace {
|
||||||
|
std::string errorMsg(int errNum)
|
||||||
{
|
{
|
||||||
#ifndef __MINGW32__
|
#ifndef __MINGW32__
|
||||||
return strerror(err);
|
return util::safeStrerror(errNum);
|
||||||
#else
|
#else
|
||||||
static char buf[256];
|
static char buf[256];
|
||||||
if (FormatMessage(
|
if (FormatMessage(
|
||||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
NULL,
|
NULL,
|
||||||
err,
|
errNum,
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
||||||
(LPTSTR) &buf,
|
(LPTSTR) &buf,
|
||||||
sizeof(buf),
|
sizeof(buf),
|
||||||
NULL
|
NULL
|
||||||
) == 0) {
|
) == 0) {
|
||||||
snprintf(buf, sizeof(buf), EX_SOCKET_UNKNOWN_ERROR, err, err);
|
snprintf(buf, sizeof(buf), EX_SOCKET_UNKNOWN_ERROR, errNum, errNum);
|
||||||
}
|
}
|
||||||
return buf;
|
return buf;
|
||||||
#endif // __MINGW32__
|
#endif // __MINGW32__
|
||||||
}
|
}
|
||||||
|
} // namespace
|
||||||
static const char *errorMsg()
|
|
||||||
{
|
|
||||||
return errorMsg(SOCKET_ERRNO);
|
|
||||||
}
|
|
||||||
|
|
||||||
int SocketCore::protocolFamily_ = AF_UNSPEC;
|
int SocketCore::protocolFamily_ = AF_UNSPEC;
|
||||||
|
|
||||||
|
@ -170,18 +167,23 @@ SocketCore::~SocketCore() {
|
||||||
|
|
||||||
void SocketCore::create(int family, int protocol)
|
void SocketCore::create(int family, int protocol)
|
||||||
{
|
{
|
||||||
|
int errNum;
|
||||||
closeConnection();
|
closeConnection();
|
||||||
sock_t fd = socket(family, sockType_, protocol);
|
sock_t fd = socket(family, sockType_, protocol);
|
||||||
|
errNum = SOCKET_ERRNO;
|
||||||
if(fd == (sock_t) -1) {
|
if(fd == (sock_t) -1) {
|
||||||
throw DL_ABORT_EX
|
throw DL_ABORT_EX
|
||||||
(StringFormat("Failed to create socket. Cause:%s", errorMsg()).str());
|
(StringFormat
|
||||||
|
("Failed to create socket. Cause:%s", errorMsg(errNum).c_str()).str());
|
||||||
}
|
}
|
||||||
int sockopt = 1;
|
int sockopt = 1;
|
||||||
if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
|
if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
|
||||||
(a2_sockopt_t) &sockopt, sizeof(sockopt)) < 0) {
|
(a2_sockopt_t) &sockopt, sizeof(sockopt)) < 0) {
|
||||||
|
errNum = SOCKET_ERRNO;
|
||||||
CLOSE(fd);
|
CLOSE(fd);
|
||||||
throw DL_ABORT_EX
|
throw DL_ABORT_EX
|
||||||
(StringFormat("Failed to create socket. Cause:%s", errorMsg()).str());
|
(StringFormat
|
||||||
|
("Failed to create socket. Cause:%s", errorMsg(errNum).c_str()).str());
|
||||||
}
|
}
|
||||||
sockfd_ = fd;
|
sockfd_ = fd;
|
||||||
}
|
}
|
||||||
|
@ -190,13 +192,18 @@ static sock_t bindInternal(int family, int socktype, int protocol,
|
||||||
const struct sockaddr* addr, socklen_t addrlen,
|
const struct sockaddr* addr, socklen_t addrlen,
|
||||||
std::string& error)
|
std::string& error)
|
||||||
{
|
{
|
||||||
|
int errNum;
|
||||||
sock_t fd = socket(family, socktype, protocol);
|
sock_t fd = socket(family, socktype, protocol);
|
||||||
|
errNum = SOCKET_ERRNO;
|
||||||
if(fd == (sock_t) -1) {
|
if(fd == (sock_t) -1) {
|
||||||
|
error = errorMsg(errNum);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int sockopt = 1;
|
int sockopt = 1;
|
||||||
if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (a2_sockopt_t) &sockopt,
|
if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (a2_sockopt_t) &sockopt,
|
||||||
sizeof(sockopt)) < 0) {
|
sizeof(sockopt)) < 0) {
|
||||||
|
errNum = SOCKET_ERRNO;
|
||||||
|
error = errorMsg(errNum);
|
||||||
CLOSE(fd);
|
CLOSE(fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -205,13 +212,16 @@ static sock_t bindInternal(int family, int socktype, int protocol,
|
||||||
int sockopt = 1;
|
int sockopt = 1;
|
||||||
if(setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (a2_sockopt_t) &sockopt,
|
if(setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (a2_sockopt_t) &sockopt,
|
||||||
sizeof(sockopt)) < 0) {
|
sizeof(sockopt)) < 0) {
|
||||||
|
errNum = SOCKET_ERRNO;
|
||||||
|
error = errorMsg(errNum);
|
||||||
CLOSE(fd);
|
CLOSE(fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // IPV6_V6ONLY
|
#endif // IPV6_V6ONLY
|
||||||
if(::bind(fd, addr, addrlen) == -1) {
|
if(::bind(fd, addr, addrlen) == -1) {
|
||||||
error = errorMsg();
|
errNum = SOCKET_ERRNO;
|
||||||
|
error = errorMsg(errNum);
|
||||||
CLOSE(fd);
|
CLOSE(fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -319,7 +329,9 @@ void SocketCore::bind(const struct sockaddr* addr, socklen_t addrlen)
|
||||||
void SocketCore::beginListen()
|
void SocketCore::beginListen()
|
||||||
{
|
{
|
||||||
if(listen(sockfd_, 1) == -1) {
|
if(listen(sockfd_, 1) == -1) {
|
||||||
throw DL_ABORT_EX(StringFormat(EX_SOCKET_LISTEN, errorMsg()).str());
|
int errNum = SOCKET_ERRNO;
|
||||||
|
throw DL_ABORT_EX(StringFormat
|
||||||
|
(EX_SOCKET_LISTEN, errorMsg(errNum).c_str()).str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,9 +340,13 @@ SocketCore* SocketCore::acceptConnection() const
|
||||||
struct sockaddr_storage sockaddr;
|
struct sockaddr_storage sockaddr;
|
||||||
socklen_t len = sizeof(sockaddr);
|
socklen_t len = sizeof(sockaddr);
|
||||||
sock_t fd;
|
sock_t fd;
|
||||||
while((fd = accept(sockfd_, reinterpret_cast<struct sockaddr*>(&sockaddr), &len)) == (sock_t) -1 && SOCKET_ERRNO == A2_EINTR);
|
while((fd = accept(sockfd_, reinterpret_cast<struct sockaddr*>(&sockaddr),
|
||||||
|
&len)) == (sock_t) -1 &&
|
||||||
|
SOCKET_ERRNO == A2_EINTR);
|
||||||
|
int errNum = SOCKET_ERRNO;
|
||||||
if(fd == (sock_t) -1) {
|
if(fd == (sock_t) -1) {
|
||||||
throw DL_ABORT_EX(StringFormat(EX_SOCKET_ACCEPT, errorMsg()).str());
|
throw DL_ABORT_EX(StringFormat
|
||||||
|
(EX_SOCKET_ACCEPT, errorMsg(errNum).c_str()).str());
|
||||||
}
|
}
|
||||||
return new SocketCore(fd, sockType_);
|
return new SocketCore(fd, sockType_);
|
||||||
}
|
}
|
||||||
|
@ -349,7 +365,9 @@ void SocketCore::getAddrInfo
|
||||||
{
|
{
|
||||||
struct sockaddr* addrp = reinterpret_cast<struct sockaddr*>(&sockaddr);
|
struct sockaddr* addrp = reinterpret_cast<struct sockaddr*>(&sockaddr);
|
||||||
if(getsockname(sockfd_, addrp, &len) == -1) {
|
if(getsockname(sockfd_, addrp, &len) == -1) {
|
||||||
throw DL_ABORT_EX(StringFormat(EX_SOCKET_GET_NAME, errorMsg()).str());
|
int errNum = SOCKET_ERRNO;
|
||||||
|
throw DL_ABORT_EX(StringFormat
|
||||||
|
(EX_SOCKET_GET_NAME, errorMsg(errNum).c_str()).str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -367,7 +385,9 @@ void SocketCore::getPeerInfo(std::pair<std::string, uint16_t>& peerinfo) const
|
||||||
socklen_t len = sizeof(sockaddr);
|
socklen_t len = sizeof(sockaddr);
|
||||||
struct sockaddr* addrp = reinterpret_cast<struct sockaddr*>(&sockaddr);
|
struct sockaddr* addrp = reinterpret_cast<struct sockaddr*>(&sockaddr);
|
||||||
if(getpeername(sockfd_, addrp, &len) == -1) {
|
if(getpeername(sockfd_, addrp, &len) == -1) {
|
||||||
throw DL_ABORT_EX(StringFormat(EX_SOCKET_GET_NAME, errorMsg()).str());
|
int errNum = SOCKET_ERRNO;
|
||||||
|
throw DL_ABORT_EX(StringFormat
|
||||||
|
(EX_SOCKET_GET_NAME, errorMsg(errNum).c_str()).str());
|
||||||
}
|
}
|
||||||
peerinfo = util::getNumericNameInfo(addrp, len);
|
peerinfo = util::getNumericNameInfo(addrp, len);
|
||||||
}
|
}
|
||||||
|
@ -386,15 +406,19 @@ void SocketCore::establishConnection(const std::string& host, uint16_t port)
|
||||||
}
|
}
|
||||||
WSAAPI_AUTO_DELETE<struct addrinfo*> resDeleter(res, freeaddrinfo);
|
WSAAPI_AUTO_DELETE<struct addrinfo*> resDeleter(res, freeaddrinfo);
|
||||||
struct addrinfo* rp;
|
struct addrinfo* rp;
|
||||||
|
int errNum;
|
||||||
for(rp = res; rp; rp = rp->ai_next) {
|
for(rp = res; rp; rp = rp->ai_next) {
|
||||||
sock_t fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
|
sock_t fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
|
||||||
|
errNum = SOCKET_ERRNO;
|
||||||
if(fd == (sock_t) -1) {
|
if(fd == (sock_t) -1) {
|
||||||
error = errorMsg();
|
error = errorMsg(errNum);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int sockopt = 1;
|
int sockopt = 1;
|
||||||
if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (a2_sockopt_t) &sockopt, sizeof(sockopt)) < 0) {
|
if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (a2_sockopt_t) &sockopt,
|
||||||
error = errorMsg();
|
sizeof(sockopt)) < 0) {
|
||||||
|
errNum = SOCKET_ERRNO;
|
||||||
|
error = errorMsg(errNum);
|
||||||
CLOSE(fd);
|
CLOSE(fd);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -405,7 +429,8 @@ void SocketCore::establishConnection(const std::string& host, uint16_t port)
|
||||||
i != eoi; ++i) {
|
i != eoi; ++i) {
|
||||||
if(::bind(fd,reinterpret_cast<const struct sockaddr*>(&(*i).first),
|
if(::bind(fd,reinterpret_cast<const struct sockaddr*>(&(*i).first),
|
||||||
(*i).second) == -1) {
|
(*i).second) == -1) {
|
||||||
error = errorMsg();
|
errNum = SOCKET_ERRNO;
|
||||||
|
error = errorMsg(errNum);
|
||||||
if(LogFactory::getInstance()->debug()) {
|
if(LogFactory::getInstance()->debug()) {
|
||||||
LogFactory::getInstance()->debug(EX_SOCKET_BIND, error.c_str());
|
LogFactory::getInstance()->debug(EX_SOCKET_BIND, error.c_str());
|
||||||
}
|
}
|
||||||
|
@ -425,7 +450,8 @@ void SocketCore::establishConnection(const std::string& host, uint16_t port)
|
||||||
setNonBlockingMode();
|
setNonBlockingMode();
|
||||||
if(connect(fd, rp->ai_addr, rp->ai_addrlen) == -1 &&
|
if(connect(fd, rp->ai_addr, rp->ai_addrlen) == -1 &&
|
||||||
SOCKET_ERRNO != A2_EINPROGRESS) {
|
SOCKET_ERRNO != A2_EINPROGRESS) {
|
||||||
error = errorMsg();
|
errNum = SOCKET_ERRNO;
|
||||||
|
error = errorMsg(errNum);
|
||||||
CLOSE(sockfd_);
|
CLOSE(sockfd_);
|
||||||
sockfd_ = (sock_t) -1;
|
sockfd_ = (sock_t) -1;
|
||||||
continue;
|
continue;
|
||||||
|
@ -444,7 +470,9 @@ void SocketCore::setSockOpt
|
||||||
(int level, int optname, void* optval, socklen_t optlen)
|
(int level, int optname, void* optval, socklen_t optlen)
|
||||||
{
|
{
|
||||||
if(setsockopt(sockfd_, level, optname, (a2_sockopt_t)optval, optlen) < 0) {
|
if(setsockopt(sockfd_, level, optname, (a2_sockopt_t)optval, optlen) < 0) {
|
||||||
throw DL_ABORT_EX(StringFormat(EX_SOCKET_SET_OPT, errorMsg()).str());
|
int errNum = SOCKET_ERRNO;
|
||||||
|
throw DL_ABORT_EX(StringFormat
|
||||||
|
(EX_SOCKET_SET_OPT, errorMsg(errNum).c_str()).str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -502,7 +530,9 @@ void SocketCore::setNonBlockingMode()
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
static u_long flag = 1;
|
static u_long flag = 1;
|
||||||
if (::ioctlsocket(sockfd_, FIONBIO, &flag) == -1) {
|
if (::ioctlsocket(sockfd_, FIONBIO, &flag) == -1) {
|
||||||
throw DL_ABORT_EX(StringFormat(EX_SOCKET_NONBLOCKING, errorMsg()).str());
|
int errNum = SOCKET_ERRNO;
|
||||||
|
throw DL_ABORT_EX(StringFormat
|
||||||
|
(EX_SOCKET_NONBLOCKING, errorMsg(errNum).c_str()).str());
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
int flags;
|
int flags;
|
||||||
|
@ -518,7 +548,9 @@ void SocketCore::setBlockingMode()
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
static u_long flag = 0;
|
static u_long flag = 0;
|
||||||
if (::ioctlsocket(sockfd_, FIONBIO, &flag) == -1) {
|
if (::ioctlsocket(sockfd_, FIONBIO, &flag) == -1) {
|
||||||
throw DL_ABORT_EX(StringFormat(EX_SOCKET_BLOCKING, errorMsg()).str());
|
int errNum = SOCKET_ERRNO;
|
||||||
|
throw DL_ABORT_EX(StringFormat
|
||||||
|
(EX_SOCKET_BLOCKING, errorMsg(errNum).c_str()).str());
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
int flags;
|
int flags;
|
||||||
|
@ -576,13 +608,14 @@ bool SocketCore::isWritable(time_t timeout)
|
||||||
p.events = POLLOUT;
|
p.events = POLLOUT;
|
||||||
int r;
|
int r;
|
||||||
while((r = poll(&p, 1, timeout*1000)) == -1 && errno == EINTR);
|
while((r = poll(&p, 1, timeout*1000)) == -1 && errno == EINTR);
|
||||||
|
int errNum = SOCKET_ERRNO;
|
||||||
if(r > 0) {
|
if(r > 0) {
|
||||||
return p.revents&(POLLOUT|POLLHUP|POLLERR);
|
return p.revents&(POLLOUT|POLLHUP|POLLERR);
|
||||||
} else if(r == 0) {
|
} else if(r == 0) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
throw DL_RETRY_EX
|
throw DL_RETRY_EX
|
||||||
(StringFormat(EX_SOCKET_CHECK_WRITABLE, errorMsg()).str());
|
(StringFormat(EX_SOCKET_CHECK_WRITABLE, errorMsg(errNum).c_str()).str());
|
||||||
}
|
}
|
||||||
#else // !HAVE_POLL
|
#else // !HAVE_POLL
|
||||||
# ifndef __MINGW32__
|
# ifndef __MINGW32__
|
||||||
|
@ -597,17 +630,19 @@ bool SocketCore::isWritable(time_t timeout)
|
||||||
tv.tv_usec = 0;
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
int r = select(sockfd_+1, NULL, &fds, NULL, &tv);
|
int r = select(sockfd_+1, NULL, &fds, NULL, &tv);
|
||||||
|
int errNum = SOCKET_ERRNO;
|
||||||
if(r == 1) {
|
if(r == 1) {
|
||||||
return true;
|
return true;
|
||||||
} else if(r == 0) {
|
} else if(r == 0) {
|
||||||
// time out
|
// time out
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
if(SOCKET_ERRNO == A2_EINPROGRESS || SOCKET_ERRNO == A2_EINTR) {
|
if(errNum == A2_EINPROGRESS || errNum == A2_EINTR) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
throw DL_RETRY_EX
|
throw DL_RETRY_EX
|
||||||
(StringFormat(EX_SOCKET_CHECK_WRITABLE, errorMsg()).str());
|
(StringFormat(EX_SOCKET_CHECK_WRITABLE,
|
||||||
|
errorMsg(errNum).c_str()).str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // !HAVE_POLL
|
#endif // !HAVE_POLL
|
||||||
|
@ -626,13 +661,14 @@ bool SocketCore::isReadable(time_t timeout)
|
||||||
p.events = POLLIN;
|
p.events = POLLIN;
|
||||||
int r;
|
int r;
|
||||||
while((r = poll(&p, 1, timeout*1000)) == -1 && errno == EINTR);
|
while((r = poll(&p, 1, timeout*1000)) == -1 && errno == EINTR);
|
||||||
|
int errNum = SOCKET_ERRNO;
|
||||||
if(r > 0) {
|
if(r > 0) {
|
||||||
return p.revents&(POLLIN|POLLHUP|POLLERR);
|
return p.revents&(POLLIN|POLLHUP|POLLERR);
|
||||||
} else if(r == 0) {
|
} else if(r == 0) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
throw DL_RETRY_EX
|
throw DL_RETRY_EX
|
||||||
(StringFormat(EX_SOCKET_CHECK_READABLE, errorMsg()).str());
|
(StringFormat(EX_SOCKET_CHECK_READABLE, errorMsg(errNum).c_str()).str());
|
||||||
}
|
}
|
||||||
#else // !HAVE_POLL
|
#else // !HAVE_POLL
|
||||||
# ifndef __MINGW32__
|
# ifndef __MINGW32__
|
||||||
|
@ -647,17 +683,19 @@ bool SocketCore::isReadable(time_t timeout)
|
||||||
tv.tv_usec = 0;
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
int r = select(sockfd_+1, &fds, NULL, NULL, &tv);
|
int r = select(sockfd_+1, &fds, NULL, NULL, &tv);
|
||||||
|
int errNum = SOCKET_ERRNO;
|
||||||
if(r == 1) {
|
if(r == 1) {
|
||||||
return true;
|
return true;
|
||||||
} else if(r == 0) {
|
} else if(r == 0) {
|
||||||
// time out
|
// time out
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
if(SOCKET_ERRNO == A2_EINPROGRESS || SOCKET_ERRNO == A2_EINTR) {
|
if(errNum == A2_EINPROGRESS || errNum == A2_EINTR) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
throw DL_RETRY_EX
|
throw DL_RETRY_EX
|
||||||
(StringFormat(EX_SOCKET_CHECK_READABLE, errorMsg()).str());
|
(StringFormat(EX_SOCKET_CHECK_READABLE,
|
||||||
|
errorMsg(errNum).c_str()).str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // !HAVE_POLL
|
#endif // !HAVE_POLL
|
||||||
|
@ -699,12 +737,14 @@ ssize_t SocketCore::writeData(const char* data, size_t len)
|
||||||
|
|
||||||
if(!secure_) {
|
if(!secure_) {
|
||||||
while((ret = send(sockfd_, data, len, 0)) == -1 && SOCKET_ERRNO == A2_EINTR);
|
while((ret = send(sockfd_, data, len, 0)) == -1 && SOCKET_ERRNO == A2_EINTR);
|
||||||
|
int errNum = SOCKET_ERRNO;
|
||||||
if(ret == -1) {
|
if(ret == -1) {
|
||||||
if(A2_WOULDBLOCK(SOCKET_ERRNO)) {
|
if(A2_WOULDBLOCK(errNum)) {
|
||||||
wantWrite_ = true;
|
wantWrite_ = true;
|
||||||
ret = 0;
|
ret = 0;
|
||||||
} else {
|
} else {
|
||||||
throw DL_RETRY_EX(StringFormat(EX_SOCKET_SEND, errorMsg()).str());
|
throw DL_RETRY_EX(StringFormat(EX_SOCKET_SEND,
|
||||||
|
errorMsg(errNum).c_str()).str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -743,12 +783,14 @@ void SocketCore::readData(char* data, size_t& len)
|
||||||
if(!secure_) {
|
if(!secure_) {
|
||||||
while((ret = recv(sockfd_, data, len, 0)) == -1 && SOCKET_ERRNO == A2_EINTR);
|
while((ret = recv(sockfd_, data, len, 0)) == -1 && SOCKET_ERRNO == A2_EINTR);
|
||||||
|
|
||||||
|
int errNum = SOCKET_ERRNO;
|
||||||
if(ret == -1) {
|
if(ret == -1) {
|
||||||
if(A2_WOULDBLOCK(SOCKET_ERRNO)) {
|
if(A2_WOULDBLOCK(errNum)) {
|
||||||
wantRead_ = true;
|
wantRead_ = true;
|
||||||
ret = 0;
|
ret = 0;
|
||||||
} else {
|
} else {
|
||||||
throw DL_RETRY_EX(StringFormat(EX_SOCKET_RECV, errorMsg()).str());
|
throw DL_RETRY_EX(StringFormat(EX_SOCKET_RECV,
|
||||||
|
errorMsg(errNum).c_str()).str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -789,12 +831,14 @@ void SocketCore::peekData(char* data, size_t& len)
|
||||||
if(!secure_) {
|
if(!secure_) {
|
||||||
while((ret = recv(sockfd_, data, len, MSG_PEEK)) == -1 &&
|
while((ret = recv(sockfd_, data, len, MSG_PEEK)) == -1 &&
|
||||||
SOCKET_ERRNO == A2_EINTR);
|
SOCKET_ERRNO == A2_EINTR);
|
||||||
|
int errNum = SOCKET_ERRNO;
|
||||||
if(ret == -1) {
|
if(ret == -1) {
|
||||||
if(A2_WOULDBLOCK(SOCKET_ERRNO)) {
|
if(A2_WOULDBLOCK(errNum)) {
|
||||||
wantRead_ = true;
|
wantRead_ = true;
|
||||||
ret = 0;
|
ret = 0;
|
||||||
} else {
|
} else {
|
||||||
throw DL_RETRY_EX(StringFormat(EX_SOCKET_PEEK, errorMsg()).str());
|
throw DL_RETRY_EX(StringFormat(EX_SOCKET_PEEK,
|
||||||
|
errorMsg(errNum).c_str()).str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1133,20 +1177,23 @@ ssize_t SocketCore::writeData(const char* data, size_t len,
|
||||||
WSAAPI_AUTO_DELETE<struct addrinfo*> resDeleter(res, freeaddrinfo);
|
WSAAPI_AUTO_DELETE<struct addrinfo*> resDeleter(res, freeaddrinfo);
|
||||||
struct addrinfo* rp;
|
struct addrinfo* rp;
|
||||||
ssize_t r = -1;
|
ssize_t r = -1;
|
||||||
|
int errNum = 0;
|
||||||
for(rp = res; rp; rp = rp->ai_next) {
|
for(rp = res; rp; rp = rp->ai_next) {
|
||||||
while((r = sendto(sockfd_, data, len, 0, rp->ai_addr, rp->ai_addrlen)) == -1
|
while((r = sendto(sockfd_, data, len, 0, rp->ai_addr, rp->ai_addrlen)) == -1
|
||||||
&& A2_EINTR == SOCKET_ERRNO);
|
&& A2_EINTR == SOCKET_ERRNO);
|
||||||
|
errNum = SOCKET_ERRNO;
|
||||||
if(r == static_cast<ssize_t>(len)) {
|
if(r == static_cast<ssize_t>(len)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(r == -1 && A2_WOULDBLOCK(SOCKET_ERRNO)) {
|
if(r == -1 && A2_WOULDBLOCK(errNum)) {
|
||||||
wantWrite_ = true;
|
wantWrite_ = true;
|
||||||
r = 0;
|
r = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(r == -1) {
|
if(r == -1) {
|
||||||
throw DL_ABORT_EX(StringFormat(EX_SOCKET_SEND, errorMsg()).str());
|
throw DL_ABORT_EX(StringFormat(EX_SOCKET_SEND,
|
||||||
|
errorMsg(errNum).c_str()).str());
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -1163,12 +1210,14 @@ ssize_t SocketCore::readDataFrom(char* data, size_t len,
|
||||||
ssize_t r;
|
ssize_t r;
|
||||||
while((r = recvfrom(sockfd_, data, len, 0, addrp, &sockaddrlen)) == -1 &&
|
while((r = recvfrom(sockfd_, data, len, 0, addrp, &sockaddrlen)) == -1 &&
|
||||||
A2_EINTR == SOCKET_ERRNO);
|
A2_EINTR == SOCKET_ERRNO);
|
||||||
|
int errNum = SOCKET_ERRNO;
|
||||||
if(r == -1) {
|
if(r == -1) {
|
||||||
if(A2_WOULDBLOCK(SOCKET_ERRNO)) {
|
if(A2_WOULDBLOCK(errNum)) {
|
||||||
wantRead_ = true;
|
wantRead_ = true;
|
||||||
r = 0;
|
r = 0;
|
||||||
} else {
|
} else {
|
||||||
throw DL_RETRY_EX(StringFormat(EX_SOCKET_RECV, errorMsg()).str());
|
throw DL_RETRY_EX(StringFormat(EX_SOCKET_RECV,
|
||||||
|
errorMsg(errNum).c_str()).str());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sender = util::getNumericNameInfo(addrp, sockaddrlen);
|
sender = util::getNumericNameInfo(addrp, sockaddrlen);
|
||||||
|
@ -1182,9 +1231,11 @@ std::string SocketCore::getSocketError() const
|
||||||
int error;
|
int error;
|
||||||
socklen_t optlen = sizeof(error);
|
socklen_t optlen = sizeof(error);
|
||||||
|
|
||||||
if(getsockopt(sockfd_, SOL_SOCKET, SO_ERROR, (a2_sockopt_t) &error, &optlen) == -1) {
|
if(getsockopt(sockfd_, SOL_SOCKET, SO_ERROR,
|
||||||
|
(a2_sockopt_t) &error, &optlen) == -1) {
|
||||||
|
int errNum = SOCKET_ERRNO;
|
||||||
throw DL_ABORT_EX(StringFormat("Failed to get socket error: %s",
|
throw DL_ABORT_EX(StringFormat("Failed to get socket error: %s",
|
||||||
errorMsg()).str());
|
errorMsg(errNum).c_str()).str());
|
||||||
}
|
}
|
||||||
if(error != 0) {
|
if(error != 0) {
|
||||||
return errorMsg(error);
|
return errorMsg(error);
|
||||||
|
@ -1243,7 +1294,9 @@ void getInterfaceAddress
|
||||||
// First find interface in interface addresses
|
// First find interface in interface addresses
|
||||||
struct ifaddrs* ifaddr = 0;
|
struct ifaddrs* ifaddr = 0;
|
||||||
if(getifaddrs(&ifaddr) == -1) {
|
if(getifaddrs(&ifaddr) == -1) {
|
||||||
logger->info(MSG_INTERFACE_NOT_FOUND, iface.c_str(), errorMsg());
|
int errNum = SOCKET_ERRNO;
|
||||||
|
logger->info(MSG_INTERFACE_NOT_FOUND,
|
||||||
|
iface.c_str(), errorMsg(errNum).c_str());
|
||||||
} else {
|
} else {
|
||||||
auto_delete<struct ifaddrs*> ifaddrDeleter(ifaddr, freeifaddrs);
|
auto_delete<struct ifaddrs*> ifaddrDeleter(ifaddr, freeifaddrs);
|
||||||
for(struct ifaddrs* ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
|
for(struct ifaddrs* ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
|
||||||
|
|
|
@ -229,9 +229,8 @@
|
||||||
#define EX_FILE_OFFSET_OUT_OF_RANGE _("The offset is out of range, offset=%s")
|
#define EX_FILE_OFFSET_OUT_OF_RANGE _("The offset is out of range, offset=%s")
|
||||||
#define EX_NOT_DIRECTORY _("%s is not a directory.")
|
#define EX_NOT_DIRECTORY _("%s is not a directory.")
|
||||||
#define EX_MAKE_DIR _("Failed to make the directory %s, cause: %s")
|
#define EX_MAKE_DIR _("Failed to make the directory %s, cause: %s")
|
||||||
#define EX_SEGMENT_FILE_OPEN _("Failed to open the segment file %s, cause: %s")
|
#define EX_SEGMENT_FILE_WRITE "Failed to write into the segment file %s"
|
||||||
#define EX_SEGMENT_FILE_WRITE _("Failed to write into the segment file %s, cause: %s")
|
#define EX_SEGMENT_FILE_READ "Failed to read from the segment file %s"
|
||||||
#define EX_SEGMENT_FILE_READ _("Failed to read from the segment file %s, cause: %s")
|
|
||||||
|
|
||||||
#define EX_SOCKET_OPEN _("Failed to open a socket, cause: %s")
|
#define EX_SOCKET_OPEN _("Failed to open a socket, cause: %s")
|
||||||
#define EX_SOCKET_SET_OPT _("Failed to set a socket option, cause: %s")
|
#define EX_SOCKET_SET_OPT _("Failed to set a socket option, cause: %s")
|
||||||
|
|
24
src/util.cc
24
src/util.cc
|
@ -1128,10 +1128,13 @@ unsigned int alphaToNum(const std::string& alphabets)
|
||||||
void mkdirs(const std::string& dirpath)
|
void mkdirs(const std::string& dirpath)
|
||||||
{
|
{
|
||||||
File dir(dirpath);
|
File dir(dirpath);
|
||||||
if(!dir.mkdirs() &&!dir.isDir()) {
|
if(!dir.mkdirs()) {
|
||||||
|
int errNum = errno;
|
||||||
|
if(!dir.isDir()) {
|
||||||
throw DL_ABORT_EX
|
throw DL_ABORT_EX
|
||||||
(StringFormat(EX_MAKE_DIR, dir.getPath().c_str(),
|
(StringFormat(EX_MAKE_DIR, dir.getPath().c_str(),
|
||||||
strerror(errno)).str());
|
safeStrerror(errNum).c_str()).str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1171,7 +1174,8 @@ void* allocateAlignedMemory(size_t alignment, size_t size)
|
||||||
int res;
|
int res;
|
||||||
if((res = posix_memalign(&buffer, alignment, size)) != 0) {
|
if((res = posix_memalign(&buffer, alignment, size)) != 0) {
|
||||||
throw FATAL_EXCEPTION
|
throw FATAL_EXCEPTION
|
||||||
(StringFormat("Error in posix_memalign: %s", strerror(res)).str());
|
(StringFormat("Error in posix_memalign: %s",
|
||||||
|
util::safeStrerror(res).c_str()).str());
|
||||||
}
|
}
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
@ -1498,6 +1502,20 @@ std::string encodeNonUtf8(const std::string& s)
|
||||||
return util::isUtf8(s)?s:util::percentEncode(s);
|
return util::isUtf8(s)?s:util::percentEncode(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string makeString(const char* str)
|
||||||
|
{
|
||||||
|
if(str) {
|
||||||
|
return str;
|
||||||
|
} else {
|
||||||
|
return A2STR::NIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string safeStrerror(int errNum)
|
||||||
|
{
|
||||||
|
return makeString(strerror(errNum));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace util
|
} // namespace util
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -427,6 +427,14 @@ std::string createSafePath(const std::string& dir, const std::string& filename);
|
||||||
|
|
||||||
std::string encodeNonUtf8(const std::string& s);
|
std::string encodeNonUtf8(const std::string& s);
|
||||||
|
|
||||||
|
// Create string safely. If str is NULL, returns empty string.
|
||||||
|
// Otherwise, returns std::string(str).
|
||||||
|
std::string makeString(const char* str);
|
||||||
|
|
||||||
|
// This function is basically the same with strerror(errNum) but when
|
||||||
|
// strerror returns NULL, this function returns empty string.
|
||||||
|
std::string safeStrerror(int errNum);
|
||||||
|
|
||||||
} // namespace util
|
} // namespace util
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
Loading…
Reference in New Issue