diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/configfile.c | 16 | ||||
-rw-r--r-- | src/log.c | 32 | ||||
-rw-r--r-- | src/log.h | 2 | ||||
-rw-r--r-- | src/mod_accesslog.c | 13 | ||||
-rw-r--r-- | src/server.c | 10 |
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; } @@ -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); @@ -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; } |