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;
}
Example #2
0
/* 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? */
    }
}