William A. Rowe, Jr. wrote:
Mladen Turk wrote:
I'd leave rotatelogs alone, please. Its design is not flawed. But
I think Jim was working on something which would release the file
just as soon as its time is up, and that is useful across all of
the architectures, not windows specific.
Attached is the patch that uses 1 second timeout when reading
from stdin (hard-coded because we have 1 second rotation resolution).
Unfortunately I had to make WIN32 specific peace of code,
cause we don't have APR_FILES_AS_SOCKETS on that platform.
Code was testes both on windows and linux and it works like
a charm (rotation is done at exact time regardless of log events).
Regards
--
^(TM)
--- rotatelogs.c.org 2008-11-06 07:49:07.000000000 +0100
+++ rotatelogs.c 2009-06-10 14:15:39.000000000 +0200
@@ -44,6 +44,8 @@
#include "apr_file_io.h"
#include "apr_file_info.h"
#include "apr_general.h"
+#include "apr_poll.h"
+#include "apr_portable.h"
#include "apr_time.h"
#include "apr_getopt.h"
@@ -64,6 +66,53 @@
#define MAX_PATH 1024
#endif
+#if APR_FILES_AS_SOCKETS
+static apr_pollfd_t wait_pollfd;
+static apr_status_t wait_for_io_or_timeout(apr_file_t *f,
+ apr_interval_time_t timeout,
+ apr_pool_t *pool)
+{
+ apr_int32_t nd;
+
+ if (!wait_pollfd.p) {
+ wait_pollfd.p = pool;
+ }
+ wait_pollfd.desc_type = APR_POLL_FILE;
+ wait_pollfd.reqevents = APR_POLLIN;
+ wait_pollfd.desc.f = f;
+
+ return apr_poll(&wait_pollfd, 1, &nd, timeout);
+}
+#elif defined(WIN32)
+static apr_status_t wait_for_io_or_timeout(apr_file_t *f,
+ apr_interval_time_t timeout,
+ apr_pool_t *pool)
+{
+ HANDLE h;
+ char c;
+ DWORD r;
+ int s = 0;
+
+ apr_os_file_get(&h, f);
+ while (PeekNamedPipe(h, &c, 1, &r, NULL, NULL)) {
+ if (r == 1)
+ break;
+ if (s >= apr_time_msec(timeout))
+ return APR_TIMEUP;
+ Sleep(100);
+ s += 100;
+ }
+ return APR_SUCCESS;
+}
+#else
+static apr_status_t wait_for_io_or_timeout(apr_file_t *f,
+ apr_interval_time_t timeout,
+ apr_pool_t *pool)
+{
+ return APR_SUCCESS;
+}
+#endif /* APR_FILES_AS_SOCKETS */
+
static void usage(const char *argv0, const char *reason)
{
if (reason) {
@@ -198,7 +247,18 @@
* since we reset bypass_io after the 1st loop
*/
if (!bypass_io) {
- if (apr_file_read(f_stdin, buf, &nRead) != APR_SUCCESS) {
+ apr_status_t rv;
+
+ rv = wait_for_io_or_timeout(f_stdin, apr_time_from_sec(1), pool);
+ if (rv == APR_SUCCESS) {
+ if (apr_file_read(f_stdin, buf, &nRead) != APR_SUCCESS) {
+ exit(3);
+ }
+ }
+ else if (APR_STATUS_IS_TIMEUP(rv)) {
+ nRead = 0;
+ }
+ else {
exit(3);
}
}