Add defence code to handle socket write failure 95/141795/3
authorMu-Woong Lee <muwoong.lee@samsung.com>
Tue, 1 Aug 2017 11:31:11 +0000 (20:31 +0900)
committerMu-Woong Lee <muwoong.lee@samsung.com>
Wed, 2 Aug 2017 02:50:17 +0000 (11:50 +0900)
Change-Id: Ia31d1b138fefb8bb89d61ad9515b9eca2918ed61
Signed-off-by: Mu-Woong Lee <muwoong.lee@samsung.com>
src/server/AgentCommander.cpp

index 916a2e6..56a9104 100644 (file)
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <errno.h>
 #include <fcntl.h>
 #include <sys/socket.h>
 #include <sys/un.h>
@@ -36,26 +37,45 @@ AgentCommander::~AgentCommander()
 
 bool AgentCommander::send(uint16_t id, uint8_t length, const void* command)
 {
-       IF_FAIL_RETURN(length <= CTX_AGENT_COMMAND_LIMIT, false);
+       IF_FAIL_RETURN(length > 0 && length <= CTX_AGENT_COMMAND_LIMIT, false);
 
        if (!__init()) {
                __release();
                return false;
        }
 
-       //TODO: handle the degeneracy case failed to write all input data
-
-       int sent = 0;
-
-       sent += write(__sockFd, &id, sizeof(id));
-       sent += write(__sockFd, &length, sizeof(length));
-       sent += write(__sockFd, command, length);
+       auto safeWrite = [this](const char* buf, size_t count)->bool {
+               do {
+                       int sent = write(__sockFd, buf, count);
+                       if (sent < 0) {
+                               if (errno == EAGAIN) {
+                                       continue;
+                               } else {
+                                       _E("Socket write error: %d", errno);
+                                       return false;
+                               }
+                       }
+                       count -= sent;
+                       buf += sent;
+               } while (count > 0);
+               return true;
+       };
+
+       bool success;
+
+       success = safeWrite(reinterpret_cast<const char*>(&id), sizeof(id));
+       IF_FAIL_RETURN(success, false);
+
+       success = safeWrite(reinterpret_cast<const char*>(&length), sizeof(length));
+       IF_FAIL_RETURN(success, false);
+
+       success = safeWrite(reinterpret_cast<const char*>(command), length);
+       IF_FAIL_RETURN(success, false);
 
        __release();
 
-       _D("Given: %u bytes, Sent: %d bytes", sizeof(id) + sizeof(length) + length, sent);
-
-       return (sizeof(id) + sizeof(length) + length == static_cast<unsigned>(sent));
+       _D("Sent");
+       return true;
 }
 
 bool AgentCommander::__init()