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>