Annotation of libaitio/src/exec.c, revision 1.1.2.7

1.1.2.1   misho       1: #include "global.h"
                      2: 
                      3: 
                      4: /*
                      5:  * io_progInit() - Init program pool
                      6:  *
                      7:  * @progName = program name for execution
                      8:  * @initNum = initial started programs
                      9:  * @maxNum = maximum started programs
                     10:  * return: NULL error or !=NULL allocated pool (must destroied with io_progDestroy())
                     11:  */
                     12: prog_t *
                     13: io_progInit(const char *progName, u_int initNum, u_int maxNum)
                     14: {
                     15:        prog_t *prg = NULL;
                     16: 
                     17:        if (initNum > maxNum)
                     18:                return NULL;
                     19: 
                     20:        prg = e_malloc(sizeof(prog_t));
                     21:        if (!prg) {
                     22:                io_SetErr(elwix_GetErrno(), "%s", elwix_GetError());
                     23:                return NULL;
                     24:        } else
                     25:                memset(prg, 0, sizeof(prog_t));
                     26: 
                     27:        prg->prog_inin = initNum;
                     28:        prg->prog_maxn = maxNum;
                     29:        strlcpy(prg->prog_name, progName, sizeof prg->prog_name);
                     30: 
                     31:        prg->prog_fds = array_Init(prg->prog_maxn);
                     32:        if (!prg->prog_fds) {
                     33:                io_SetErr(elwix_GetErrno(), "%s", elwix_GetError());
                     34:                e_free(prg);
                     35:                return NULL;
                     36:        }
                     37: 
                     38:        pthread_mutex_init(&prg->prog_mtx, NULL);
1.1.2.2   misho      39: 
1.1.2.6   misho      40:        if (io_progOpen(prg, prg->prog_inin) < 0) {
1.1.2.2   misho      41:                io_progDestroy(&prg);
1.1.2.6   misho      42:                prg = NULL;
                     43:        }
1.1.2.1   misho      44:        return prg;
                     45: }
                     46: 
                     47: /*
                     48:  * io_progDestroy() - Destroy entire program pool
                     49:  *
                     50:  * @pprg = program pool
                     51:  * return: none
                     52:  */
                     53: void
                     54: io_progDestroy(prog_t ** __restrict pprg)
                     55: {
                     56:        if (!pprg || !*pprg)
                     57:                return;
                     58: 
                     59:        io_progClose(*pprg, 0);
                     60: 
                     61:        array_Destroy(&(*pprg)->prog_fds);
                     62:        pthread_mutex_destroy(&(*pprg)->prog_mtx);
                     63: 
                     64:        e_free(*pprg);
                     65:        *pprg = NULL;
                     66: }
                     67: 
                     68: /*
                     69:  * io_progClose() - Close all programs in pool
                     70:  *
                     71:  * @prg = program pool
                     72:  * @closeNum = close program(s) (0 all)
                     73:  * return: 0 error, >0 closed programs
                     74:  */
                     75: int
                     76: io_progClose(prog_t * __restrict prg, u_int closeNum)
                     77: {
                     78:        register int i;
                     79:        int ret = 0;
                     80: 
                     81:        if (!prg)
                     82:                return 0;
                     83:        if (closeNum > prg->prog_maxn) {
                     84:                io_SetErr(EINVAL, "Requested number for close program is over pool's limit");
                     85:                return 0;
                     86:        }
                     87: 
                     88:        pthread_mutex_lock(&prg->prog_mtx);
                     89:        for (i = array_Size(prg->prog_fds) - 1; 
                     90:                        (closeNum ? ret < closeNum : 42) && i > -1; i--)
                     91:                if (array_Get(prg->prog_fds, i)) {
1.1.2.6   misho      92:                        e_pclose(array(prg->prog_fds, i, FILE*));
1.1.2.1   misho      93:                        array_Del(prg->prog_fds, i, 0);
                     94:                        prg->prog_cnum--;
                     95:                        ret++;
                     96:                }
                     97:        pthread_mutex_unlock(&prg->prog_mtx);
                     98: 
                     99:        return ret;
                    100: }
                    101: 
                    102: /*
                    103:  * io_progOpen() - Execute number of program(s)
                    104:  *
                    105:  * @prg = program pool
                    106:  * @execNum = execute program(s) (0 max)
                    107:  * return: 0 error, >0 executed programs and abs(<0) executed programs with logged error
                    108:  */
                    109: int
                    110: io_progOpen(prog_t * __restrict prg, u_int execNum)
                    111: {
                    112:        FILE *f;
1.1.2.4   misho     113:        int stat, ret = 0;
1.1.2.1   misho     114:        register int i;
1.1.2.4   misho     115:        pid_t pid;
1.1.2.1   misho     116: 
                    117:        if (!prg)
                    118:                return 0;
                    119:        if (execNum > prg->prog_maxn) {
                    120:                io_SetErr(EINVAL, "Requested number for program execution is over pool's limit");
                    121:                return 0;
                    122:        }
                    123: 
                    124:        pthread_mutex_lock(&prg->prog_mtx);
                    125:        for (i = 0; (execNum ? ret < execNum : 42) && i < array_Size(prg->prog_fds); i++)
                    126:                if (!array_Get(prg->prog_fds, i)) {
1.1.2.6   misho     127:                        f = e_popen(prg->prog_name, "r+", &pid);
1.1.2.1   misho     128:                        if (!f) {
                    129:                                LOGERR;
1.1.2.5   misho     130:                                ret = -1;
1.1.2.1   misho     131:                                break;
1.1.2.6   misho     132:                        } else if (waitpid(pid, &stat, WNOHANG)) {
                    133:                                io_SetErr(ECHILD, "Program with pid=%d exit with status %d", 
                    134:                                                pid, WIFEXITED(stat) ? WEXITSTATUS(stat) : -1);
1.1.2.5   misho     135:                                ret = -1;
1.1.2.4   misho     136:                                break;
1.1.2.1   misho     137:                        } else
                    138:                                array_Set(prg->prog_fds, i, f);
                    139:                        prg->prog_cnum++;
                    140:                        ret++;
                    141:                }
                    142:        pthread_mutex_unlock(&prg->prog_mtx);
                    143: 
                    144:        return ret;
                    145: }
                    146: 
                    147: /*
                    148:  * io_progVacuum() - Vacuum pool to running number of programs
                    149:  *
                    150:  * @prg = program pool
                    151:  * @toNum = vacuum to number of programs (0 to init number)
                    152:  * return: 0 error or >0 closed programs
                    153:  */
                    154: int
                    155: io_progVacuum(prog_t * __restrict prg, u_int toNum)
                    156: {
                    157:        register int i;
                    158:        int ret = 0;
                    159: 
                    160:        if (!prg)
                    161:                return 0;
                    162:        if (toNum > prg->prog_maxn) {
                    163:                io_SetErr(EINVAL, "Requested number for close program is over pool's limit");
                    164:                return 0;
                    165:        }
                    166:        if (!toNum)
                    167:                toNum = prg->prog_inin;
                    168: 
                    169:        pthread_mutex_lock(&prg->prog_mtx);
                    170:        for (i = array_Size(prg->prog_fds) - 1; prg->prog_cnum > toNum && i > -1; i--)
                    171:                if (array_Get(prg->prog_fds, i)) {
1.1.2.6   misho     172:                        e_pclose(array(prg->prog_fds, i, FILE*));
1.1.2.1   misho     173:                        array_Del(prg->prog_fds, i, 0);
                    174:                        prg->prog_cnum--;
                    175:                        ret++;
                    176:                }
                    177:        pthread_mutex_unlock(&prg->prog_mtx);
                    178: 
                    179:        return ret;
                    180: }
1.1.2.7 ! misho     181: 
        !           182: /*
        !           183:  * io_progCheck() - Check exit status of program pool
        !           184:  *
        !           185:  * @prg = program pool
        !           186:  * return: -1 error or >-1 exited programs
        !           187:  */
        !           188: int
        !           189: io_progCheck(prog_t * __restrict prg)
        !           190: {
        !           191:        int ret = 0;
        !           192:        struct tagPIOPID *p;
        !           193:        register int i;
        !           194: 
        !           195:        if (!prg)
        !           196:                return -1;
        !           197: 
        !           198:        for (i = 0; i < array_Size(prg->prog_fds); i++)
        !           199:                if (array_Get(prg->prog_fds, i) && 
        !           200:                                (p = pio_pgetpid(array(prg->prog_fds, i, FILE*))))
        !           201:                        if (waitpid(p->pid, &p->stat, WNOHANG) > 0)
        !           202:                                ret++;
        !           203: 
        !           204:        return ret;
        !           205: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>