X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Futils%2Funixsock.c;h=75221716e2479585f310c0c1dd263321dbd2735f;hb=4bab2b402db650122d5338c47d27e47f814f5977;hp=b4b9772a0e9dbe1684abed2e7af3d8b9fad8fc06;hpb=a6bb88e99588be4c62aa7a81bfae643b3c1888fa;p=sysdb.git diff --git a/src/utils/unixsock.c b/src/utils/unixsock.c index b4b9772..7522171 100644 --- a/src/utils/unixsock.c +++ b/src/utils/unixsock.c @@ -25,9 +25,12 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "utils/unixsock.h" +#if HAVE_CONFIG_H +# include "config.h" +#endif /* HAVE_CONFIG_H */ + #include "utils/error.h" -#include "utils/string.h" +#include "utils/unixsock.h" #include #include @@ -88,59 +91,6 @@ sdb_unixsock_get_column_count(const char *string, const char *delim) return count; } /* sdb_unixsock_get_column_count */ -static int -sdb_unixsock_parse_cell(char *string, int type, sdb_data_t *data) -{ - char *endptr = NULL; - - switch (type) { - case SDB_TYPE_INTEGER: - errno = 0; - data->data.integer = strtoll(string, &endptr, 0); - break; - case SDB_TYPE_DECIMAL: - errno = 0; - data->data.decimal = strtod(string, &endptr); - break; - case SDB_TYPE_STRING: - data->data.string = string; - break; - case SDB_TYPE_DATETIME: - { - double datetime = strtod(string, &endptr); - data->data.datetime = DOUBLE_TO_SDB_TIME(datetime); - } - break; - case SDB_TYPE_BINARY: - /* we don't support any binary information containing 0-bytes */ - data->data.binary.length = strlen(string); - data->data.binary.datum = (const unsigned char *)string; - break; - default: - sdb_error_set(SDB_LOG_ERR, "unixsock: Unexpected type %i while " - "parsing query result.\n", type); - return -1; - } - - if ((type == SDB_TYPE_INTEGER) || (type == SDB_TYPE_DECIMAL) - || (type == SDB_TYPE_DATETIME)) { - if (errno || (string == endptr)) { - char errbuf[1024]; - sdb_error_set(SDB_LOG_ERR, "unixsock: Failed to parse string " - "'%s' as numeric value (type %i): %s\n", string, type, - sdb_strerror(errno, errbuf, sizeof(errbuf))); - return -1; - } - else if (endptr && (*endptr != '\0')) - sdb_error_set(SDB_LOG_WARNING, "unixsock: Ignoring garbage after " - "number while parsing numeric value (type %i): %s.\n", - type, endptr); - } - - data->type = type; - return 0; -} /* sdb_unixsock_parse_cell */ - static int sdb_unixsock_client_process_one_line(sdb_unixsock_client_t *client, char *line, sdb_unixsock_client_data_cb callback, @@ -157,10 +107,10 @@ sdb_unixsock_client_process_one_line(sdb_unixsock_client_t *client, for (i = 0; i < column_count; ++i) { char *next; - if (! line) { /* this must no happen */ - sdb_error_set(SDB_LOG_ERR, "unixsock: Unexpected EOL while " + if (! line) { /* this must not 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; } @@ -175,15 +125,25 @@ sdb_unixsock_client_process_one_line(sdb_unixsock_client_t *client, ++next; } - if (sdb_unixsock_parse_cell(line, - types ? types[i] : SDB_TYPE_STRING, &data[i])) - return -1; + if (types && (types[i] != SDB_TYPE_STRING)) { + if (sdb_data_parse(line, types[i], &data[i])) + return -1; + } + else { + /* Avoid a copy in common cases */ + data[i].type = SDB_TYPE_STRING; + data[i].data.string = line; + } line = next; } if (callback(client, (size_t)column_count, data, user_data)) return -1; + + for (i = 0; i < column_count; ++i) + if (types && (types[i] != SDB_TYPE_STRING)) + sdb_data_free_datum(&data[i]); return 0; } /* sdb_unixsock_client_process_one_line */ @@ -232,7 +192,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_error_set(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 +203,7 @@ sdb_unixsock_client_connect(sdb_unixsock_client_t *client) if (connect(fd, (struct sockaddr *)&sa, sizeof(sa))) { char errbuf[1024]; - sdb_error_set(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; @@ -252,13 +212,16 @@ sdb_unixsock_client_connect(sdb_unixsock_client_t *client) client->fh = fdopen(fd, "r+"); if (! client->fh) { char errbuf[1024]; - sdb_error_set(SDB_LOG_ERR, "unixsock: Failed to open I/O " - "stream for %s: %s\n", sa.sun_path, + sdb_log(SDB_LOG_ERR, "unixsock: Failed to open I/O " + "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 */ @@ -278,8 +241,8 @@ sdb_unixsock_client_send(sdb_unixsock_client_t *client, status = fprintf(client->fh, "%s\r\n", msg); if (status < 0) { char errbuf[1024]; - sdb_error_set(SDB_LOG_ERR, "unixsock: Failed to write to " - "socket (%s): %s\n", client->path, + sdb_log(SDB_LOG_ERR, "unixsock: Failed to write to " + "socket (%s): %s", client->path, sdb_strerror(errno, errbuf, sizeof(errbuf))); return status; } @@ -290,26 +253,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_error_set(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; } @@ -341,9 +313,9 @@ sdb_unixsock_client_process_lines(sdb_unixsock_client_t *client, types[i] = va_arg(ap, int); if ((types[i] < 1) || (types[i] > SDB_TYPE_BINARY)) { - sdb_error_set(SDB_LOG_ERR, "unixsock: Unknown column " + 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; @@ -374,10 +346,10 @@ sdb_unixsock_client_process_lines(sdb_unixsock_client_t *client, column_count = sdb_unixsock_get_column_count(line, delim); if ((n_cols >= 0) && (n_cols != column_count)) { - sdb_error_set(SDB_LOG_ERR, "unixsock: number of columns (%i) " + 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; } @@ -395,8 +367,8 @@ sdb_unixsock_client_process_lines(sdb_unixsock_client_t *client, || ((max_lines < 0) && (! sdb_unixsock_client_eof(client))) || sdb_unixsock_client_error(client)) { char errbuf[1024]; - sdb_error_set(SDB_LOG_ERR, "unixsock: Unexpected end of data while " - "reading from socket (%s): %s\n", client->path, + sdb_log(SDB_LOG_ERR, "unixsock: Unexpected end of data while " + "reading from socket (%s): %s", client->path, sdb_strerror(errno, errbuf, sizeof(errbuf))); return -1; }