#include "global.h"
/*
* io_progInit() - Init program pool
*
* @progName = program name for execution
* @initNum = initial started programs
* @maxNum = maximum started programs
* return: NULL error or !=NULL allocated pool (must destroied with io_progDestroy())
*/
prog_t *
io_progInit(const char *progName, u_int initNum, u_int maxNum)
{
prog_t *prg = NULL;
if (initNum > maxNum)
return NULL;
prg = e_malloc(sizeof(prog_t));
if (!prg) {
io_SetErr(elwix_GetErrno(), "%s", elwix_GetError());
return NULL;
} else
memset(prg, 0, sizeof(prog_t));
prg->prog_inin = initNum;
prg->prog_maxn = maxNum;
strlcpy(prg->prog_name, progName, sizeof prg->prog_name);
prg->prog_fds = array_Init(prg->prog_maxn);
if (!prg->prog_fds) {
io_SetErr(elwix_GetErrno(), "%s", elwix_GetError());
e_free(prg);
return NULL;
}
pthread_mutex_init(&prg->prog_mtx, NULL);
if (io_progOpen(prg, prg->prog_inin) < 0)
io_progDestroy(&prg);
return prg;
}
/*
* io_progDestroy() - Destroy entire program pool
*
* @pprg = program pool
* return: none
*/
void
io_progDestroy(prog_t ** __restrict pprg)
{
if (!pprg || !*pprg)
return;
io_progClose(*pprg, 0);
array_Destroy(&(*pprg)->prog_fds);
pthread_mutex_destroy(&(*pprg)->prog_mtx);
e_free(*pprg);
*pprg = NULL;
}
/*
* io_progClose() - Close all programs in pool
*
* @prg = program pool
* @closeNum = close program(s) (0 all)
* return: 0 error, >0 closed programs
*/
int
io_progClose(prog_t * __restrict prg, u_int closeNum)
{
register int i;
int ret = 0;
if (!prg)
return 0;
if (closeNum > prg->prog_maxn) {
io_SetErr(EINVAL, "Requested number for close program is over pool's limit");
return 0;
}
pthread_mutex_lock(&prg->prog_mtx);
for (i = array_Size(prg->prog_fds) - 1;
(closeNum ? ret < closeNum : 42) && i > -1; i--)
if (array_Get(prg->prog_fds, i)) {
pclose(array(prg->prog_fds, i, FILE*));
array_Del(prg->prog_fds, i, 0);
prg->prog_cnum--;
ret++;
}
pthread_mutex_unlock(&prg->prog_mtx);
return ret;
}
/*
* io_progOpen() - Execute number of program(s)
*
* @prg = program pool
* @execNum = execute program(s) (0 max)
* return: 0 error, >0 executed programs and abs(<0) executed programs with logged error
*/
int
io_progOpen(prog_t * __restrict prg, u_int execNum)
{
FILE *f;
int ret = 0;
register int i;
if (!prg)
return 0;
if (execNum > prg->prog_maxn) {
io_SetErr(EINVAL, "Requested number for program execution is over pool's limit");
return 0;
}
pthread_mutex_lock(&prg->prog_mtx);
for (i = 0; (execNum ? ret < execNum : 42) && i < array_Size(prg->prog_fds); i++)
if (!array_Get(prg->prog_fds, i)) {
f = popen(prg->prog_name, "r+");
if (!f) {
LOGERR;
ret *= -1;
break;
} else
array_Set(prg->prog_fds, i, f);
prg->prog_cnum++;
ret++;
}
pthread_mutex_unlock(&prg->prog_mtx);
return ret;
}
/*
* io_progVacuum() - Vacuum pool to running number of programs
*
* @prg = program pool
* @toNum = vacuum to number of programs (0 to init number)
* return: 0 error or >0 closed programs
*/
int
io_progVacuum(prog_t * __restrict prg, u_int toNum)
{
register int i;
int ret = 0;
if (!prg)
return 0;
if (toNum > prg->prog_maxn) {
io_SetErr(EINVAL, "Requested number for close program is over pool's limit");
return 0;
}
if (!toNum)
toNum = prg->prog_inin;
pthread_mutex_lock(&prg->prog_mtx);
for (i = array_Size(prg->prog_fds) - 1; prg->prog_cnum > toNum && i > -1; i--)
if (array_Get(prg->prog_fds, i)) {
pclose(array(prg->prog_fds, i, FILE*));
array_Del(prg->prog_fds, i, 0);
prg->prog_cnum--;
ret++;
}
pthread_mutex_unlock(&prg->prog_mtx);
return ret;
}
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>