--- l2_ch_file.c 2003/09/25 13:15:24 1.29
+++ l2_ch_file.c 2003/09/25 13:20:34 1.30
@@ -42,8 +42,24 @@
int trunc;
int perm;
int jitter;
+ int jittercount;
} l2_ch_file_t;
+/* open channel file */
+static void openchfile(l2_context_t *ctx, l2_channel_t *ch, int mode)
+{
+ l2_ch_file_t *cfg = (l2_ch_file_t *)ctx->vp;
+ mode_t mask;
+
+ /* open channel file */
+ mask = umask(0);
+ cfg->fd = open(cfg->path, mode, cfg->perm);
+ umask(mask);
+
+ /* prepare jittering counter */
+ cfg->jittercount = 0;
+}
+
/* create channel */
static l2_result_t hook_create(l2_context_t *ctx, l2_channel_t *ch)
{
@@ -54,12 +70,13 @@
return L2_ERR_ARG;
/* initialize configuration with reasonable defaults */
- cfg->fd = -1;
- cfg->path = NULL;
- cfg->append = -1;
- cfg->trunc = -1;
- cfg->perm = (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
- cfg->jitter = 0;
+ cfg->fd = -1;
+ cfg->path = NULL;
+ cfg->append = -1;
+ cfg->trunc = -1;
+ cfg->perm = (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
+ cfg->jitter = 0;
+ cfg->jittercount = 0;
/* link private channel configuration into channel context */
ctx->vp = cfg;
@@ -76,11 +93,11 @@
l2_env_t *env;
/* feed and call generic parameter parsing engine */
- L2_PARAM_SET(pa[0], path, STR, &cfg->path);
- L2_PARAM_SET(pa[1], append, INT, &cfg->append);
- L2_PARAM_SET(pa[2], trunc, INT, &cfg->trunc);
- L2_PARAM_SET(pa[3], perm, INT, &cfg->perm);
- L2_PARAM_SET(pa[4], jitter, INT, &cfg->jitter);
+ L2_PARAM_SET(pa[0], path, STR, &cfg->path);
+ L2_PARAM_SET(pa[1], append, INT, &cfg->append);
+ L2_PARAM_SET(pa[2], trunc, INT, &cfg->trunc);
+ L2_PARAM_SET(pa[3], perm, INT, &cfg->perm);
+ L2_PARAM_SET(pa[4], jitter, INT, &cfg->jitter);
L2_PARAM_END(pa[5]);
l2_channel_env(ch, &env);
rv = l2_util_setparams(env, pa, fmt, ap);
@@ -92,8 +109,6 @@
static l2_result_t hook_open(l2_context_t *ctx, l2_channel_t *ch)
{
l2_ch_file_t *cfg = (l2_ch_file_t *)ctx->vp;
- int mode;
- mode_t mask;
/* "append" backward compatibility; only cfg->trunc is used in the code
* make sure append/trunc either both use defaults, both are set different, or only one is set
@@ -121,34 +136,23 @@
if ( cfg->trunc == -1)
cfg->trunc = (1 - cfg->append) & 1;
- /* reduce jitter to 0 (no) or 1 (yes) */
- if (cfg->jitter <= 0)
- cfg->jitter = 0;
- if (cfg->jitter >= 1)
- cfg->jitter = 1;
+ /* make sure jitter count is positive number */
+ if (cfg->jitter < 0)
+ return L2_ERR_USE;
/* make sure a path was set */
if (cfg->path == NULL)
return L2_ERR_USE;
/* open channel file */
- mode = O_WRONLY|O_CREAT;
if (cfg->trunc == 1)
- mode |= O_TRUNC;
+ openchfile(ctx, ch, O_WRONLY|O_CREAT|O_TRUNC);
else
- mode |= O_APPEND;
- mask = umask(0);
- cfg->fd = open(cfg->path, mode, cfg->perm);
- umask(mask);
+ openchfile(ctx, ch, O_WRONLY|O_CREAT|O_APPEND);
+
if (cfg->fd == -1)
return L2_ERR_SYS;
- /* close channel file if jittering, we just wanted to see a successful open and truncate if required */
- if (cfg->jitter == 1) {
- close(cfg->fd);
- cfg->fd = -1;
- }
-
return L2_OK;
}
@@ -158,20 +162,28 @@
{
l2_ch_file_t *cfg = (l2_ch_file_t *)ctx->vp;
l2_result_t rc = L2_OK;
- mode_t mask;
+ int reopen = 0;
- /* handle the impossible; close any lingering file if jittering */
- if (cfg->fd != -1 && cfg->jitter == 1) {
+ /* if jittering, count writes and reopen file if jitter threshold is reached or exceeded */
+ if (cfg->jitter >= 1) {
+ cfg->jittercount++;
+ if (cfg->jittercount >= cfg->jitter) {
+ cfg->jittercount = 0;
+ reopen = 1;
+ }
+ }
+
+ /* close for reopen if required */
+ if (reopen == 1 && cfg->fd != -1) {
close(cfg->fd);
cfg->fd = -1;
}
- /* open channel file if jittering */
- if (cfg->fd == -1 && cfg->jitter == 1) {
- mask = umask(0);
- cfg->fd = open(cfg->path, O_WRONLY|O_CREAT|O_APPEND, cfg->perm);
- umask(mask);
+ /* open if required */
+ if (cfg->fd == -1) {
+ openchfile(ctx, ch, O_WRONLY|O_CREAT|O_APPEND);
}
+
if (cfg->fd == -1)
return L2_ERR_SYS;
@@ -179,12 +191,6 @@
if (write(cfg->fd, buf, buf_size) == -1)
rc = L2_ERR_SYS;
- /* close channel file if jittering */
- if (cfg->jitter == 1) {
- close(cfg->fd);
- cfg->fd = -1;
- }
-
return rc;
}
|