]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Fix incorrect use of errno in various libcomm.la places
authorAlex Dowad <alexinbeijing@gmail.com>
Thu, 14 May 2015 10:24:29 +0000 (03:24 -0700)
committerAmos Jeffries <squid3@treenet.co.nz>
Thu, 14 May 2015 10:24:29 +0000 (03:24 -0700)
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.

src/comm/Read.cc
src/comm/TcpAcceptor.cc
src/comm/Write.cc

index e6c565779e4d41a308cde87936c7a4f0b824f4a5..482c97e29648211a4edc931966fe9e10a1c44a0f 100644 (file)
@@ -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;
     };
 
index 17c13bb7c15d6c478939298fd6966393b58cb7bb..f009fbcd715f3a0e75f8c3c49d296b61923303aa 100644 (file)
@@ -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;
     }
 
index 4a853e20888e54488cb8e71f10dbbb374b72bde8..b74f2b2ecac19d140cd7705349b1729cf380160a 100644 (file)
@@ -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);
         }
     }