Improve starting/stopping tincd using tincctl.
[tinc] / src / tincctl.c
index eaf676d..a771b0e 100644 (file)
@@ -687,8 +687,19 @@ static bool remove_service(void) {
 #endif
 
 static bool connect_tincd(bool verbose) {
-       if(fd >= 0)
-               return true;
+       if(fd >= 0) {
+               fd_set r;
+               FD_ZERO(&r);
+               FD_SET(fd, &r);
+               struct timeval tv = {0, 0};
+               if(select(fd + 1, &r, NULL, NULL, &tv)) {
+                       fprintf(stderr, "Previous connection to tincd lost, reconnecting.\n");
+                       close(fd);
+                       fd = -1;
+               } else {
+                       return true;
+               }
+       }
 
        FILE *f = fopen(pidfilename, "r");
        if(!f) {
@@ -751,6 +762,8 @@ static bool connect_tincd(bool verbose) {
        if(connect(fd, res->ai_addr, res->ai_addrlen) < 0) {
                if(verbose)
                        fprintf(stderr, "Cannot connect to %s port %s: %s\n", host, port, sockstrerror(sockerrno));
+               close(fd);
+               fd = -1;
                return false;
        }
 
@@ -762,6 +775,8 @@ static bool connect_tincd(bool verbose) {
        if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %s %d", &code, data, &version) != 3 || code != 0) {
                if(verbose)
                        fprintf(stderr, "Cannot read greeting from control socket: %s\n", sockstrerror(sockerrno));
+               close(fd);
+               fd = -1;
                return false;
        }
 
@@ -770,6 +785,8 @@ static bool connect_tincd(bool verbose) {
        if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &version, &pid) != 3 || code != 4 || version != TINC_CTL_VERSION_CURRENT) {
                if(verbose)
                        fprintf(stderr, "Could not fully establish control socket connection\n");
+               close(fd);
+               fd = -1;
                return false;
        }
 
@@ -800,9 +817,10 @@ static int cmd_start(int argc, char *argv[]) {
                c = "tincd";
 
        int nargc = 0;
-       char **nargv = xmalloc_and_zero((orig_argc + argc) * sizeof *nargv);
+       char **nargv = xmalloc_and_zero((optind + argc) * sizeof *nargv);
 
-       for(int i = 0; i < orig_argc; i++)
+       nargv[nargc++] = c;
+       for(int i = 1; i < optind; i++)
                nargv[nargc++] = orig_argv[i];
        for(int i = 1; i < argc; i++)
                nargv[nargc++] = argv[i];
@@ -835,9 +853,13 @@ static int cmd_stop(int argc, char *argv[]) {
 #ifndef HAVE_MINGW
        if(!connect_tincd(true)) {
                if(pid) {
-                       if(kill(pid, SIGTERM)) 
+                       if(kill(pid, SIGTERM)) {
+                               fprintf(stderr, "Could not send TERM signal to process with PID %u: %s\n", pid, strerror(errno));
                                return 1;
+                       }
+
                        fprintf(stderr, "Sent TERM signal to process with PID %u.\n", pid);
+                       waitpid(pid, NULL, 0);
                        return 0;
                }
 
@@ -849,6 +871,12 @@ static int cmd_stop(int argc, char *argv[]) {
                fprintf(stderr, "Could not stop tinc daemon.\n");
                return 1;
        }
+
+       // Wait for tincd to close the connection...
+       fd_set r;
+       FD_ZERO(&r);
+       FD_SET(fd, &r);
+       select(fd + 1, &r, NULL, NULL, NULL);
 #else
        if(!remove_service())
                return 1;
@@ -2020,7 +2048,6 @@ static int cmd_shell(int argc, char *argv[]) {
        char *line = NULL;
        int maxargs = argc + 16;
        char **nargv = xmalloc(maxargs * sizeof *nargv);
-       optind = argc;
 
        for(int i = 0; i < argc; i++)
                nargv[i] = argv[i];