| version 1.9, 2002/02/05 22:37:03 |
version 1.10, 2002/02/06 21:44:11 |
|
|
| # include "menu.h" |
# include "menu.h" |
| #endif |
#endif |
| |
|
| #define MAX_EBADF_COUNT (100) |
|
| |
|
| /* Global pointer to argv[0] (program name). */ |
/* Global pointer to argv[0] (program name). */ |
| char *argv0; |
char *argv0; |
| |
|
| void exit_fnc(void) |
void exit_fnc(void) |
| { |
{ |
| /* |
|
| msg_print("exit_fnc(): ep shutting down, sending all process SIGTERM...\n"); |
|
| kill(0, SIGTERM); |
|
| */ |
|
| #if DEBUG |
#if DEBUG |
| msg_debug_print("exit_fnc(): %s terminating\n", argv0); |
msg_debug_print("exit_fnc(): %s terminating\n", argv0); |
| #endif |
#endif |
|
|
| char **argv; |
char **argv; |
| { |
{ |
| register int i, k; |
register int i, k; |
| register int ret; |
register int ret, pid; |
| /* register int ebadf_count; */ |
struct timeval tv; |
| PROCTABLE ptbl; |
PROCTABLE ptbl; |
| fd_set fds; |
fd_set rfds, efds; |
| |
|
| argv0 = strrchr(argv[0], '/') == NULL ? strdup(argv[0]) : |
argv0 = strrchr(argv[0], '/') == NULL ? strdup(argv[0]) : |
| strdup(strrchr(argv[0], '/') + 1); |
strdup(strrchr(argv[0], '/') + 1); |
| Line 179 main(argc, argv) |
|
| Line 174 main(argc, argv) |
|
| |
|
| /* Main loop. */ |
/* Main loop. */ |
| while (1) { |
while (1) { |
| /* |
|
| ebadf_count = 0; |
|
| |
|
| while (1) { |
|
| */ |
|
| struct timeval tv; |
|
| int pid = 0; |
|
| |
|
| do { |
do { |
| |
|
| |
/* Set rfds and efds. */ |
| /* Wait up to five seconds. */ |
FD_ZERO(&rfds); |
| tv.tv_sec = 1; |
FD_ZERO(&efds); |
| tv.tv_usec = 0; |
|
| |
for (i = 0; ptbl[i] != NULL; i++) { |
| /* Set fds. */ |
|
| FD_ZERO(&fds); |
for (k = 0; k < N_FD; k++) { |
| |
if (ptbl[i]->fd[k].n_link != 0) { |
| for (i = 0; ptbl[i] != NULL; i++) |
if ((!i && !k) || (i && k)) |
| for (k = (i ? 1 : 0); k < (i ? N_FD : 1); k++) |
FD_SET(ptbl[i]->fd[k].pipe[0], &rfds); |
| if (ptbl[i]->fd[k].n_link != 0) |
|
| FD_SET(ptbl[i]->fd[k].pipe[0], &fds); |
FD_SET(ptbl[i]->fd[k].pipe[k ? 0 : 1], &efds); |
| |
} |
| |
} |
| |
} |
| |
|
| /* Check if processes still running. */ |
/* Check if processes still running. */ |
| pid = proctable_wait(&ptbl); |
pid = proctable_wait(&ptbl); |
| Line 211 main(argc, argv) |
|
| Line 202 main(argc, argv) |
|
| return errno; |
return errno; |
| } |
} |
| |
|
| } while (pid > 0); |
} while (pid > 1 && proctable_get_size(ptbl) > 1); |
| |
|
| { |
{ |
| register int size = proctable_get_size(ptbl); |
register int size = proctable_get_size(ptbl); |
| #if DEBUG |
#if 0 && DEBUG |
| msg_debug_print("main(): proctable_get_size() = %d\n", size); |
msg_debug_print("main(): proctable_get_size() = %d\n", size); |
| #endif |
#endif |
| if (size < 2) |
if (size < 2) |
| break; |
break; |
| } |
} |
| |
|
| ret = select(FD_SETSIZE, &fds, NULL, NULL, /*&tv/*/NULL/**/); |
/* TODO: if closed fd 0, always use timeout */ |
| if (ret >= 0) |
if (1 || pid == 1) { |
| ; |
tv.tv_sec = 1; |
| /* break; */ |
tv.tv_usec = 1000; |
| |
} |
| |
|
| |
ret = select(FD_SETSIZE, &rfds, NULL, &efds, 1 || pid == 1 ? &tv : NULL); |
| |
|
| if (ret < 0 /*|| errno != EBADF || ebadf_count > MAX_EBADF_COUNT*/) { |
if (ret < 0) { |
| msg_error_print("select() failure: %s\n", strerror(errno)); |
msg_error_print("select() failure: %s\n", strerror(errno)); |
| proctable_destroy(&ptbl); |
proctable_destroy(&ptbl); |
| return errno; |
return errno; |
| } |
} |
| else { |
|
| /* |
|
| register int size; |
|
| |
|
| int status; |
|
| int pid; |
|
| int idx; |
|
| |
|
| pid = waitpid(-1, &status, WNOHANG); |
|
| |
|
| if (pid > 0) { |
|
| idx = proctable_get_process_index_by_pid(ptbl, pid); |
|
| if (proctable_remove_process(&ptbl, idx) < 0) { |
|
| msg_error_print("error during removing process from proctable\n"); |
|
| exit(1); |
|
| } |
|
| } |
|
| |
|
| if ((size = proctable_get_size(ptbl)) < 2) |
|
| return 0; |
|
| #if DEBUG |
|
| msg_debug_print("proctable_get_size() = %d\n", size); |
|
| #endif |
|
| ebadf_count++; |
|
| */ |
|
| } |
|
| /*}*/ |
|
| |
|
| #if MENU |
#if MENU |
| if (FD_ISSET(0, &fds)) { |
if (FD_ISSET(0, &rfds)) { |
| int c; |
int c; |
| c = getch(); |
c = getch(); |
| switch (c) { |
switch (c) { |
|
|
| #endif /* #if MENU */ |
#endif /* #if MENU */ |
| |
|
| /* Read and transfer data. */ |
/* Read and transfer data. */ |
| proctable_read(&ptbl, &fds); |
while (proctable_read(&ptbl, &rfds, &efds) == 0) { |
| |
#if DEBUG |
| |
msg_debug_print("main(): repeating proctable_read()\n"); |
| |
#endif |
| |
} |
| |
#if DEBUG |
| |
proctable_print(ptbl); |
| |
#endif |
| } |
} |
| |
|
| proctable_destroy(&ptbl); |
proctable_destroy(&ptbl); |