]> git.lizzy.rs Git - rust.git/commitdiff
Use less syscalls in `FileDesc::set_{nonblocking,cloexec}`
authorTobias Bucher <tobiasbucher5991@gmail.com>
Sat, 4 Feb 2017 00:10:12 +0000 (01:10 +0100)
committerTobias Bucher <tobiasbucher5991@gmail.com>
Sat, 4 Feb 2017 00:10:12 +0000 (01:10 +0100)
Only set the flags if they differ from what the OS reported, use
`FIONBIO` to atomically set the non-blocking IO flag on Linux.

src/libstd/sys/unix/fd.rs

index dcab30aad8385b9c9ed38929c3531007a1740b6d..c690fd467ee4125a97ddefb8af01e327c482f933 100644 (file)
@@ -144,11 +144,24 @@ pub fn set_cloexec(&self) -> io::Result<()> {
     pub fn set_cloexec(&self) -> io::Result<()> {
         unsafe {
             let previous = cvt(libc::fcntl(self.fd, libc::F_GETFD))?;
-            cvt(libc::fcntl(self.fd, libc::F_SETFD, previous | libc::FD_CLOEXEC))?;
+            let new = previous | libc::FD_CLOEXEC;
+            if new != previous {
+                cvt(libc::fcntl(self.fd, libc::F_SETFD, new))?;
+            }
+            Ok(())
+        }
+    }
+
+    #[cfg(target_os = "linux")]
+    pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
+        unsafe {
+            let v = nonblocking as c_int;
+            cvt(libc::ioctl(self.fd, libc::FIONBIO, &v))?;
             Ok(())
         }
     }
 
+    #[cfg(not(target_os = "linux"))]
     pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
         unsafe {
             let previous = cvt(libc::fcntl(self.fd, libc::F_GETFL))?;
@@ -157,7 +170,9 @@ pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
             } else {
                 previous & !libc::O_NONBLOCK
             };
-            cvt(libc::fcntl(self.fd, libc::F_SETFL, new))?;
+            if new != previous {
+                cvt(libc::fcntl(self.fd, libc::F_SETFL, new))?;
+            }
             Ok(())
         }
     }