Index: ossp-pkg/l2/l2_ch_file.c RCS File: /v/ossp/cvs/ossp-pkg/l2/l2_ch_file.c,v rcsdiff -q -kk '-r1.29' '-r1.30' -u '/v/ossp/cvs/ossp-pkg/l2/l2_ch_file.c,v' 2>/dev/null --- 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; }