static apr_status_t ap_buffered_log_writer(request_rec *r, void *handle, const char **strs, int *strl, int nelts, apr_size_t len) { char *str; char *s; int i; apr_status_t rv; buffered_log *buf = (buffered_log*)handle; if ((rv = APR_ANYLOCK_LOCK(&buf->mutex)) != APR_SUCCESS) { return rv; } if (len + buf->outcnt > LOG_BUFSIZE) { flush_log(buf); } if (len >= LOG_BUFSIZE) { apr_size_t w; str = apr_palloc(r->pool, len + 1); for (i = 0, s = str; i < nelts; ++i) { memcpy(s, strs[i], strl[i]); s += strl[i]; } w = len; rv = apr_file_write(buf->handle, str, &w); } else { for (i = 0, s = &buf->outbuf[buf->outcnt]; i < nelts; ++i) { memcpy(s, strs[i], strl[i]); s += strl[i]; } buf->outcnt += len; rv = APR_SUCCESS; } APR_ANYLOCK_UNLOCK(&buf->mutex); return rv; }
/* Called by mod_log_config to write a log file line. */ static apr_status_t ap_rotated_log_writer(request_rec *r, void *handle, const char **strs, int *strl, int nelts, apr_size_t len) { char *str; char *s; int i; apr_status_t rv = 0; rotated_log *rl = (rotated_log *) handle; if (NULL != rl && NULL != rl->fd) { if (rl->st.enabled) { apr_time_t logt = ap_get_quantized_time(rl, r->request_time); ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, r->server, "New: %lu, old: %lu", (unsigned long) logt, (unsigned long) rl->logtime); /* Decide if the quantized time has rolled over into a new slot. */ if (logt != rl->logtime) { /* Get the mutex */ if (rv = APR_ANYLOCK_LOCK(&rl->mutex), APR_SUCCESS != rv) { return rv; } /* Now check again in case someone else rotated the log while we waited * for the mutex. */ if (logt != rl->logtime) { apr_file_t *ofd = rl->fd; apr_pool_t *par, *np; rl->logtime = logt; /* Create a new pool to provide storage for the new file. * Once we have the new file open we'll destroy the old * pool and make this one current. */ par = apr_pool_parent_get(rl->pool); if (rv = apr_pool_create(&np, par), APR_SUCCESS != rv) { APR_ANYLOCK_UNLOCK(&rl->mutex); return rv; } /* Atomically replace the current log file because other * threads, perhaps those responsible for a long lived * request, won't have blocked on the mutex. */ if (rl->fd = ap_open_log(np, r->server, rl->fname, &rl->st, logt), NULL == rl->fd) { /* Open failed so keep going with the old log... */ rl->fd = ofd; /* ...and destroy the new pool. */ apr_pool_destroy(np); } else { /* Close the old log... */ ap_close_log(r->server, ofd); /* ...and switch to the new pool. */ apr_pool_destroy(rl->pool); rl->pool = np; } } APR_ANYLOCK_UNLOCK(&rl->mutex); } } str = apr_palloc(r->pool, len + 1); for (i = 0, s = str; i < nelts; ++i) { memcpy(s, strs[i], strl[i]); s += strl[i]; } rv = apr_file_write(rl->fd, str, &len); return rv; } else { return APR_SUCCESS; /* Should we complain? */ } }