summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/configfile.c16
-rw-r--r--src/log.c32
-rw-r--r--src/log.h2
-rw-r--r--src/mod_accesslog.c13
-rw-r--r--src/server.c10
5 files changed, 62 insertions, 11 deletions
diff --git a/src/configfile.c b/src/configfile.c
index 17f67ae7..f6971596 100644
--- a/src/configfile.c
+++ b/src/configfile.c
@@ -1045,7 +1045,7 @@ int config_parse_cmd(server *srv, config_t *context, const char *cmd) {
if (NULL == (oldpwd = getCWD())) {
log_error_write(srv, __FILE__, __LINE__, "s",
- "cannot get cwd", strerror(errno));
+ "cannot get cwd", strerror(errno));
return -1;
}
@@ -1053,12 +1053,16 @@ int config_parse_cmd(server *srv, config_t *context, const char *cmd) {
out = buffer_init();
if (!buffer_string_is_empty(context->basedir)) {
- chdir(context->basedir->ptr);
+ if (0 != chdir(context->basedir->ptr)) {
+ log_error_write(srv, __FILE__, __LINE__, "sbs",
+ "cannot change directory to", context->basedir, strerror(errno));
+ return -1;
+ }
}
if (0 != proc_open_buffer(cmd, NULL, out, NULL)) {
log_error_write(srv, __FILE__, __LINE__, "sbss",
- "opening", source, "failed:", strerror(errno));
+ "opening", source, "failed:", strerror(errno));
ret = -1;
} else {
tokenizer_init(&t, source, CONST_BUF_LEN(out));
@@ -1067,7 +1071,11 @@ int config_parse_cmd(server *srv, config_t *context, const char *cmd) {
buffer_free(source);
buffer_free(out);
- chdir(oldpwd);
+ if (0 != chdir(oldpwd)) {
+ log_error_write(srv, __FILE__, __LINE__, "sss",
+ "cannot change directory to", oldpwd, strerror(errno));
+ return -1;
+ }
free(oldpwd);
return ret;
}
diff --git a/src/log.c b/src/log.c
index 94f47107..89fee878 100644
--- a/src/log.c
+++ b/src/log.c
@@ -26,6 +26,36 @@
# define O_LARGEFILE 0
#endif
+/* retry write on EINTR or when not all data was written */
+ssize_t write_all(int fd, const void* buf, size_t count) {
+ ssize_t written = 0;
+
+ while (count > 0) {
+ ssize_t r = write(fd, buf, count);
+ if (r < 0) {
+ switch (errno) {
+ case EINTR:
+ /* try again */
+ break;
+ default:
+ /* fail - repeating probably won't help */
+ return -1;
+ }
+ } else if (0 == r) {
+ /* really shouldn't happen... */
+ errno = EIO;
+ return -1;
+ } else {
+ force_assert(r <= (ssize_t) count);
+ written += r;
+ buf = r + (char const*) buf;
+ count -= r;
+ }
+ }
+
+ return written;
+}
+
/* Close fd and _try_ to get a /dev/null for it instead.
* close() alone may trigger some bugs when a
* process opens another file and gets fd = STDOUT_FILENO or STDERR_FILENO
@@ -361,7 +391,7 @@ static void log_write(server *srv, buffer *b) {
case ERRORLOG_FILE:
case ERRORLOG_FD:
buffer_append_string_len(b, CONST_STR_LEN("\n"));
- write(srv->errorlog_fd, CONST_BUF_LEN(b));
+ write_all(srv->errorlog_fd, CONST_BUF_LEN(b));
break;
case ERRORLOG_SYSLOG:
syslog(LOG_ERR, "%s", b->ptr);
diff --git a/src/log.h b/src/log.h
index 7e924306..6cc2cfb0 100644
--- a/src/log.h
+++ b/src/log.h
@@ -3,6 +3,8 @@
#include "server.h"
+ssize_t write_all(int fd, const void* buf, size_t count);
+
/* Close fd and _try_ to get a /dev/null for it instead.
* Returns 0 on success and -1 on failure (fd gets closed in all cases)
*/
diff --git a/src/mod_accesslog.c b/src/mod_accesslog.c
index 17c5412c..542a9266 100644
--- a/src/mod_accesslog.c
+++ b/src/mod_accesslog.c
@@ -160,6 +160,13 @@ INIT_FUNC(mod_accesslog_init) {
return p;
}
+static void accesslog_write_all(server *srv, const buffer *filename, int fd, const void* buf, size_t count) {
+ if (-1 == write_all(fd, buf, count)) {
+ log_error_write(srv, __FILE__, __LINE__, "sbs",
+ "writing access log entry failed:", filename, strerror(errno));
+ }
+}
+
static void accesslog_append_escaped(buffer *dest, buffer *str) {
char *ptr, *start, *end;
@@ -418,7 +425,7 @@ FREE_FUNC(mod_accesslog_free) {
if (!buffer_string_is_empty(s->access_logbuffer)) {
if (s->log_access_fd != -1) {
- write(s->log_access_fd, CONST_BUF_LEN(s->access_logbuffer));
+ accesslog_write_all(srv, s->access_logfile, s->log_access_fd, CONST_BUF_LEN(s->access_logbuffer));
}
}
@@ -593,7 +600,7 @@ SIGHUP_FUNC(log_access_cycle) {
if (!buffer_string_is_empty(s->access_logbuffer)) {
if (s->log_access_fd != -1) {
- write(s->log_access_fd, CONST_BUF_LEN(s->access_logbuffer));
+ accesslog_write_all(srv, s->access_logfile, s->log_access_fd, CONST_BUF_LEN(s->access_logbuffer));
}
buffer_reset(s->access_logbuffer);
@@ -914,7 +921,7 @@ REQUESTDONE_FUNC(log_access_write) {
}
#endif
} else if (p->conf.log_access_fd != -1) {
- write(p->conf.log_access_fd, CONST_BUF_LEN(b));
+ accesslog_write_all(srv, p->conf.access_logfile, p->conf.log_access_fd, CONST_BUF_LEN(b));
}
buffer_reset(b);
}
diff --git a/src/server.c b/src/server.c
index d97541ba..d79594cd 100644
--- a/src/server.c
+++ b/src/server.c
@@ -366,7 +366,7 @@ static void show_version (void) {
"Build-Date: " __DATE__ " " __TIME__ "\n";
;
#undef TEXT_SSL
- write(STDOUT_FILENO, b, strlen(b));
+ write_all(STDOUT_FILENO, b, strlen(b));
}
static void show_features (void) {
@@ -535,7 +535,7 @@ static void show_help (void) {
;
#undef TEXT_SSL
#undef TEXT_IPV6
- write(STDOUT_FILENO, b, strlen(b));
+ write_all(STDOUT_FILENO, b, strlen(b));
}
int main (int argc, char **argv) {
@@ -1001,7 +1001,11 @@ int main (int argc, char **argv) {
if (pid_fd != -1) {
buffer_copy_int(srv->tmp_buf, getpid());
buffer_append_string_len(srv->tmp_buf, CONST_STR_LEN("\n"));
- write(pid_fd, CONST_BUF_LEN(srv->tmp_buf));
+ if (-1 == write_all(pid_fd, CONST_BUF_LEN(srv->tmp_buf))) {
+ log_error_write(srv, __FILE__, __LINE__, "ss", "Couldn't write pid file:", strerror(errno));
+ close(pid_fd);
+ return -1;
+ }
close(pid_fd);
pid_fd = -1;
}