Refactoring in utilities.
authorDavin McCall <davmac@davmac.org>
Tue, 13 Feb 2018 18:14:29 +0000 (18:14 +0000)
committerDavin McCall <davmac@davmac.org>
Tue, 13 Feb 2018 18:14:29 +0000 (18:14 +0000)
src/dinitctl.cc
src/includes/dinit-client.h
src/shutdown.cc

index 359ea55561d23141a0f51ecbc038bbd69040a5dd..6be9da9c9541ec9f61d9f401ab1693d5d1c19efa 100644 (file)
@@ -290,41 +290,30 @@ static int start_stop_service(int socknum, cpbuffer_t &rbuffer, const char *serv
     service_state_t wanted_state = do_stop ? service_state_t::STOPPED : service_state_t::STARTED;
     int pcommand = 0;
     switch (command) {
-    case command_t::STOP_SERVICE:
-        pcommand = DINIT_CP_STOPSERVICE;
-        break;
-    case command_t::RELEASE_SERVICE:
-        pcommand = DINIT_CP_RELEASESERVICE;
-        break;
-    case command_t::START_SERVICE:
-        pcommand = DINIT_CP_STARTSERVICE;
-        break;
-    case command_t::WAKE_SERVICE:
-        pcommand = DINIT_CP_WAKESERVICE;
-        break;
-    default: ;
+        case command_t::STOP_SERVICE:
+            pcommand = DINIT_CP_STOPSERVICE;
+            break;
+        case command_t::RELEASE_SERVICE:
+            pcommand = DINIT_CP_RELEASESERVICE;
+            break;
+        case command_t::START_SERVICE:
+            pcommand = DINIT_CP_STARTSERVICE;
+            break;
+        case command_t::WAKE_SERVICE:
+            pcommand = DINIT_CP_WAKESERVICE;
+            break;
+        default: ;
     }
 
     // Need to issue STOPSERVICE/STARTSERVICE
     // We'll do this regardless of the current service state / target state, since issuing
     // start/stop also sets or clears the "explicitly started" flag on the service.
     {
-        int r;
-        
-        {
-            auto buf = new char[2 + sizeof(handle)];
-            unique_ptr<char[]> ubuf(buf);
-
-            buf[0] = pcommand;
-            buf[1] = do_pin ? 1 : 0;
-            memcpy(buf + 2, &handle, sizeof(handle));
-            r = write_all(socknum, buf, 2 + sizeof(handle));
-        }
-        
-        if (r == -1) {
-            perror("dinitctl: write");
-            return 1;
-        }
+        char buf[2 + sizeof(handle)];
+        buf[0] = pcommand;
+        buf[1] = do_pin ? 1 : 0;
+        memcpy(buf + 2, &handle, sizeof(handle));
+        write_all_x(socknum, buf, 2 + sizeof(handle));
         
         wait_for_reply(rbuffer, socknum);
         if (rbuffer[0] == DINIT_RP_ALREADYSS) {
@@ -419,27 +408,15 @@ static int issue_load_service(int socknum, const char *service_name, bool find_o
     // Build buffer;
     uint16_t sname_len = strlen(service_name);
     int bufsize = 3 + sname_len;
-    int r;
     
-    try {
-        std::unique_ptr<char[]> ubuf(new char[bufsize]);
-        auto buf = ubuf.get();
-        
-        buf[0] = find_only ? DINIT_CP_FINDSERVICE : DINIT_CP_LOADSERVICE;
-        memcpy(buf + 1, &sname_len, 2);
-        memcpy(buf + 3, service_name, sname_len);
-        
-        r = write_all(socknum, buf, bufsize);
-    }
-    catch (std::bad_alloc &badalloc) {
-        std::cerr << "dinitctl: " << badalloc.what() << std::endl;
-        return 1;
-    }
-    
-    if (r == -1) {
-        perror("dinitctl: write");
-        return 1;
-    }
+    std::unique_ptr<char[]> ubuf(new char[bufsize]);
+    auto buf = ubuf.get();
+
+    buf[0] = find_only ? DINIT_CP_FINDSERVICE : DINIT_CP_LOADSERVICE;
+    memcpy(buf + 1, &sname_len, 2);
+    memcpy(buf + 3, service_name, sname_len);
+
+    write_all_x(socknum, buf, bufsize);
     
     return 0;
 }
@@ -488,20 +465,10 @@ static int unpin_service(int socknum, cpbuffer_t &rbuffer, const char *service_n
 
     // Issue UNPIN command.
     {
-        int r;
-        
-        {
-            char *buf = new char[1 + sizeof(handle)];
-            unique_ptr<char[]> ubuf(buf);
-            buf[0] = DINIT_CP_UNPINSERVICE;
-            memcpy(buf + 1, &handle, sizeof(handle));
-            r = write_all(socknum, buf, 2 + sizeof(handle));
-        }
-        
-        if (r == -1) {
-            perror("dinitctl: write");
-            return 1;
-        }
+        char buf[1 + sizeof(handle)];
+        buf[0] = DINIT_CP_UNPINSERVICE;
+        memcpy(buf + 1, &handle, sizeof(handle));
+        write_all_x(socknum, buf, 2 + sizeof(handle));
         
         wait_for_reply(rbuffer, socknum);
         if (rbuffer[0] != DINIT_RP_ACK) {
@@ -538,20 +505,10 @@ static int unload_service(int socknum, cpbuffer_t &rbuffer, const char *service_
 
     // Issue UNLOAD command.
     {
-        int r;
-
-        {
-            char *buf = new char[1 + sizeof(handle)];
-            unique_ptr<char[]> ubuf(buf);
-            buf[0] = DINIT_CP_UNLOADSERVICE;
-            memcpy(buf + 1, &handle, sizeof(handle));
-            r = write_all(socknum, buf, 2 + sizeof(handle));
-        }
-
-        if (r == -1) {
-            perror("dinitctl: write");
-            return 1;
-        }
+        char buf[1 + sizeof(handle)];
+        buf[0] = DINIT_CP_UNLOADSERVICE;
+        memcpy(buf + 1, &handle, sizeof(handle));
+        write_all_x(socknum, buf, 2 + sizeof(handle));
 
         wait_for_reply(rbuffer, socknum);
         if (rbuffer[0] == DINIT_RP_NAK) {
@@ -575,12 +532,7 @@ static int list_services(int socknum, cpbuffer_t &rbuffer)
     using namespace std;
     
     char cmdbuf[] = { (char)DINIT_CP_LISTSERVICES };
-    int r = write_all(socknum, cmdbuf, 1);
-
-    if (r == -1) {
-        perror("dinitctl: write");
-        return 1;
-    }
+    write_all_x(socknum, cmdbuf, 1);
 
     wait_for_reply(rbuffer, socknum);
     while (rbuffer[0] == DINIT_RP_SVCINFO) {
@@ -643,11 +595,7 @@ static int shutdown_dinit(int socknum, cpbuffer_t &rbuffer)
     buf[0] = DINIT_CP_SHUTDOWN;
     buf[1] = static_cast<char>(shutdown_type_t::HALT);
 
-    int r = write_all(socknum, buf, bufsize);
-    if (r == -1) {
-        perror("write");
-        return 1;
-    }
+    write_all_x(socknum, buf, bufsize);
 
     wait_for_reply(rbuffer, socknum);
 
index e40ad6ddf39d07db959540d9a0b01054a2175bc4..0fff4a42310d0051592dbf814a6a4e5765577a89 100644 (file)
@@ -104,20 +104,25 @@ inline int write_all(int fd, const void *buf, size_t count)
     return w;
 }
 
+// Write all the requested buffer, and throw an exception on failure.
+inline void write_all_x(int fd, const void *buf, size_t count)
+{
+    if (write_all(fd, buf, count) == -1) {
+        throw cp_write_exception(errno);
+    }
+}
+
 // Check the protocol version is compatible with the client.
 //   minverison - minimum protocol version that client can speak
 //   version - maximum protocol version that client can speak
 //   rbuffer, fd -  communication buffer and socket
 // returns: the actual protocol version
 // throws an exception on protocol mismatch or error.
-uint16_t check_protocol_version(int minversion, int version, cpbuffer_t &rbuffer, int fd)
+inline uint16_t check_protocol_version(int minversion, int version, cpbuffer_t &rbuffer, int fd)
 {
     constexpr int bufsize = 1;
     char buf[bufsize] = { DINIT_CP_QUERYVERSION };
-    int r = write_all(fd, buf, bufsize);
-    if (r == -1) {
-        throw cp_write_exception(errno);
-    }
+    write_all_x(fd, buf, bufsize);
 
     wait_for_reply(rbuffer, fd);
     if (rbuffer[0] != DINIT_RP_CPVERSION) {
index 886826b52bec1af88efb3c30f4a7c20c7b244498..6ba4416e42abffbf3c2e96363c58f0768484b080 100644 (file)
@@ -131,29 +131,24 @@ int main(int argc, char **argv)
         }
     }
 
-    // Build buffer;
-    constexpr int bufsize = 2;
-    char buf[bufsize];
-    
-    buf[0] = DINIT_CP_SHUTDOWN;
-    buf[1] = static_cast<char>(shutdown_type);
-    
-    cout << "Issuing shutdown command..." << endl;
-    
-    int r = write_all(socknum, buf, bufsize);
-    if (r == -1) {
-        perror("write");
-        return 1;
-    }
+    try {
+        cpbuffer_t rbuffer;
     
-    // Wait for ACK/NACK
-    // r = read(socknum, buf, 1);
-    //if (r > 0) {
-    //    cout << "Received acknowledgement. System should now shut down." << endl;
-    //}
+        check_protocol_version(0, 0, rbuffer, socknum);
+
+        // Build buffer;
+        constexpr int bufsize = 2;
+        char buf[bufsize];
+
+        buf[0] = DINIT_CP_SHUTDOWN;
+        buf[1] = static_cast<char>(shutdown_type);
+
+        cout << "Issuing shutdown command..." << endl;
+
+        write_all_x(socknum, buf, bufsize);
+
+        // Wait for ACK/NACK
     
-    cpbuffer<1024> rbuffer;
-    try {
         wait_for_reply(rbuffer, socknum);
         
         if (rbuffer[0] != DINIT_RP_ACK) {
@@ -161,9 +156,20 @@ int main(int argc, char **argv)
             return 1;
         }
     }
-    catch (cp_read_exception &exc)
-    {
-        cerr << "shutdown: control socket read failure or protocol error" << endl;    
+    catch (cp_old_client_exception &e) {
+        std::cerr << "shutdown: too old (server reports newer protocol version)" << std::endl;
+        return 1;
+    }
+    catch (cp_old_server_exception &e) {
+        std::cerr << "shutdown: server too old or protocol error" << std::endl;
+        return 1;
+    }
+    catch (cp_read_exception &e) {
+        cerr << "shutdown: control socket read failure or protocol error" << endl;
+        return 1;
+    }
+    catch (cp_write_exception &e) {
+        cerr << "shutdown: control socket write error: " << std::strerror(e.errcode) << endl;
         return 1;
     }