From: Alex Dowad Date: Fri, 22 May 2015 04:47:22 +0000 (-0700) Subject: Fix incorrect use of errno in various libcomm.la places X-Git-Tag: SQUID_3_5_5~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2cd95caf3f540030c50f94d981b6eb9549b23526;p=thirdparty%2Fsquid.git Fix incorrect use of errno in various libcomm.la places Fix problems with 'errno' in TcpAcceptor::Listen, Comm::HandleRead, and Comm::HandleWrite. 'errno' is only valid after a standard library function returns an error. Also, we must avoid calling out to other functions before recording the value of 'errno', since they might overwrite it. --- diff --git a/src/comm/Read.cc b/src/comm/Read.cc index 9712de6bd5..afae89ad84 100644 --- a/src/comm/Read.cc +++ b/src/comm/Read.cc @@ -138,22 +138,22 @@ Comm::HandleRead(int fd, void *data) /* For legacy callers : Attempt a read */ // Keep in sync with Comm::ReadNow()! ++ statCounter.syscalls.sock.reads; - errno = 0; + int xerrno = errno = 0; int retval = FD_READ_METHOD(fd, ccb->buf, ccb->size); - debugs(5, 3, "FD " << fd << ", size " << ccb->size << ", retval " << retval << ", errno " << errno); + xerrno = errno; + debugs(5, 3, "FD " << fd << ", size " << ccb->size << ", retval " << retval << ", errno " << xerrno); /* See if we read anything */ /* Note - read 0 == socket EOF, which is a valid read */ if (retval >= 0) { fd_bytes(fd, retval, FD_READ); ccb->offset = retval; - ccb->finish(Comm::OK, errno); + ccb->finish(Comm::OK, 0); return; - - } else if (retval < 0 && !ignoreErrno(errno)) { + } else if (retval < 0 && !ignoreErrno(xerrno)) { debugs(5, 3, "comm_read_try: scheduling Comm::COMM_ERROR"); ccb->offset = 0; - ccb->finish(Comm::COMM_ERROR, errno); + ccb->finish(Comm::COMM_ERROR, xerrno); return; }; diff --git a/src/comm/TcpAcceptor.cc b/src/comm/TcpAcceptor.cc index ff162797f1..0d5e46b583 100644 --- a/src/comm/TcpAcceptor.cc +++ b/src/comm/TcpAcceptor.cc @@ -150,10 +150,10 @@ Comm::TcpAcceptor::status() const void Comm::TcpAcceptor::setListen() { - errcode = 0; // reset local errno copy. + errcode = errno = 0; if (listen(conn->fd, Squid_MaxFD >> 2) < 0) { - debugs(50, DBG_CRITICAL, "ERROR: listen(" << status() << ", " << (Squid_MaxFD >> 2) << "): " << xstrerror()); errcode = errno; + debugs(50, DBG_CRITICAL, "ERROR: listen(" << status() << ", " << (Squid_MaxFD >> 2) << "): " << xstrerr(errcode)); return; } diff --git a/src/comm/Write.cc b/src/comm/Write.cc index 4a853e2088..b74f2b2eca 100644 --- a/src/comm/Write.cc +++ b/src/comm/Write.cc @@ -102,7 +102,9 @@ Comm::HandleWrite(int fd, void *data) #endif /* USE_DELAY_POOLS */ /* actually WRITE data */ + int xerrno = errno = 0; len = FD_WRITE_METHOD(fd, state->buf + state->offset, nleft); + xerrno = errno; debugs(5, 5, HERE << "write() returns " << len); #if USE_DELAY_POOLS @@ -133,18 +135,18 @@ Comm::HandleWrite(int fd, void *data) if (nleft != 0) debugs(5, DBG_IMPORTANT, "FD " << fd << " write failure: connection closed with " << nleft << " bytes remaining."); - state->finish(nleft ? Comm::COMM_ERROR : Comm::OK, errno); + state->finish(nleft ? Comm::COMM_ERROR : Comm::OK, 0); } else if (len < 0) { /* An error */ if (fd_table[fd].flags.socket_eof) { - debugs(50, 2, HERE << "FD " << fd << " write failure: " << xstrerror() << "."); - state->finish(nleft ? Comm::COMM_ERROR : Comm::OK, errno); - } else if (ignoreErrno(errno)) { - debugs(50, 9, HERE << "FD " << fd << " write failure: " << xstrerror() << "."); + debugs(50, 2, "FD " << fd << " write failure: " << xstrerr(xerrno) << "."); + state->finish(nleft ? Comm::COMM_ERROR : Comm::OK, xerrno); + } else if (ignoreErrno(xerrno)) { + debugs(50, 9, "FD " << fd << " write failure: " << xstrerr(xerrno) << "."); state->selectOrQueueWrite(); } else { - debugs(50, 2, HERE << "FD " << fd << " write failure: " << xstrerror() << "."); - state->finish(nleft ? Comm::COMM_ERROR : Comm::OK, errno); + debugs(50, 2, "FD " << fd << " write failure: " << xstrerr(xerrno) << "."); + state->finish(nleft ? Comm::COMM_ERROR : Comm::OK, xerrno); } } else { /* A successful write, continue */ @@ -154,7 +156,7 @@ Comm::HandleWrite(int fd, void *data) /* Not done, reinstall the write handler and write some more */ state->selectOrQueueWrite(); } else { - state->finish(nleft ? Comm::OK : Comm::COMM_ERROR, errno); + state->finish(nleft ? Comm::OK : Comm::COMM_ERROR, 0); } }