#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)) 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; }