]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/boost/boost/asio/detail/impl/descriptor_ops.ipp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / asio / detail / impl / descriptor_ops.ipp
index f4c21d551b1189f1d95eb5dda33523c038888753..16c04f3eb8aba7646441a655c6ada209c1cc64e8 100644 (file)
@@ -33,10 +33,8 @@ namespace descriptor_ops {
 
 int open(const char* path, int flags, boost::system::error_code& ec)
 {
-  errno = 0;
-  int result = error_wrapper(::open(path, flags), ec);
-  if (result >= 0)
-    ec = boost::system::error_code();
+  int result = ::open(path, flags);
+  get_last_error(ec, result < 0);
   return result;
 }
 
@@ -45,8 +43,8 @@ int close(int d, state_type& state, boost::system::error_code& ec)
   int result = 0;
   if (d != -1)
   {
-    errno = 0;
-    result = error_wrapper(::close(d), ec);
+    result = ::close(d);
+    get_last_error(ec, result < 0);
 
     if (result != 0
         && (ec == boost::asio::error::would_block
@@ -68,13 +66,11 @@ int close(int d, state_type& state, boost::system::error_code& ec)
 #endif // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__)
       state &= ~non_blocking;
 
-      errno = 0;
-      result = error_wrapper(::close(d), ec);
+      result = ::close(d);
+      get_last_error(ec, result < 0);
     }
   }
 
-  if (result == 0)
-    ec = boost::system::error_code();
   return result;
 }
 
@@ -87,23 +83,23 @@ bool set_user_non_blocking(int d, state_type& state,
     return false;
   }
 
-  errno = 0;
 #if defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__)
-  int result = error_wrapper(::fcntl(d, F_GETFL, 0), ec);
+  int result = ::fcntl(d, F_GETFL, 0);
+  get_last_error(ec, result < 0);
   if (result >= 0)
   {
-    errno = 0;
     int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK));
-    result = error_wrapper(::fcntl(d, F_SETFL, flag), ec);
+    result = ::fcntl(d, F_SETFL, flag);
+    get_last_error(ec, result < 0);
   }
 #else // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__)
   ioctl_arg_type arg = (value ? 1 : 0);
-  int result = error_wrapper(::ioctl(d, FIONBIO, &arg), ec);
+  int result = ::ioctl(d, FIONBIO, &arg);
+  get_last_error(ec, result < 0);
 #endif // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__)
 
   if (result >= 0)
   {
-    ec = boost::system::error_code();
     if (value)
       state |= user_set_non_blocking;
     else
@@ -137,23 +133,23 @@ bool set_internal_non_blocking(int d, state_type& state,
     return false;
   }
 
-  errno = 0;
 #if defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__)
-  int result = error_wrapper(::fcntl(d, F_GETFL, 0), ec);
+  int result = ::fcntl(d, F_GETFL, 0);
+  get_last_error(ec, result < 0);
   if (result >= 0)
   {
-    errno = 0;
     int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK));
-    result = error_wrapper(::fcntl(d, F_SETFL, flag), ec);
+    result = ::fcntl(d, F_SETFL, flag);
+    get_last_error(ec, result < 0);
   }
 #else // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__)
   ioctl_arg_type arg = (value ? 1 : 0);
-  int result = error_wrapper(::ioctl(d, FIONBIO, &arg), ec);
+  int result = ::ioctl(d, FIONBIO, &arg);
+  get_last_error(ec, result < 0);
 #endif // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__)
 
   if (result >= 0)
   {
-    ec = boost::system::error_code();
     if (value)
       state |= internal_non_blocking;
     else
@@ -176,7 +172,7 @@ std::size_t sync_read(int d, state_type state, buf* bufs,
   // A request to read 0 bytes on a stream is a no-op.
   if (all_empty)
   {
-    ec = boost::system::error_code();
+    ec.assign(0, ec.category());
     return 0;
   }
 
@@ -184,9 +180,54 @@ std::size_t sync_read(int d, state_type state, buf* bufs,
   for (;;)
   {
     // Try to complete the operation without blocking.
-    errno = 0;
-    signed_size_type bytes = error_wrapper(::readv(
-          d, bufs, static_cast<int>(count)), ec);
+    signed_size_type bytes = ::readv(d, bufs, static_cast<int>(count));
+    get_last_error(ec, bytes < 0);
+
+    // Check if operation succeeded.
+    if (bytes > 0)
+      return bytes;
+
+    // Check for EOF.
+    if (bytes == 0)
+    {
+      ec = boost::asio::error::eof;
+      return 0;
+    }
+
+    // Operation failed.
+    if ((state & user_set_non_blocking)
+        || (ec != boost::asio::error::would_block
+          && ec != boost::asio::error::try_again))
+      return 0;
+
+    // Wait for descriptor to become ready.
+    if (descriptor_ops::poll_read(d, 0, ec) < 0)
+      return 0;
+  }
+}
+
+std::size_t sync_read1(int d, state_type state, void* data,
+    std::size_t size, boost::system::error_code& ec)
+{
+  if (d == -1)
+  {
+    ec = boost::asio::error::bad_descriptor;
+    return 0;
+  }
+
+  // A request to read 0 bytes on a stream is a no-op.
+  if (size == 0)
+  {
+    ec.assign(0, ec.category());
+    return 0;
+  }
+
+  // Read some data.
+  for (;;)
+  {
+    // Try to complete the operation without blocking.
+    signed_size_type bytes = ::read(d, data, size);
+    get_last_error(ec, bytes < 0);
 
     // Check if operation succeeded.
     if (bytes > 0)
@@ -217,9 +258,8 @@ bool non_blocking_read(int d, buf* bufs, std::size_t count,
   for (;;)
   {
     // Read some data.
-    errno = 0;
-    signed_size_type bytes = error_wrapper(::readv(
-          d, bufs, static_cast<int>(count)), ec);
+    signed_size_type bytes = ::readv(d, bufs, static_cast<int>(count));
+    get_last_error(ec, bytes < 0);
 
     // Check for end of stream.
     if (bytes == 0)
@@ -228,6 +268,13 @@ bool non_blocking_read(int d, buf* bufs, std::size_t count,
       return true;
     }
 
+    // Check if operation succeeded.
+    if (bytes > 0)
+    {
+      bytes_transferred = bytes;
+      return true;
+    }
+
     // Retry operation if interrupted by signal.
     if (ec == boost::asio::error::interrupted)
       continue;
@@ -237,15 +284,46 @@ bool non_blocking_read(int d, buf* bufs, std::size_t count,
         || ec == boost::asio::error::try_again)
       return false;
 
-    // Operation is complete.
+    // Operation failed.
+    bytes_transferred = 0;
+    return true;
+  }
+}
+
+bool non_blocking_read1(int d, void* data, std::size_t size,
+    boost::system::error_code& ec, std::size_t& bytes_transferred)
+{
+  for (;;)
+  {
+    // Read some data.
+    signed_size_type bytes = ::read(d, data, size);
+    get_last_error(ec, bytes < 0);
+
+    // Check for end of stream.
+    if (bytes == 0)
+    {
+      ec = boost::asio::error::eof;
+      return true;
+    }
+
+    // Check if operation succeeded.
     if (bytes > 0)
     {
-      ec = boost::system::error_code();
       bytes_transferred = bytes;
+      return true;
     }
-    else
-      bytes_transferred = 0;
 
+    // Retry operation if interrupted by signal.
+    if (ec == boost::asio::error::interrupted)
+      continue;
+
+    // Check if we need to run the operation again.
+    if (ec == boost::asio::error::would_block
+        || ec == boost::asio::error::try_again)
+      return false;
+
+    // Operation failed.
+    bytes_transferred = 0;
     return true;
   }
 }
@@ -262,7 +340,46 @@ std::size_t sync_write(int d, state_type state, const buf* bufs,
   // A request to write 0 bytes on a stream is a no-op.
   if (all_empty)
   {
-    ec = boost::system::error_code();
+    ec.assign(0, ec.category());
+    return 0;
+  }
+
+  // Write some data.
+  for (;;)
+  {
+    // Try to complete the operation without blocking.
+    signed_size_type bytes = ::writev(d, bufs, static_cast<int>(count));
+    get_last_error(ec, bytes < 0);
+
+    // Check if operation succeeded.
+    if (bytes > 0)
+      return bytes;
+
+    // Operation failed.
+    if ((state & user_set_non_blocking)
+        || (ec != boost::asio::error::would_block
+          && ec != boost::asio::error::try_again))
+      return 0;
+
+    // Wait for descriptor to become ready.
+    if (descriptor_ops::poll_write(d, 0, ec) < 0)
+      return 0;
+  }
+}
+
+std::size_t sync_write1(int d, state_type state, const void* data,
+    std::size_t size, boost::system::error_code& ec)
+{
+  if (d == -1)
+  {
+    ec = boost::asio::error::bad_descriptor;
+    return 0;
+  }
+
+  // A request to write 0 bytes on a stream is a no-op.
+  if (size == 0)
+  {
+    ec.assign(0, ec.category());
     return 0;
   }
 
@@ -270,9 +387,8 @@ std::size_t sync_write(int d, state_type state, const buf* bufs,
   for (;;)
   {
     // Try to complete the operation without blocking.
-    errno = 0;
-    signed_size_type bytes = error_wrapper(::writev(
-          d, bufs, static_cast<int>(count)), ec);
+    signed_size_type bytes = ::write(d, data, size);
+    get_last_error(ec, bytes < 0);
 
     // Check if operation succeeded.
     if (bytes > 0)
@@ -296,9 +412,15 @@ bool non_blocking_write(int d, const buf* bufs, std::size_t count,
   for (;;)
   {
     // Write some data.
-    errno = 0;
-    signed_size_type bytes = error_wrapper(::writev(
-          d, bufs, static_cast<int>(count)), ec);
+    signed_size_type bytes = ::writev(d, bufs, static_cast<int>(count));
+    get_last_error(ec, bytes < 0);
+
+    // Check if operation succeeded.
+    if (bytes >= 0)
+    {
+      bytes_transferred = bytes;
+      return true;
+    }
 
     // Retry operation if interrupted by signal.
     if (ec == boost::asio::error::interrupted)
@@ -309,15 +431,39 @@ bool non_blocking_write(int d, const buf* bufs, std::size_t count,
         || ec == boost::asio::error::try_again)
       return false;
 
-    // Operation is complete.
+    // Operation failed.
+    bytes_transferred = 0;
+    return true;
+  }
+}
+
+bool non_blocking_write1(int d, const void* data, std::size_t size,
+    boost::system::error_code& ec, std::size_t& bytes_transferred)
+{
+  for (;;)
+  {
+    // Write some data.
+    signed_size_type bytes = ::write(d, data, size);
+    get_last_error(ec, bytes < 0);
+
+    // Check if operation succeeded.
     if (bytes >= 0)
     {
-      ec = boost::system::error_code();
       bytes_transferred = bytes;
+      return true;
     }
-    else
-      bytes_transferred = 0;
 
+    // Retry operation if interrupted by signal.
+    if (ec == boost::asio::error::interrupted)
+      continue;
+
+    // Check if we need to run the operation again.
+    if (ec == boost::asio::error::would_block
+        || ec == boost::asio::error::try_again)
+      return false;
+
+    // Operation failed.
+    bytes_transferred = 0;
     return true;
   }
 }
@@ -331,13 +477,11 @@ int ioctl(int d, state_type& state, long cmd,
     return -1;
   }
 
-  errno = 0;
-  int result = error_wrapper(::ioctl(d, cmd, arg), ec);
+  int result = ::ioctl(d, cmd, arg);
+  get_last_error(ec, result < 0);
 
   if (result >= 0)
   {
-    ec = boost::system::error_code();
-
     // When updating the non-blocking mode we always perform the ioctl syscall,
     // even if the flags would otherwise indicate that the descriptor is
     // already in the correct state. This ensures that the underlying
@@ -371,10 +515,8 @@ int fcntl(int d, int cmd, boost::system::error_code& ec)
     return -1;
   }
 
-  errno = 0;
-  int result = error_wrapper(::fcntl(d, cmd), ec);
-  if (result != -1)
-    ec = boost::system::error_code();
+  int result = ::fcntl(d, cmd);
+  get_last_error(ec, result < 0);
   return result;
 }
 
@@ -386,10 +528,8 @@ int fcntl(int d, int cmd, long arg, boost::system::error_code& ec)
     return -1;
   }
 
-  errno = 0;
-  int result = error_wrapper(::fcntl(d, cmd, arg), ec);
-  if (result != -1)
-    ec = boost::system::error_code();
+  int result = ::fcntl(d, cmd, arg);
+  get_last_error(ec, result < 0);
   return result;
 }
 
@@ -406,13 +546,11 @@ int poll_read(int d, state_type state, boost::system::error_code& ec)
   fds.events = POLLIN;
   fds.revents = 0;
   int timeout = (state & user_set_non_blocking) ? 0 : -1;
-  errno = 0;
-  int result = error_wrapper(::poll(&fds, 1, timeout), ec);
+  int result = ::poll(&fds, 1, timeout);
+  get_last_error(ec, result < 0);
   if (result == 0)
-    ec = (state & user_set_non_blocking)
-      ? boost::asio::error::would_block : boost::system::error_code();
-  else if (result > 0)
-    ec = boost::system::error_code();
+    if (state & user_set_non_blocking)
+      ec = boost::asio::error::would_block;
   return result;
 }
 
@@ -429,13 +567,11 @@ int poll_write(int d, state_type state, boost::system::error_code& ec)
   fds.events = POLLOUT;
   fds.revents = 0;
   int timeout = (state & user_set_non_blocking) ? 0 : -1;
-  errno = 0;
-  int result = error_wrapper(::poll(&fds, 1, timeout), ec);
+  int result = ::poll(&fds, 1, timeout);
+  get_last_error(ec, result < 0);
   if (result == 0)
-    ec = (state & user_set_non_blocking)
-      ? boost::asio::error::would_block : boost::system::error_code();
-  else if (result > 0)
-    ec = boost::system::error_code();
+    if (state & user_set_non_blocking)
+      ec = boost::asio::error::would_block;
   return result;
 }
 
@@ -452,13 +588,11 @@ int poll_error(int d, state_type state, boost::system::error_code& ec)
   fds.events = POLLPRI | POLLERR | POLLHUP;
   fds.revents = 0;
   int timeout = (state & user_set_non_blocking) ? 0 : -1;
-  errno = 0;
-  int result = error_wrapper(::poll(&fds, 1, timeout), ec);
+  int result = ::poll(&fds, 1, timeout);
+  get_last_error(ec, result < 0);
   if (result == 0)
-    ec = (state & user_set_non_blocking)
-      ? boost::asio::error::would_block : boost::system::error_code();
-  else if (result > 0)
-    ec = boost::system::error_code();
+    if (state & user_set_non_blocking)
+      ec = boost::asio::error::would_block;
   return result;
 }