From: Sebastian Harl Date: Tue, 11 Dec 2012 09:55:36 +0000 (+0100) Subject: utils unixsock: Added sc_unixsock_client_shutdown(). X-Git-Tag: sysdb-0.1.0~459 X-Git-Url: https://git.tokkee.org/?p=sysdb.git;a=commitdiff_plain;h=c56d3fd14df5efba97fa47b08d5ea7fe602f7c9a;ds=sidebyside utils unixsock: Added sc_unixsock_client_shutdown(). This function is a wrapper around shutdown(3). After shutting down send / receive operations, the client will automatically re-connect on the next send() / recv() call. --- diff --git a/src/include/utils/unixsock.h b/src/include/utils/unixsock.h index e51e4ac..0df0b71 100644 --- a/src/include/utils/unixsock.h +++ b/src/include/utils/unixsock.h @@ -28,6 +28,8 @@ #ifndef SC_UTILS_UNIXSOCK_H #define SC_UTILS_UNIXSOCK_H 1 +#include + #include #ifdef __cplusplus @@ -49,6 +51,17 @@ sc_unixsock_client_send(sc_unixsock_client_t *client, const char *msg); char * sc_unixsock_client_recv(sc_unixsock_client_t *client, char *buffer, size_t buflen); +/* + * sc_unixsock_client_shutdown: + * Shut down the client's send and/or receive operations. If appropriate, the + * client will automatically re-connect on the next send / receive operation + * after that. + * + * See shutdown(3) for details. + */ +int +sc_unixsock_client_shutdown(sc_unixsock_client_t *client, int how); + void sc_unixsock_client_destroy(sc_unixsock_client_t *client); diff --git a/src/utils/unixsock.c b/src/utils/unixsock.c index 70fd273..af1f2fe 100644 --- a/src/utils/unixsock.c +++ b/src/utils/unixsock.c @@ -46,8 +46,14 @@ 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 */ @@ -71,6 +77,8 @@ sc_unixsock_client_create(const char *path) sc_unixsock_client_destroy(client); return NULL; } + + client->shutdown = 0; return client; } /* sc_unixsock_client_create */ @@ -116,6 +124,8 @@ sc_unixsock_client_connect(sc_unixsock_client_t *client) close(fd); return -1; } + + client->shutdown = 0; 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->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,6 +156,9 @@ 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) { if (! feof(client->fh)) { @@ -162,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) {