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

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: 
1.1.2.9   misho      31:        prg->prog_used = e_malloc(E_ALIGN(prg->prog_maxn, sizeof *prg->prog_used) / 
                     32:                        sizeof *prg->prog_used);
                     33:        if (!prg->prog_used) {
                     34:                io_SetErr(elwix_GetErrno(), "%s", elwix_GetError());
                     35:                e_free(prg);
                     36:                return NULL;
                     37:        }
                     38: 
1.1.2.1   misho      39:        prg->prog_fds = array_Init(prg->prog_maxn);
                     40:        if (!prg->prog_fds) {
                     41:                io_SetErr(elwix_GetErrno(), "%s", elwix_GetError());
1.1.2.9   misho      42:                e_free(prg->prog_used);
1.1.2.1   misho      43:                e_free(prg);
                     44:                return NULL;
                     45:        }
                     46: 
                     47:        pthread_mutex_init(&prg->prog_mtx, NULL);
1.1.2.2   misho      48: 
1.1.2.6   misho      49:        if (io_progOpen(prg, prg->prog_inin) < 0) {
1.1.2.2   misho      50:                io_progDestroy(&prg);
1.1.2.6   misho      51:                prg = NULL;
                     52:        }
1.1.2.1   misho      53:        return prg;
                     54: }
                     55: 
                     56: /*
                     57:  * io_progDestroy() - Destroy entire program pool
                     58:  *
                     59:  * @pprg = program pool
                     60:  * return: none
                     61:  */
                     62: void
                     63: io_progDestroy(prog_t ** __restrict pprg)
                     64: {
                     65:        if (!pprg || !*pprg)
                     66:                return;
                     67: 
                     68:        io_progClose(*pprg, 0);
                     69: 
1.1.2.9   misho      70:        e_free((*pprg)->prog_used);
1.1.2.1   misho      71:        array_Destroy(&(*pprg)->prog_fds);
                     72:        pthread_mutex_destroy(&(*pprg)->prog_mtx);
                     73: 
                     74:        e_free(*pprg);
                     75:        *pprg = NULL;
                     76: }
                     77: 
                     78: /*
                     79:  * io_progClose() - Close all programs in pool
                     80:  *
                     81:  * @prg = program pool
                     82:  * @closeNum = close program(s) (0 all)
                     83:  * return: 0 error, >0 closed programs
                     84:  */
                     85: int
                     86: io_progClose(prog_t * __restrict prg, u_int closeNum)
                     87: {
                     88:        register int i;
                     89:        int ret = 0;
                     90: 
                     91:        if (!prg)
                     92:                return 0;
                     93:        if (closeNum > prg->prog_maxn) {
                     94:                io_SetErr(EINVAL, "Requested number for close program is over pool's limit");
                     95:                return 0;
                     96:        }
                     97: 
                     98:        pthread_mutex_lock(&prg->prog_mtx);
                     99:        for (i = array_Size(prg->prog_fds) - 1; 
                    100:                        (closeNum ? ret < closeNum : 42) && i > -1; i--)
                    101:                if (array_Get(prg->prog_fds, i)) {
1.1.2.6   misho     102:                        e_pclose(array(prg->prog_fds, i, FILE*));
1.1.2.1   misho     103:                        array_Del(prg->prog_fds, i, 0);
1.1.2.9   misho     104:                        clrbit(prg->prog_used, i);
1.1.2.1   misho     105:                        prg->prog_cnum--;
                    106:                        ret++;
                    107:                }
                    108:        pthread_mutex_unlock(&prg->prog_mtx);
                    109: 
                    110:        return ret;
                    111: }
                    112: 
                    113: /*
                    114:  * io_progOpen() - Execute number of program(s)
                    115:  *
                    116:  * @prg = program pool
                    117:  * @execNum = execute program(s) (0 max)
                    118:  * return: 0 error, >0 executed programs and abs(<0) executed programs with logged error
                    119:  */
                    120: int
                    121: io_progOpen(prog_t * __restrict prg, u_int execNum)
                    122: {
                    123:        FILE *f;
1.1.2.4   misho     124:        int stat, ret = 0;
1.1.2.1   misho     125:        register int i;
1.1.2.4   misho     126:        pid_t pid;
1.1.2.1   misho     127: 
                    128:        if (!prg)
                    129:                return 0;
1.1.2.8   misho     130:        if (prg->prog_cnum + execNum > prg->prog_maxn) {
1.1.2.1   misho     131:                io_SetErr(EINVAL, "Requested number for program execution is over pool's limit");
                    132:                return 0;
                    133:        }
                    134: 
                    135:        pthread_mutex_lock(&prg->prog_mtx);
                    136:        for (i = 0; (execNum ? ret < execNum : 42) && i < array_Size(prg->prog_fds); i++)
                    137:                if (!array_Get(prg->prog_fds, i)) {
1.1.2.6   misho     138:                        f = e_popen(prg->prog_name, "r+", &pid);
1.1.2.1   misho     139:                        if (!f) {
                    140:                                LOGERR;
1.1.2.5   misho     141:                                ret = -1;
1.1.2.1   misho     142:                                break;
1.1.2.6   misho     143:                        } else if (waitpid(pid, &stat, WNOHANG)) {
                    144:                                io_SetErr(ECHILD, "Program with pid=%d exit with status %d", 
                    145:                                                pid, WIFEXITED(stat) ? WEXITSTATUS(stat) : -1);
1.1.2.5   misho     146:                                ret = -1;
1.1.2.4   misho     147:                                break;
1.1.2.1   misho     148:                        } else
                    149:                                array_Set(prg->prog_fds, i, f);
                    150:                        prg->prog_cnum++;
                    151:                        ret++;
                    152:                }
                    153:        pthread_mutex_unlock(&prg->prog_mtx);
                    154: 
                    155:        return ret;
                    156: }
                    157: 
                    158: /*
1.1.2.8   misho     159:  * io_progGrow() - Execute to number of programs in pool
                    160:  *
                    161:  * @prg = program pool
                    162:  * @toNum = execute to number of programs (0 max)
                    163:  * return: 0 error, >0 executed programs and abs(<0) executed programs with logged error
                    164:  */
                    165: int
                    166: io_progGrow(prog_t * __restrict prg, u_int toNum)
                    167: {
                    168:        if (!prg)
                    169:                return 0;
                    170:        if (toNum > prg->prog_maxn) {
                    171:                io_SetErr(EINVAL, "Requested number for program execution is over pool's limit");
                    172:                return 0;
                    173:        }
                    174:        if (!toNum)
                    175:                toNum = prg->prog_maxn;
                    176: 
                    177:        return io_progOpen(prg, toNum - prg->prog_cnum);
                    178: }
                    179: 
                    180: /*
1.1.2.1   misho     181:  * io_progVacuum() - Vacuum pool to running number of programs
                    182:  *
                    183:  * @prg = program pool
                    184:  * @toNum = vacuum to number of programs (0 to init number)
                    185:  * return: 0 error or >0 closed programs
                    186:  */
                    187: int
                    188: io_progVacuum(prog_t * __restrict prg, u_int toNum)
                    189: {
                    190:        register int i;
                    191:        int ret = 0;
                    192: 
                    193:        if (!prg)
                    194:                return 0;
                    195:        if (toNum > prg->prog_maxn) {
                    196:                io_SetErr(EINVAL, "Requested number for close program is over pool's limit");
                    197:                return 0;
                    198:        }
                    199:        if (!toNum)
                    200:                toNum = prg->prog_inin;
                    201: 
                    202:        pthread_mutex_lock(&prg->prog_mtx);
                    203:        for (i = array_Size(prg->prog_fds) - 1; prg->prog_cnum > toNum && i > -1; i--)
1.1.2.10! misho     204:                if (array_Get(prg->prog_fds, i) && isclr(prg->prog_used, i)) {
1.1.2.6   misho     205:                        e_pclose(array(prg->prog_fds, i, FILE*));
1.1.2.1   misho     206:                        array_Del(prg->prog_fds, i, 0);
                    207:                        prg->prog_cnum--;
                    208:                        ret++;
                    209:                }
                    210:        pthread_mutex_unlock(&prg->prog_mtx);
                    211: 
                    212:        return ret;
                    213: }
1.1.2.7   misho     214: 
                    215: /*
                    216:  * io_progCheck() - Check exit status of program pool
                    217:  *
                    218:  * @prg = program pool
                    219:  * return: -1 error or >-1 exited programs
                    220:  */
                    221: int
                    222: io_progCheck(prog_t * __restrict prg)
                    223: {
                    224:        int ret = 0;
                    225:        struct tagPIOPID *p;
                    226:        register int i;
                    227: 
                    228:        if (!prg)
                    229:                return -1;
                    230: 
1.1.2.9   misho     231:        pthread_mutex_lock(&prg->prog_mtx);
1.1.2.7   misho     232:        for (i = 0; i < array_Size(prg->prog_fds); i++)
                    233:                if (array_Get(prg->prog_fds, i) && 
                    234:                                (p = pio_pgetpid(array(prg->prog_fds, i, FILE*))))
1.1.2.9   misho     235:                        if (waitpid(p->pid, &p->stat, WNOHANG) > 0) {
                    236:                                clrbit(prg->prog_used, i);
1.1.2.7   misho     237:                                ret++;
1.1.2.9   misho     238:                        }
                    239:        pthread_mutex_unlock(&prg->prog_mtx);
1.1.2.7   misho     240: 
                    241:        return ret;
                    242: }
1.1.2.9   misho     243: 
                    244: /*
                    245:  * io_progAttach() - Attach to open program
                    246:  *
                    247:  * @prg = program pool
                    248:  * return: NULL error or !=NULL attached program handle
                    249:  */
                    250: FILE *
                    251: io_progAttach(prog_t * __restrict prg)
                    252: {
                    253:        FILE *f = NULL;
                    254:        register int i;
                    255: 
                    256:        if (!prg)
                    257:                return NULL;
                    258: 
                    259:        pthread_mutex_lock(&prg->prog_mtx);
                    260:        for (i = 0; i < array_Size(prg->prog_fds); i++)
                    261:                if (array_Get(prg->prog_fds, i) && isclr(prg->prog_used, i)) {
                    262:                        setbit(prg->prog_used, i);
                    263:                        f = array(prg->prog_fds, i, FILE*);
                    264:                        break;
                    265:                }
                    266:        pthread_mutex_unlock(&prg->prog_mtx);
                    267: 
                    268:        return f;
                    269: }
                    270: 
                    271: /*
                    272:  * io_progDetach() - Detch from open program
                    273:  *
                    274:  * @prg= program pool
                    275:  * @pfd = attached program handle
                    276:  * return: none
                    277:  */
                    278: void
                    279: io_progDetach(prog_t * __restrict prg, FILE *pfd)
                    280: {
                    281:        register int i;
                    282: 
                    283:        if (!prg || !pfd)
                    284:                return;
                    285: 
                    286:        pthread_mutex_lock(&prg->prog_mtx);
                    287:        for (i = 0; i < array_Size(prg->prog_fds); i++)
                    288:                if (array(prg->prog_fds, i, FILE*) == pfd) {
                    289:                        clrbit(prg->prog_used, i);
                    290:                        break;
                    291:                }
                    292:        pthread_mutex_unlock(&prg->prog_mtx);
                    293: }

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