Browse Source

Handle EINTR in mod_rrdtool (fixes #604)

git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2400 152afb58-edef-0310-8abb-c4023f1b3aa9
svn/tags/lighttpd-1.4.22
Stefan Bühler 13 years ago
parent
commit
a15e1ce4bb
  1. 1
      NEWS
  2. 51
      src/mod_rrdtool.c

1
NEWS

@ -6,6 +6,7 @@ NEWS
- 1.4.22 -
* Fix wrong lua type for CACHE_MISS/CACHE_HIT in mod_cml (fixes #533)
* Fix default vhost in mod_simple_vhost (fixes #1905)
* Handle EINTR in mod_rrdtool (fixes #604)
- 1.4.21 - 2009-02-16

51
src/mod_rrdtool.c

@ -92,11 +92,11 @@ FREE_FUNC(mod_rrd_free) {
}
int mod_rrd_create_pipe(server *srv, plugin_data *p) {
#ifdef HAVE_FORK
pid_t pid;
int to_rrdtool_fds[2];
int from_rrdtool_fds[2];
#ifdef HAVE_FORK
if (pipe(to_rrdtool_fds)) {
log_error_write(srv, __FILE__, __LINE__, "ss",
"pipe failed: ", strerror(errno));
@ -194,6 +194,47 @@ int mod_rrd_create_pipe(server *srv, plugin_data *p) {
#endif
}
/* read/write wrappers to catch EINTR */
/* write to blocking socket; blocks until all data is sent, write returns 0 or an error (apart from EINTR) occurs. */
static ssize_t safe_write(int fd, const void *buf, size_t count) {
ssize_t res, sum = 0;
for (;;) {
res = write(fd, buf, count);
if (res >= 0) {
sum += res;
/* do not try again if res == 0 */
if (res == 0 || (size_t) res == count) return sum;
count -= res;
buf = (const char*) buf + res;
continue;
}
switch (errno) {
case EINTR:
continue;
default:
return -1;
}
}
}
/* this assumes we get enough data on a successful read */
static ssize_t safe_read(int fd, void *buf, size_t count) {
ssize_t res;
for (;;) {
res = read(fd, buf, count);
if (res >= 0) return res;
switch (errno) {
case EINTR:
continue;
default:
return -1;
}
}
}
static int mod_rrdtool_create_rrd(server *srv, plugin_data *p, plugin_config *s) {
struct stat st;
@ -229,7 +270,7 @@ static int mod_rrdtool_create_rrd(server *srv, plugin_data *p, plugin_config *s)
"RRA:MIN:0.5:24:775 "
"RRA:MIN:0.5:288:797\n"));
if (-1 == (r = write(p->write_fd, p->cmd->ptr, p->cmd->used - 1))) {
if (-1 == (r = safe_write(p->write_fd, p->cmd->ptr, p->cmd->used - 1))) {
log_error_write(srv, __FILE__, __LINE__, "ss",
"rrdtool-write: failed", strerror(errno));
@ -237,7 +278,7 @@ static int mod_rrdtool_create_rrd(server *srv, plugin_data *p, plugin_config *s)
}
buffer_prepare_copy(p->resp, 4096);
if (-1 == (r = read(p->read_fd, p->resp->ptr, p->resp->size))) {
if (-1 == (r = safe_read(p->read_fd, p->resp->ptr, p->resp->size))) {
log_error_write(srv, __FILE__, __LINE__, "ss",
"rrdtool-read: failed", strerror(errno));
@ -390,7 +431,7 @@ TRIGGER_FUNC(mod_rrd_trigger) {
buffer_append_long(p->cmd, s->requests);
buffer_append_string_len(p->cmd, CONST_STR_LEN("\n"));
if (-1 == (r = write(p->write_fd, p->cmd->ptr, p->cmd->used - 1))) {
if (-1 == (r = safe_write(p->write_fd, p->cmd->ptr, p->cmd->used - 1))) {
p->rrdtool_running = 0;
log_error_write(srv, __FILE__, __LINE__, "ss",
@ -400,7 +441,7 @@ TRIGGER_FUNC(mod_rrd_trigger) {
}
buffer_prepare_copy(p->resp, 4096);
if (-1 == (r = read(p->read_fd, p->resp->ptr, p->resp->size))) {
if (-1 == (r = safe_read(p->read_fd, p->resp->ptr, p->resp->size))) {
p->rrdtool_running = 0;
log_error_write(srv, __FILE__, __LINE__, "ss",

Loading…
Cancel
Save