summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 00e2b37)
raw | patch | inline | side by side (parent: 00e2b37)
author | Benjamin Gilbert <bgilbert@cs.cmu.edu> | |
Tue, 3 Jun 2014 20:15:24 +0000 (16:15 -0400) | ||
committer | Benjamin Gilbert <bgilbert@backtick.net> | |
Mon, 19 Sep 2016 06:35:12 +0000 (01:35 -0500) |
Dynamically scale the response buffer, up to a maximum of 1 MB.
src/hddtemp.c | patch | blob | history |
diff --git a/src/hddtemp.c b/src/hddtemp.c
index 4840e14a8b4a865c4ae7c34cbd874903695d6801..4e275dc87c8193ac4ab121dbe4fdb49594eb6c9a 100644 (file)
--- a/src/hddtemp.c
+++ b/src/hddtemp.c
# include <netinet/in.h>
# include <netinet/tcp.h>
# include <libgen.h> /* for basename */
+# include <assert.h>
#if HAVE_LINUX_MAJOR_H
# include <linux/major.h>
#define HDDTEMP_DEF_HOST "127.0.0.1"
#define HDDTEMP_DEF_PORT "7634"
+#define HDDTEMP_MAX_RECV_BUF (1 << 20)
static const char *config_keys[] =
{
* we need to create a new socket each time. Is there another way?
* Hm, maybe we can re-use the `sockaddr' structure? -octo
*/
-static int hddtemp_query_daemon (char *buffer, int buffer_size)
+static char *hddtemp_query_daemon (void)
{
int fd;
ssize_t status;
+
+ char *buffer;
+ int buffer_size;
int buffer_fill;
+ char *new_buffer;
const char *host;
const char *port;
(ai_return == EAI_SYSTEM)
? sstrerror (errno, errbuf, sizeof (errbuf))
: gai_strerror (ai_return));
- return (-1);
+ return (NULL);
}
fd = -1;
if (fd < 0)
{
ERROR ("hddtemp plugin: Could not connect to daemon.");
- return (-1);
+ return (NULL);
}
/* receive data from the hddtemp daemon */
- memset (buffer, '\0', buffer_size);
-
+ buffer = NULL;
+ buffer_size = 0;
buffer_fill = 0;
- while ((status = read (fd, buffer + buffer_fill, buffer_size - buffer_fill)) != 0)
+ while (1)
{
- if (status == -1)
+ if (buffer_fill >= buffer_size - 1)
+ {
+ if (buffer_size == 0)
+ buffer_size = 1024;
+ else
+ buffer_size *= 2;
+ if (buffer_size > HDDTEMP_MAX_RECV_BUF)
+ {
+ WARNING ("hddtemp plugin: Message from hddtemp has been "
+ "truncated.");
+ break;
+ }
+ new_buffer = realloc (buffer, buffer_size);
+ if (new_buffer == NULL) {
+ close (fd);
+ free (buffer);
+ ERROR ("hddtemp plugin: Allocation failed.");
+ return (NULL);
+ }
+ buffer = new_buffer;
+ }
+ status = read (fd, buffer + buffer_fill, buffer_size - buffer_fill - 1);
+ if (status == 0) {
+ break;
+ }
+ else if (status == -1)
{
char errbuf[1024];
ERROR ("hddtemp plugin: Error reading from socket: %s",
sstrerror (errno, errbuf, sizeof (errbuf)));
close (fd);
- return (-1);
+ free (buffer);
+ return (NULL);
}
buffer_fill += status;
-
- if (buffer_fill >= buffer_size)
- break;
}
- if (buffer_fill >= buffer_size)
- {
- buffer[buffer_size - 1] = '\0';
- WARNING ("hddtemp plugin: Message from hddtemp has been "
- "truncated.");
- }
- else if (buffer_fill == 0)
+ if (buffer_fill == 0)
{
WARNING ("hddtemp plugin: Peer has unexpectedly shut down "
"the socket. Buffer: `%s'", buffer);
close (fd);
- return (-1);
+ free (buffer);
+ return (NULL);
}
+ assert (buffer_fill < buffer_size);
+ buffer[buffer_fill] = '\0';
close (fd);
- return (0);
+ return (buffer);
}
static int hddtemp_config (const char *key, const char *value)
static int hddtemp_read (void)
{
- char buf[1024];
+ char *buf;
char *ptr;
char *saveptr;
char *name;
char *mode;
/* get data from daemon */
- if (hddtemp_query_daemon (buf, sizeof (buf)) < 0)
+ buf = hddtemp_query_daemon ();
+ if (buf == NULL)
return (-1);
/* NB: strtok_r will eat up "||" and leading "|"'s */
hddtemp_submit (name, temperature_value);
}
+ free (buf);
return (0);
} /* int hddtemp_read */