From: Haijun Zhu <haijunz@fb.com>
Date: Mon, 2 Feb 2015 19:41:38 +0000 (-0800)
Subject: Set CLOEXEC for connected fd
X-Git-Tag: v0.24.0~9
X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=4bffc7589f7bb66aa8ab0dbf1e5d39840daf6121;p=folly.git

Set CLOEXEC for connected fd

Summary:
AsyncSocket sets CLOEXEC if it connects an address, but won't
if it uses a connected fd. This sets CLOEXEC for such fd.

Test Plan: fbconfig folly/io/async/test && fbmake runtests

Reviewed By: davejwatson@fb.com

Subscribers: trunkagent, folly-diffs@, zacm

FB internal diff: D1809300

Signature: t1:1809300:1422900997:40fcc84506582ac67076fd975a36d094522c35c2
---

diff --git a/folly/io/async/AsyncSocket.cpp b/folly/io/async/AsyncSocket.cpp
index 167a49bf..c8754d2c 100644
--- a/folly/io/async/AsyncSocket.cpp
+++ b/folly/io/async/AsyncSocket.cpp
@@ -222,6 +222,7 @@ AsyncSocket::AsyncSocket(EventBase* evb, int fd)
           << fd << ")";
   init();
   fd_ = fd;
+  setCloseOnExec();
   state_ = StateEnum::ESTABLISHED;
 }
 
@@ -293,6 +294,15 @@ void AsyncSocket::setShutdownSocketSet(ShutdownSocketSet* newSS) {
   }
 }
 
+void AsyncSocket::setCloseOnExec() {
+  int rv = fcntl(fd_, F_SETFD, FD_CLOEXEC);
+  if (rv != 0) {
+    throw AsyncSocketException(AsyncSocketException::INTERNAL_ERROR,
+                               withAddr("failed to set close-on-exec flag"),
+                               errno);
+  }
+}
+
 void AsyncSocket::connect(ConnectCallback* callback,
                            const folly::SocketAddress& address,
                            int timeout,
@@ -331,14 +341,7 @@ void AsyncSocket::connect(ConnectCallback* callback,
     }
     ioHandler_.changeHandlerFD(fd_);
 
-    // Set the FD_CLOEXEC flag so that the socket will be closed if the program
-    // later forks and execs.
-    int rv = fcntl(fd_, F_SETFD, FD_CLOEXEC);
-    if (rv != 0) {
-      throw AsyncSocketException(AsyncSocketException::INTERNAL_ERROR,
-                                withAddr("failed to set close-on-exec flag"),
-                                errno);
-    }
+    setCloseOnExec();
 
     // Put the socket in non-blocking mode
     int flags = fcntl(fd_, F_GETFL, 0);
@@ -346,7 +349,7 @@ void AsyncSocket::connect(ConnectCallback* callback,
       throw AsyncSocketException(AsyncSocketException::INTERNAL_ERROR,
                                 withAddr("failed to get socket flags"), errno);
     }
-    rv = fcntl(fd_, F_SETFL, flags | O_NONBLOCK);
+    int rv = fcntl(fd_, F_SETFL, flags | O_NONBLOCK);
     if (rv == -1) {
       throw AsyncSocketException(
           AsyncSocketException::INTERNAL_ERROR,
diff --git a/folly/io/async/AsyncSocket.h b/folly/io/async/AsyncSocket.h
index 7819647b..10614abf 100644
--- a/folly/io/async/AsyncSocket.h
+++ b/folly/io/async/AsyncSocket.h
@@ -398,6 +398,13 @@ class AsyncSocket : virtual public AsyncTransportWrapper {
    */
   int setNoDelay(bool noDelay);
 
+
+  /**
+   * Set the FD_CLOEXEC flag so that the socket will be closed if the program
+   * later forks and execs.
+   */
+  void setCloseOnExec();
+
   /*
    * Set the Flavor of Congestion Control to be used for this Socket
    * Please check '/lib/modules/<kernel>/kernel/net/ipv4' for tcp_*.ko