From: Alex Dowad Date: Thu, 14 May 2015 10:24:29 +0000 (-0700) Subject: Fix incorrect use of errno in various libcomm.la places X-Git-Tag: merge-candidate-3-v1~123 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5dc67d5887e697d2b35b24c4e715140513e94d93;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 e6c565779e..482c97e296 100644 --- a/src/comm/Read.cc +++ b/src/comm/Read.cc @@ -140,22 +140,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 17c13bb7c1..f009fbcd71 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); } }