OSDN Git Service

Return errors explicitly instead of using errno.
authorSreeram Ramachandran <sreeram@google.com>
Fri, 20 Jun 2014 18:51:48 +0000 (11:51 -0700)
committerSreeram Ramachandran <sreeram@google.com>
Fri, 20 Jun 2014 19:16:43 +0000 (12:16 -0700)
Change-Id: Ia29f500e747a8c72d13a8f38c3b08c319c8c029a

client/FwmarkClient.cpp
client/FwmarkClient.h
client/NetdClient.cpp
include/NetdClient.h

index 24c84c4..03cd5fb 100644 (file)
@@ -36,25 +36,21 @@ FwmarkClient::FwmarkClient() : mChannel(-1) {
 
 FwmarkClient::~FwmarkClient() {
     if (mChannel >= 0) {
-        // We don't care about errors while closing the channel, so restore any previous error.
-        int error = errno;
         close(mChannel);
-        errno = error;
     }
 }
 
-bool FwmarkClient::send(void* data, size_t len, int fd) {
+int FwmarkClient::send(void* data, size_t len, int fd) {
     mChannel = socket(AF_UNIX, SOCK_STREAM, 0);
     if (mChannel == -1) {
-        return false;
+        return errno;
     }
 
     if (TEMP_FAILURE_RETRY(connect(mChannel, reinterpret_cast<const sockaddr*>(&FWMARK_SERVER_PATH),
                                    sizeof(FWMARK_SERVER_PATH))) == -1) {
         // If we are unable to connect to the fwmark server, assume there's no error. This protects
         // against future changes if the fwmark server goes away.
-        errno = 0;
-        return true;
+        return 0;
     }
 
     iovec iov;
@@ -82,14 +78,14 @@ bool FwmarkClient::send(void* data, size_t len, int fd) {
     memcpy(CMSG_DATA(cmsgh), &fd, sizeof(fd));
 
     if (TEMP_FAILURE_RETRY(sendmsg(mChannel, &message, 0)) == -1) {
-        return false;
+        return errno;
     }
 
     int error = 0;
+
     if (TEMP_FAILURE_RETRY(recv(mChannel, &error, sizeof(error), 0)) == -1) {
-        return false;
+        return errno;
     }
 
-    errno = error;
-    return !error;
+    return error;
 }
index cb4fb74..37f89bc 100644 (file)
@@ -29,8 +29,8 @@ public:
     ~FwmarkClient();
 
     // Sends |data| to the fwmark server, along with |fd| as ancillary data using cmsg(3).
-    // Returns true on success.
-    bool send(void* data, size_t len, int fd);
+    // Returns 0 on success or an errno value on failure.
+    int send(void* data, size_t len, int fd);
 
 private:
     int mChannel;
index ba6dadd..8a54354 100644 (file)
@@ -40,8 +40,7 @@ Accept4FunctionType libcAccept4 = 0;
 ConnectFunctionType libcConnect = 0;
 SocketFunctionType libcSocket = 0;
 
-int closeFdAndRestoreErrno(int fd) {
-    int error = errno;
+int closeFdAndSetErrno(int fd, int error) {
     close(fd);
     errno = error;
     return -1;
@@ -58,13 +57,14 @@ int netdClientAccept4(int sockfd, sockaddr* addr, socklen_t* addrlen, int flags)
     } else {
         socklen_t familyLen = sizeof(family);
         if (getsockopt(acceptedSocket, SOL_SOCKET, SO_DOMAIN, &family, &familyLen) == -1) {
-            return closeFdAndRestoreErrno(acceptedSocket);
+            return closeFdAndSetErrno(acceptedSocket, errno);
         }
     }
     if (FwmarkClient::shouldSetFwmark(family)) {
         FwmarkCommand command = {FwmarkCommand::ON_ACCEPT, 0};
-        if (!FwmarkClient().send(&command, sizeof(command), acceptedSocket)) {
-            return closeFdAndRestoreErrno(acceptedSocket);
+        int error = FwmarkClient().send(&command, sizeof(command), acceptedSocket);
+        if (error) {
+            return closeFdAndSetErrno(acceptedSocket, error);
         }
     }
     return acceptedSocket;
@@ -73,7 +73,9 @@ int netdClientAccept4(int sockfd, sockaddr* addr, socklen_t* addrlen, int flags)
 int netdClientConnect(int sockfd, const sockaddr* addr, socklen_t addrlen) {
     if (sockfd >= 0 && addr && FwmarkClient::shouldSetFwmark(addr->sa_family)) {
         FwmarkCommand command = {FwmarkCommand::ON_CONNECT, 0};
-        if (!FwmarkClient().send(&command, sizeof(command), sockfd)) {
+        int error = FwmarkClient().send(&command, sizeof(command), sockfd);
+        if (error) {
+            errno = error;
             return -1;
         }
     }
@@ -87,8 +89,9 @@ int netdClientSocket(int domain, int type, int protocol) {
     }
     unsigned netId = netIdForProcess;
     if (netId != NETID_UNSET && FwmarkClient::shouldSetFwmark(domain)) {
-        if (!setNetworkForSocket(netId, socketFd)) {
-            return closeFdAndRestoreErrno(socketFd);
+        int error = setNetworkForSocket(netId, socketFd);
+        if (error) {
+            return closeFdAndSetErrno(socketFd, error);
         }
     }
     return socketFd;
@@ -105,10 +108,10 @@ unsigned getNetworkForResolv(unsigned netId) {
     return netIdForResolv;
 }
 
-bool setNetworkForTarget(unsigned netId, std::atomic_uint* target) {
+int setNetworkForTarget(unsigned netId, std::atomic_uint* target) {
     if (netId == NETID_UNSET) {
         *target = netId;
-        return true;
+        return 0;
     }
     // Verify that we are allowed to use |netId|, by creating a socket and trying to have it marked
     // with the netId. Call libcSocket() directly; else the socket creation (via netdClientSocket())
@@ -120,14 +123,14 @@ bool setNetworkForTarget(unsigned netId, std::atomic_uint* target) {
         socketFd = socket(AF_INET6, SOCK_DGRAM, 0);
     }
     if (socketFd < 0) {
-        return false;
+        return errno;
     }
-    bool status = setNetworkForSocket(netId, socketFd);
-    closeFdAndRestoreErrno(socketFd);
-    if (status) {
+    int error = setNetworkForSocket(netId, socketFd);
+    if (!error) {
         *target = netId;
     }
-    return status;
+    close(socketFd);
+    return error;
 }
 
 }  // namespace
@@ -164,27 +167,25 @@ extern "C" unsigned getNetworkForProcess() {
     return netIdForProcess;
 }
 
-extern "C" bool setNetworkForSocket(unsigned netId, int socketFd) {
+extern "C" int setNetworkForSocket(unsigned netId, int socketFd) {
     if (socketFd < 0) {
-        errno = EBADF;
-        return false;
+        return EBADF;
     }
     FwmarkCommand command = {FwmarkCommand::SELECT_NETWORK, netId};
     return FwmarkClient().send(&command, sizeof(command), socketFd);
 }
 
-extern "C" bool setNetworkForProcess(unsigned netId) {
+extern "C" int setNetworkForProcess(unsigned netId) {
     return setNetworkForTarget(netId, &netIdForProcess);
 }
 
-extern "C" bool setNetworkForResolv(unsigned netId) {
+extern "C" int setNetworkForResolv(unsigned netId) {
     return setNetworkForTarget(netId, &netIdForResolv);
 }
 
-extern "C" bool protectFromVpn(int socketFd) {
+extern "C" int protectFromVpn(int socketFd) {
     if (socketFd < 0) {
-        errno = EBADF;
-        return false;
+        return EBADF;
     }
     FwmarkCommand command = {FwmarkCommand::PROTECT_FROM_VPN, 0};
     return FwmarkClient().send(&command, sizeof(command), socketFd);
index be24702..0b75d13 100644 (file)
 
 __BEGIN_DECLS
 
-bool setNetworkForSocket(unsigned netId, int socketFd);
+// All functions below that return an int return 0 on success or an errno value on failure.
+
+int setNetworkForSocket(unsigned netId, int socketFd);
 
 unsigned getNetworkForProcess(void);
-bool setNetworkForProcess(unsigned netId);
+int setNetworkForProcess(unsigned netId);
 
-bool setNetworkForResolv(unsigned netId);
+int setNetworkForResolv(unsigned netId);
 
-bool protectFromVpn(int socketFd);
+int protectFromVpn(int socketFd);
 
 __END_DECLS