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

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.11! misho     102: #ifdef POPEN_STREAM
1.1.2.6   misho     103:                        e_pclose(array(prg->prog_fds, i, FILE*));
1.1.2.11! misho     104: #else
        !           105:                        e_pclose((int) array(prg->prog_fds, i, intptr_t));
        !           106: #endif
1.1.2.1   misho     107:                        array_Del(prg->prog_fds, i, 0);
1.1.2.9   misho     108:                        clrbit(prg->prog_used, i);
1.1.2.1   misho     109:                        prg->prog_cnum--;
                    110:                        ret++;
                    111:                }
                    112:        pthread_mutex_unlock(&prg->prog_mtx);
                    113: 
                    114:        return ret;
                    115: }
                    116: 
                    117: /*
                    118:  * io_progOpen() - Execute number of program(s)
                    119:  *
                    120:  * @prg = program pool
                    121:  * @execNum = execute program(s) (0 max)
                    122:  * return: 0 error, >0 executed programs and abs(<0) executed programs with logged error
                    123:  */
                    124: int
                    125: io_progOpen(prog_t * __restrict prg, u_int execNum)
                    126: {
1.1.2.11! misho     127: #ifdef POPEN_STREAM
1.1.2.1   misho     128:        FILE *f;
1.1.2.11! misho     129: #else
        !           130:        int f;
        !           131: #endif
1.1.2.4   misho     132:        int stat, ret = 0;
1.1.2.1   misho     133:        register int i;
1.1.2.4   misho     134:        pid_t pid;
1.1.2.1   misho     135: 
                    136:        if (!prg)
                    137:                return 0;
1.1.2.8   misho     138:        if (prg->prog_cnum + execNum > prg->prog_maxn) {
1.1.2.1   misho     139:                io_SetErr(EINVAL, "Requested number for program execution is over pool's limit");
                    140:                return 0;
                    141:        }
                    142: 
                    143:        pthread_mutex_lock(&prg->prog_mtx);
                    144:        for (i = 0; (execNum ? ret < execNum : 42) && i < array_Size(prg->prog_fds); i++)
                    145:                if (!array_Get(prg->prog_fds, i)) {
1.1.2.6   misho     146:                        f = e_popen(prg->prog_name, "r+", &pid);
1.1.2.11! misho     147: #ifdef POPEN_STREAM
1.1.2.1   misho     148:                        if (!f) {
1.1.2.11! misho     149: #else
        !           150:                        if (f == -1) {
        !           151: #endif
1.1.2.1   misho     152:                                LOGERR;
1.1.2.5   misho     153:                                ret = -1;
1.1.2.1   misho     154:                                break;
1.1.2.6   misho     155:                        } else if (waitpid(pid, &stat, WNOHANG)) {
                    156:                                io_SetErr(ECHILD, "Program with pid=%d exit with status %d", 
                    157:                                                pid, WIFEXITED(stat) ? WEXITSTATUS(stat) : -1);
1.1.2.5   misho     158:                                ret = -1;
1.1.2.4   misho     159:                                break;
1.1.2.1   misho     160:                        } else
                    161:                                array_Set(prg->prog_fds, i, f);
                    162:                        prg->prog_cnum++;
                    163:                        ret++;
                    164:                }
                    165:        pthread_mutex_unlock(&prg->prog_mtx);
                    166: 
                    167:        return ret;
                    168: }
                    169: 
                    170: /*
1.1.2.8   misho     171:  * io_progGrow() - Execute to number of programs in pool
                    172:  *
                    173:  * @prg = program pool
                    174:  * @toNum = execute to number of programs (0 max)
                    175:  * return: 0 error, >0 executed programs and abs(<0) executed programs with logged error
                    176:  */
                    177: int
                    178: io_progGrow(prog_t * __restrict prg, u_int toNum)
                    179: {
                    180:        if (!prg)
                    181:                return 0;
                    182:        if (toNum > prg->prog_maxn) {
                    183:                io_SetErr(EINVAL, "Requested number for program execution is over pool's limit");
                    184:                return 0;
                    185:        }
                    186:        if (!toNum)
                    187:                toNum = prg->prog_maxn;
                    188: 
                    189:        return io_progOpen(prg, toNum - prg->prog_cnum);
                    190: }
                    191: 
                    192: /*
1.1.2.1   misho     193:  * io_progVacuum() - Vacuum pool to running number of programs
                    194:  *
                    195:  * @prg = program pool
                    196:  * @toNum = vacuum to number of programs (0 to init number)
                    197:  * return: 0 error or >0 closed programs
                    198:  */
                    199: int
                    200: io_progVacuum(prog_t * __restrict prg, u_int toNum)
                    201: {
                    202:        register int i;
                    203:        int ret = 0;
                    204: 
                    205:        if (!prg)
                    206:                return 0;
                    207:        if (toNum > prg->prog_maxn) {
                    208:                io_SetErr(EINVAL, "Requested number for close program is over pool's limit");
                    209:                return 0;
                    210:        }
                    211:        if (!toNum)
                    212:                toNum = prg->prog_inin;
                    213: 
                    214:        pthread_mutex_lock(&prg->prog_mtx);
                    215:        for (i = array_Size(prg->prog_fds) - 1; prg->prog_cnum > toNum && i > -1; i--)
1.1.2.10  misho     216:                if (array_Get(prg->prog_fds, i) && isclr(prg->prog_used, i)) {
1.1.2.11! misho     217: #ifdef POPEN_STREAM
1.1.2.6   misho     218:                        e_pclose(array(prg->prog_fds, i, FILE*));
1.1.2.11! misho     219: #else
        !           220:                        e_pclose((int) array(prg->prog_fds, i, intptr_t));
        !           221: #endif
1.1.2.1   misho     222:                        array_Del(prg->prog_fds, i, 0);
                    223:                        prg->prog_cnum--;
                    224:                        ret++;
                    225:                }
                    226:        pthread_mutex_unlock(&prg->prog_mtx);
                    227: 
                    228:        return ret;
                    229: }
1.1.2.7   misho     230: 
                    231: /*
                    232:  * io_progCheck() - Check exit status of program pool
                    233:  *
                    234:  * @prg = program pool
                    235:  * return: -1 error or >-1 exited programs
                    236:  */
                    237: int
                    238: io_progCheck(prog_t * __restrict prg)
                    239: {
                    240:        int ret = 0;
                    241:        struct tagPIOPID *p;
                    242:        register int i;
                    243: 
                    244:        if (!prg)
                    245:                return -1;
                    246: 
1.1.2.9   misho     247:        pthread_mutex_lock(&prg->prog_mtx);
1.1.2.7   misho     248:        for (i = 0; i < array_Size(prg->prog_fds); i++)
                    249:                if (array_Get(prg->prog_fds, i) && 
1.1.2.11! misho     250: #ifdef POPEN_STREAM
1.1.2.7   misho     251:                                (p = pio_pgetpid(array(prg->prog_fds, i, FILE*))))
1.1.2.11! misho     252: #else
        !           253:                                (p = pio_pgetpid((int) array(prg->prog_fds, i, intptr_t))))
        !           254: #endif
1.1.2.9   misho     255:                        if (waitpid(p->pid, &p->stat, WNOHANG) > 0) {
                    256:                                clrbit(prg->prog_used, i);
1.1.2.7   misho     257:                                ret++;
1.1.2.9   misho     258:                        }
                    259:        pthread_mutex_unlock(&prg->prog_mtx);
1.1.2.7   misho     260: 
                    261:        return ret;
                    262: }
1.1.2.9   misho     263: 
                    264: /*
                    265:  * io_progAttach() - Attach to open program
                    266:  *
                    267:  * @prg = program pool
                    268:  * return: NULL error or !=NULL attached program handle
                    269:  */
1.1.2.11! misho     270: #ifdef POPEN_STREAM
1.1.2.9   misho     271: FILE *
1.1.2.11! misho     272: #else
        !           273: int
        !           274: #endif
1.1.2.9   misho     275: io_progAttach(prog_t * __restrict prg)
                    276: {
1.1.2.11! misho     277: #ifdef POPEN_STREAM
1.1.2.9   misho     278:        FILE *f = NULL;
1.1.2.11! misho     279: #else
        !           280:        int f = -1;
        !           281: #endif
1.1.2.9   misho     282:        register int i;
                    283: 
                    284:        if (!prg)
1.1.2.11! misho     285: #ifdef POPEN_STREAM
1.1.2.9   misho     286:                return NULL;
1.1.2.11! misho     287: #else
        !           288:                return -1;
        !           289: #endif
1.1.2.9   misho     290: 
                    291:        pthread_mutex_lock(&prg->prog_mtx);
                    292:        for (i = 0; i < array_Size(prg->prog_fds); i++)
                    293:                if (array_Get(prg->prog_fds, i) && isclr(prg->prog_used, i)) {
                    294:                        setbit(prg->prog_used, i);
1.1.2.11! misho     295: #ifdef POPEN_STREAM
1.1.2.9   misho     296:                        f = array(prg->prog_fds, i, FILE*);
1.1.2.11! misho     297: #else
        !           298:                        f = array(prg->prog_fds, i, intptr_t);
        !           299: #endif
1.1.2.9   misho     300:                        break;
                    301:                }
                    302:        pthread_mutex_unlock(&prg->prog_mtx);
                    303: 
                    304:        return f;
                    305: }
                    306: 
                    307: /*
                    308:  * io_progDetach() - Detch from open program
                    309:  *
                    310:  * @prg= program pool
                    311:  * @pfd = attached program handle
                    312:  * return: none
                    313:  */
                    314: void
1.1.2.11! misho     315: #ifdef POPEN_STREAM
1.1.2.9   misho     316: io_progDetach(prog_t * __restrict prg, FILE *pfd)
1.1.2.11! misho     317: #else
        !           318: io_progDetach(prog_t * __restrict prg, int pfd)
        !           319: #endif
1.1.2.9   misho     320: {
                    321:        register int i;
                    322: 
                    323:        if (!prg || !pfd)
                    324:                return;
                    325: 
                    326:        pthread_mutex_lock(&prg->prog_mtx);
                    327:        for (i = 0; i < array_Size(prg->prog_fds); i++)
1.1.2.11! misho     328: #ifdef POPEN_STREAM
1.1.2.9   misho     329:                if (array(prg->prog_fds, i, FILE*) == pfd) {
1.1.2.11! misho     330: #else
        !           331:                if (array(prg->prog_fds, i, intptr_t) == pfd) {
        !           332: #endif
1.1.2.9   misho     333:                        clrbit(prg->prog_used, i);
                    334:                        break;
                    335:                }
                    336:        pthread_mutex_unlock(&prg->prog_mtx);
                    337: }

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