Code

Fixed memory errors identified by LLVM's AddressSanitizer.
[sysdb.git] / src / utils / unixsock.c
index 08233f8fb23f757a987422e73cd99f5d3dd58817..62b6f45aa404f360ed1f623c07362dcb2c2e26b0 100644 (file)
@@ -25,9 +25,8 @@
  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "utils/unixsock.h"
 #include "utils/error.h"
-#include "utils/string.h"
+#include "utils/unixsock.h"
 
 #include <assert.h>
 #include <errno.h>
@@ -118,7 +117,7 @@ sdb_unixsock_parse_cell(char *string, int type, sdb_data_t *data)
                        break;
                default:
                        sdb_log(SDB_LOG_ERR, "unixsock: Unexpected type %i while "
-                                       "parsing query result.\n", type);
+                                       "parsing query result.", type);
                        return -1;
        }
 
@@ -127,13 +126,13 @@ sdb_unixsock_parse_cell(char *string, int type, sdb_data_t *data)
                if (errno || (string == endptr)) {
                        char errbuf[1024];
                        sdb_log(SDB_LOG_ERR, "unixsock: Failed to parse string "
-                                       "'%s' as numeric value (type %i): %s\n", string, type,
+                                       "'%s' as numeric value (type %i): %s", string, type,
                                        sdb_strerror(errno, errbuf, sizeof(errbuf)));
                        return -1;
                }
                else if (endptr && (*endptr != '\0'))
                        sdb_log(SDB_LOG_WARNING, "unixsock: Ignoring garbage after "
-                                       "number while parsing numeric value (type %i): %s.\n",
+                                       "number while parsing numeric value (type %i): %s.",
                                        type, endptr);
        }
 
@@ -160,7 +159,7 @@ sdb_unixsock_client_process_one_line(sdb_unixsock_client_t *client,
                if (! line) { /* this must no happen */
                        sdb_log(SDB_LOG_ERR, "unixsock: Unexpected EOL while "
                                        "parsing line (expected %i columns delimited by '%s'; "
-                                       "got %i): %s\n", column_count, delim,
+                                       "got %i): %s", column_count, delim,
                                        /* last line number */ i, orig_line);
                        return -1;
                }
@@ -232,7 +231,7 @@ sdb_unixsock_client_connect(sdb_unixsock_client_t *client)
        fd = socket(AF_UNIX, SOCK_STREAM, /* protocol = */ 0);
        if (fd < 0) {
                char errbuf[1024];
-               sdb_log(SDB_LOG_ERR, "unixsock: Failed to open socket: %s\n",
+               sdb_log(SDB_LOG_ERR, "unixsock: Failed to open socket: %s",
                                sdb_strerror(errno, errbuf, sizeof(errbuf)));
                return -1;
        }
@@ -243,7 +242,7 @@ sdb_unixsock_client_connect(sdb_unixsock_client_t *client)
 
        if (connect(fd, (struct sockaddr *)&sa, sizeof(sa))) {
                char errbuf[1024];
-               sdb_log(SDB_LOG_ERR, "unixsock: Failed to connect to %s: %s\n",
+               sdb_log(SDB_LOG_ERR, "unixsock: Failed to connect to %s: %s",
                                sa.sun_path, sdb_strerror(errno, errbuf, sizeof(errbuf)));
                close(fd);
                return -1;
@@ -253,12 +252,15 @@ sdb_unixsock_client_connect(sdb_unixsock_client_t *client)
        if (! client->fh) {
                char errbuf[1024];
                sdb_log(SDB_LOG_ERR, "unixsock: Failed to open I/O "
-                               "stream for %s: %s\n", sa.sun_path,
+                               "stream for %s: %s", sa.sun_path,
                                sdb_strerror(errno, errbuf, sizeof(errbuf)));
                close(fd);
                return -1;
        }
 
+       /* enable line-buffering */
+       setvbuf(client->fh, NULL, _IOLBF, 0);
+
        client->shutdown = 0;
        return 0;
 } /* sdb_unixsock_client_connect */
@@ -279,7 +281,7 @@ sdb_unixsock_client_send(sdb_unixsock_client_t *client,
        if (status < 0) {
                char errbuf[1024];
                sdb_log(SDB_LOG_ERR, "unixsock: Failed to write to "
-                               "socket (%s): %s\n", client->path,
+                               "socket (%s): %s", client->path,
                                sdb_strerror(errno, errbuf, sizeof(errbuf)));
                return status;
        }
@@ -290,26 +292,35 @@ char *
 sdb_unixsock_client_recv(sdb_unixsock_client_t *client,
                char *buffer, size_t buflen)
 {
+       char *tmp;
+
        if ((! client) || (! client->fh) || (! buffer))
                return NULL;
 
        if (client->shutdown & SDB_SHUT_RD) /* reconnect */
                sdb_unixsock_client_connect(client);
 
-       buffer = fgets(buffer, (int)buflen - 1, client->fh);
-       if (! buffer) {
-               if (! feof(client->fh)) {
-                       char errbuf[1024];
-                       sdb_log(SDB_LOG_ERR, "unixsock: Failed to read "
-                                       "from socket (%s): %s\n", client->path,
-                                       sdb_strerror(errno, errbuf, sizeof(errbuf)));
+       tmp = NULL;
+       while (tmp == NULL) {
+               errno = 0;
+               tmp = fgets(buffer, (int)buflen - 1, client->fh);
+               if (! tmp) {
+                       if ((errno == EAGAIN) || (errno == EINTR))
+                               continue;
+
+                       if (! feof(client->fh)) {
+                               char errbuf[1024];
+                               sdb_log(SDB_LOG_ERR, "unixsock: Failed to read "
+                                               "from socket (%s): %s", client->path,
+                                               sdb_strerror(errno, errbuf, sizeof(errbuf)));
+                       }
+                       return NULL;
                }
-               return buffer;
        }
        buffer[buflen - 1] = '\0';
 
        buflen = strlen(buffer);
-       while ((buffer[buflen - 1] == '\n') || (buffer[buflen - 1] == '\r')) {
+       while (buflen && ((buffer[buflen - 1] == '\n') || (buffer[buflen - 1] == '\r'))) {
                buffer[buflen - 1] = '\0';
                --buflen;
        }
@@ -343,7 +354,7 @@ sdb_unixsock_client_process_lines(sdb_unixsock_client_t *client,
                        if ((types[i] < 1) || (types[i] > SDB_TYPE_BINARY)) {
                                sdb_log(SDB_LOG_ERR, "unixsock: Unknown column "
                                                "type %i while processing response from the "
-                                               "UNIX socket @ %s.\n", types[i], client->path);
+                                               "UNIX socket @ %s.", types[i], client->path);
                                va_end(ap);
                                free(types);
                                return -1;
@@ -376,8 +387,8 @@ sdb_unixsock_client_process_lines(sdb_unixsock_client_t *client,
                if ((n_cols >= 0) && (n_cols != column_count)) {
                        sdb_log(SDB_LOG_ERR, "unixsock: number of columns (%i) "
                                        "does not match the number of requested columns (%i) "
-                                       "while processing response from the UNIX socket @ %s: "
-                                       "%s\n", column_count, n_cols, client->path, line);
+                                       "while processing response from the UNIX socket @ %s: %s",
+                                       column_count, n_cols, client->path, line);
                        continue;
                }
 
@@ -396,7 +407,7 @@ sdb_unixsock_client_process_lines(sdb_unixsock_client_t *client,
                        || sdb_unixsock_client_error(client)) {
                char errbuf[1024];
                sdb_log(SDB_LOG_ERR, "unixsock: Unexpected end of data while "
-                               "reading from socket (%s): %s\n", client->path,
+                               "reading from socket (%s): %s", client->path,
                                sdb_strerror(errno, errbuf, sizeof(errbuf)));
                return -1;
        }