X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fcommon.c;h=4da8feee853ce3ac525157884371a01e7f744ea3;hb=1122c8fd30065b5990a5b798b7bfd8891736def9;hp=efd63c085452f7ba238247e1caade93d4bb35ac0;hpb=b6fbfb1b864be53e71d755fba59d633f5c30da7e;p=collectd.git diff --git a/src/common.c b/src/common.c index efd63c08..4da8feee 100644 --- a/src/common.c +++ b/src/common.c @@ -44,6 +44,8 @@ #include #include +#include + #if HAVE_NETINET_IN_H # include #endif @@ -265,9 +267,23 @@ ssize_t swrite (int fd, const void *buf, size_t count) const char *ptr; size_t nleft; ssize_t status; + struct pollfd pfd; ptr = (const char *) buf; nleft = count; + + /* checking for closed peer connection */ + pfd.fd = fd; + pfd.events = POLLIN | POLLHUP; + pfd.revents = 0; + if (poll(&pfd, 1, 0) > 0) { + char buffer[32]; + if (recv(fd, buffer, sizeof(buffer), MSG_PEEK | MSG_DONTWAIT) == 0) { + // if recv returns zero (even though poll() said there is data to be read), + // that means the connection has been closed + return -1; + } + } while (nleft > 0) { @@ -307,44 +323,51 @@ int strsplit (char *string, char **fields, size_t size) return ((int) i); } -int strjoin (char *dst, size_t dst_len, +int strjoin (char *buffer, size_t buffer_size, char **fields, size_t fields_num, const char *sep) { - size_t field_len; + size_t avail; + char *ptr; size_t sep_len; - int i; - - memset (dst, '\0', dst_len); + size_t i; - if (fields_num <= 0) + if ((buffer_size < 1) || (fields_num <= 0)) return (-1); + memset (buffer, 0, buffer_size); + ptr = buffer; + avail = buffer_size - 1; + sep_len = 0; if (sep != NULL) sep_len = strlen (sep); - for (i = 0; i < (int)fields_num; i++) + for (i = 0; i < fields_num; i++) { + size_t field_len; + if ((i > 0) && (sep_len > 0)) { - if (dst_len <= sep_len) + if (avail < sep_len) return (-1); - strncat (dst, sep, dst_len); - dst_len -= sep_len; + memcpy (ptr, sep, sep_len); + ptr += sep_len; + avail -= sep_len; } field_len = strlen (fields[i]); - - if (dst_len <= field_len) + if (avail < field_len) return (-1); - strncat (dst, fields[i], dst_len); - dst_len -= field_len; + memcpy (ptr, fields[i], field_len); + ptr += field_len; + avail -= field_len; } - return (strlen (dst)); + assert (buffer[buffer_size - 1] == 0); + return (strlen (buffer)); } int strsubstitute (char *str, char c_from, char c_to) @@ -438,7 +461,7 @@ int escape_slashes (char *buf, int buf_len) if (buf[0] == '/') memmove (buf, buf + 1, buf_len - 1); - for (i = 0; i < buf_len - 1; i++) + for (i = 0; i < buf_len; i++) { if (buf[i] == '\0') break; @@ -1081,6 +1104,9 @@ int parse_values (char *buffer, value_list_t *vl, const data_set_t *ds) char *ptr; char *saveptr; + if ((buffer == NULL) || (vl == NULL) || (ds == NULL)) + return EINVAL; + i = -1; dummy = buffer; saveptr = NULL;