diff --git a/src/utils/unixsock.c b/src/utils/unixsock.c
index 1be17b9994600878024a8f3b9a4c1a15d1e96eb4..af1f2fedaf4c6c5bd9c7fb253a0ce8baf856982f 100644 (file)
--- a/src/utils/unixsock.c
+++ b/src/utils/unixsock.c
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
*/
sc_unixsock_client_destroy(client);
return NULL;
}
+
+ client->shutdown = 0;
return client;
} /* sc_unixsock_client_create */
close(fd);
return -1;
}
+
+ client->shutdown = 0;
return 0;
} /* sc_unixsock_client_connect */
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];
@@ -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->shutdown & SC_SHUT_RD) /* reconnect */
+ sc_unixsock_client_connect(client);
+
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';
@@ -160,6 +178,28 @@ sc_unixsock_client_recv(sc_unixsock_client_t *client, char *buffer, size_t bufle
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)
{