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>