diff --git a/src/utils/unixsock.c b/src/utils/unixsock.c
index 08233f8fb23f757a987422e73cd99f5d3dd58817..75221716e2479585f310c0c1dd263321dbd2735f 100644 (file)
--- a/src/utils/unixsock.c
+++ b/src/utils/unixsock.c
* 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 <assert.h>
#include <errno.h>
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_log(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_log(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_log(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,
for (i = 0; i < column_count; ++i) {
char *next;
- if (! line) { /* this must no happen */
+ 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;
}
++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 */
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;
}
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;
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 */
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;
}
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;
}
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;
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;
}
|| 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;
}