Add more error handling for close() calls.

This commit is contained in:
Jon Siwek 2012-07-26 12:40:12 -05:00
parent d872b1d9f6
commit 734e5f68d3
7 changed files with 47 additions and 19 deletions

View file

@ -76,7 +76,7 @@ void ChunkedIO::DumpDebugData(const char* basefnname, bool want_reads)
ChunkedIOFd io(fd, "dump-file");
io.Write(*i);
io.Flush();
close(fd);
safe_close(fd);
}
l->clear();
@ -127,7 +127,7 @@ ChunkedIOFd::~ChunkedIOFd()
delete [] read_buffer;
delete [] write_buffer;
close(fd);
safe_close(fd);
if ( partial )
{
@ -686,7 +686,7 @@ ChunkedIOSSL::~ChunkedIOSSL()
ssl = 0;
}
close(socket);
safe_close(socket);
}

View file

@ -58,7 +58,7 @@ void FlowSrc::Process()
void FlowSrc::Close()
{
close(selectable_fd);
safe_close(selectable_fd);
}

View file

@ -647,7 +647,7 @@ void RemoteSerializer::Fork()
exit(1); // FIXME: Better way to handle this?
}
close(pipe[1]);
safe_close(pipe[1]);
return;
}
@ -664,12 +664,12 @@ void RemoteSerializer::Fork()
}
child.SetParentIO(io);
close(pipe[0]);
safe_close(pipe[0]);
// Close file descriptors.
close(0);
close(1);
close(2);
safe_close(0);
safe_close(1);
safe_close(2);
// Be nice.
setpriority(PRIO_PROCESS, 0, 5);
@ -4001,7 +4001,7 @@ bool SocketComm::Connect(Peer* peer)
if ( connect(sockfd, res->ai_addr, res->ai_addrlen) < 0 )
{
Error(fmt("connect failed: %s", strerror(errno)), peer);
close(sockfd);
safe_close(sockfd);
sockfd = -1;
continue;
}
@ -4174,16 +4174,18 @@ bool SocketComm::Listen()
{
Error(fmt("can't bind to %s:%s, %s", l_addr_str.c_str(),
port_str, strerror(errno)));
close(fd);
if ( errno == EADDRINUSE )
{
// Abandon completely this attempt to set up listening sockets,
// try again later.
safe_close(fd);
CloseListenFDs();
listen_next_try = time(0) + bind_retry_interval;
return false;
}
safe_close(fd);
continue;
}
@ -4191,7 +4193,7 @@ bool SocketComm::Listen()
{
Error(fmt("can't listen on %s:%s, %s", l_addr_str.c_str(),
port_str, strerror(errno)));
close(fd);
safe_close(fd);
continue;
}
@ -4227,7 +4229,7 @@ bool SocketComm::AcceptConnection(int fd)
{
Error(fmt("accept fail, unknown address family %d",
client.ss.ss_family));
close(clientfd);
safe_close(clientfd);
return false;
}
@ -4298,7 +4300,7 @@ const char* SocketComm::MakeLogString(const char* msg, Peer* peer)
void SocketComm::CloseListenFDs()
{
for ( size_t i = 0; i < listen_fds.size(); ++i )
close(listen_fds[i]);
safe_close(listen_fds[i]);
listen_fds.clear();
}

View file

@ -746,7 +746,7 @@ FileSerializer::~FileSerializer()
if ( io )
delete io; // destructor will call close() on fd
else if ( fd >= 0 )
close(fd);
safe_close(fd);
}
bool FileSerializer::Open(const char* file, bool pure)
@ -810,7 +810,7 @@ void FileSerializer::CloseFile()
io->Flush();
if ( fd >= 0 && ! io ) // destructor of io calls close() on fd
close(fd);
safe_close(fd);
fd = -1;
delete [] file;

View file

@ -86,7 +86,7 @@ void Ascii::CloseFile(double t)
WriteHeaderField("end", ts);
}
close(fd);
safe_close(fd);
fd = 0;
}

View file

@ -722,7 +722,7 @@ void init_random_seed(uint32 seed, const char* read_file, const char* write_file
{
int amt = read(fd, buf + pos,
sizeof(uint32) * (bufsiz - pos));
close(fd);
safe_close(fd);
if ( amt > 0 )
pos += amt / sizeof(uint32);
@ -1204,7 +1204,7 @@ void _set_processing_status(const char* status)
len -= n;
}
close(fd);
safe_close(fd);
errno = old_errno;
}
@ -1353,6 +1353,29 @@ bool safe_write(int fd, const char* data, int len)
return true;
}
void safe_close(int fd)
{
/*
* Failure cases of close(2) are ...
* EBADF: Indicative of programming logic error that needs to be fixed, we
* should always be attempting to close a valid file descriptor.
* EINTR: Ignore signal interruptions, most implementations will actually
* reclaim the open descriptor and POSIX standard doesn't leave many
* options by declaring the state of the descriptor as "unspecified".
* Attempting to inspect actual state or re-attempt close() is not
* thread safe.
* EIO: Again the state of descriptor is "unspecified", but don't recover
* from an I/O error, safe_write() won't either.
*/
if ( close(fd) < 0 && errno != EINTR )
{
char buf[128];
strerror_r(errno, buf, sizeof(buf));
fprintf(stderr, "safe_close error %d: %s\n", errno, buf);
abort();
}
}
void out_of_memory(const char* where)
{
reporter->FatalError("out of memory in %s.\n", where);

View file

@ -297,6 +297,9 @@ inline size_t pad_size(size_t size)
// thread-safe as long as no two threads write to the same descriptor.
extern bool safe_write(int fd, const char* data, int len);
// Wraps close(2) to emit error messages and abort on unrecoverable errors.
extern void safe_close(int fd);
extern void out_of_memory(const char* where);
inline void* safe_realloc(void* ptr, size_t size)