Code

utils unixsock: Added sc_unixsock_client_shutdown().
[sysdb.git] / src / utils / unixsock.c
index 1be17b9994600878024a8f3b9a4c1a15d1e96eb4..af1f2fedaf4c6c5bd9c7fb253a0ce8baf856982f 100644 (file)
 struct sc_unixsock_client {
        char *path;
        FILE *fh;
 struct sc_unixsock_client {
        char *path;
        FILE *fh;
+
+       int shutdown;
 };
 
 };
 
+#define SC_SHUT_RD   (1 << SHUT_RD)
+#define SC_SHUT_WR   (1 << SHUT_WR)
+#define SC_SHUT_RDWR (SC_SHUT_RD | SC_SHUT_WR)
+
 /*
  * public API
  */
 /*
  * public API
  */
@@ -71,6 +77,8 @@ sc_unixsock_client_create(const char *path)
                sc_unixsock_client_destroy(client);
                return NULL;
        }
                sc_unixsock_client_destroy(client);
                return NULL;
        }
+
+       client->shutdown = 0;
        return client;
 } /* sc_unixsock_client_create */
 
        return client;
 } /* sc_unixsock_client_create */
 
@@ -116,6 +124,8 @@ sc_unixsock_client_connect(sc_unixsock_client_t *client)
                close(fd);
                return -1;
        }
                close(fd);
                return -1;
        }
+
+       client->shutdown = 0;
        return 0;
 } /* sc_unixsock_client_connect */
 
        return 0;
 } /* sc_unixsock_client_connect */
 
@@ -127,6 +137,9 @@ sc_unixsock_client_send(sc_unixsock_client_t *client, const char *msg)
        if ((! client) || (! client->fh))
                return -1;
 
        if ((! client) || (! client->fh))
                return -1;
 
+       if (client->shutdown & SC_SHUT_WR) /* reconnect */
+               sc_unixsock_client_connect(client);
+
        status = fprintf(client->fh, "%s\r\n", msg);
        if (status < 0) {
                char errbuf[1024];
        status = fprintf(client->fh, "%s\r\n", msg);
        if (status < 0) {
                char errbuf[1024];
@@ -143,11 +156,16 @@ sc_unixsock_client_recv(sc_unixsock_client_t *client, char *buffer, size_t bufle
        if ((! client) || (! client->fh) || (! buffer))
                return NULL;
 
        if ((! client) || (! client->fh) || (! buffer))
                return NULL;
 
+       if (client->shutdown & SC_SHUT_RD) /* reconnect */
+               sc_unixsock_client_connect(client);
+
        buffer = fgets(buffer, (int)buflen - 1, client->fh);
        buffer = fgets(buffer, (int)buflen - 1, client->fh);
-       if ((! buffer) && (! feof(client->fh))) {
-               char errbuf[1024];
-               fprintf(stderr, "unixsock: Failed to read from socket (%s): %s\n",
-                               client->path, sc_strerror(errno, errbuf, sizeof(errbuf)));
+       if (! buffer) {
+               if (! feof(client->fh)) {
+                       char errbuf[1024];
+                       fprintf(stderr, "unixsock: Failed to read from socket (%s): %s\n",
+                                       client->path, sc_strerror(errno, errbuf, sizeof(errbuf)));
+               }
                return buffer;
        }
        buffer[buflen - 1] = '\0';
                return buffer;
        }
        buffer[buflen - 1] = '\0';
@@ -160,6 +178,28 @@ sc_unixsock_client_recv(sc_unixsock_client_t *client, char *buffer, size_t bufle
        return buffer;
 } /* sc_unixsock_client_recv */
 
        return buffer;
 } /* sc_unixsock_client_recv */
 
+int
+sc_unixsock_client_shutdown(sc_unixsock_client_t *client, int how)
+{
+       int status;
+
+       if (! client) {
+               errno = ENOTSOCK;
+               return -1;
+       }
+
+       fflush(client->fh);
+       status = shutdown(fileno(client->fh), how);
+
+       if (! status) {
+               if (how == SHUT_RDWR)
+                       client->shutdown |= SC_SHUT_RDWR;
+               else
+                       client->shutdown |= 1 << how;
+       }
+       return status;
+} /* sc_unixsock_client_shutdown */
+
 void
 sc_unixsock_client_destroy(sc_unixsock_client_t *client)
 {
 void
 sc_unixsock_client_destroy(sc_unixsock_client_t *client)
 {