| version 1.20, 2002/02/28 17:50:38 |
version 1.21, 2002/04/09 21:16:45 |
|
|
| * coding start date: 11.11.2000 |
* coding start date: 11.11.2000 |
| * authors: Ondrej Jombik |
* authors: Ondrej Jombik |
| * Lubomir Host |
* Lubomir Host |
| * Martin Karas |
* Martin Karas |
| * Copyright (c) 2000-2002 Platon software development group |
* Copyright (c) 2000-2002 Platon software development group |
| * license: GNU General Public License |
* license: GNU General Public License |
| * |
* |
| * $Id$ |
* $Id$ |
| */ |
*/ |
| |
|
| #ifdef HAVE_CONFIG_H |
#ifdef HAVE_CONFIG_H |
| # include "config.h" |
# include "config.h" |
|
|
| # include "menu.h" |
# include "menu.h" |
| #endif |
#endif |
| |
|
| |
/* |
| |
* Global variables |
| |
*/ |
| |
|
| /* Global pointer to argv[0] (program name). */ |
/* Global pointer to argv[0] (program name). */ |
| char *argv0; |
char *argv0; |
| |
/* Configration filenames. */ |
| |
char *conf_global_filename = "/etc/ep.conf"; |
| |
char *conf_user_filename = ".ep.conf"; |
| |
/* Program configuration structure. */ |
| |
struct conf_struct_global cfg; |
| |
|
| |
|
| void |
void |
| exit_fnc(void) |
exit_fnc(void) |
| { |
{ |
| |
conf_destroy(); |
| |
|
| #if DEBUG |
#if DEBUG |
| msg_debug_print("exit_fnc(): %s terminating\n", argv0); |
msg_debug_print("exit_fnc(): %s terminating\n", argv0); |
|
| Line 104 main(argc, argv) |
|
| register int i, k; |
register int i, k; |
| register int ret, pid = 0; |
register int ret, pid = 0; |
| struct timeval tv; |
struct timeval tv; |
| |
fd_set rfds; |
| |
fd_set wfds; |
| |
fd_set efds; |
| PROCTABLE ptbl; |
PROCTABLE ptbl; |
| fd_set rfds, efds; |
|
| |
|
| argv0 = strrchr(argv[0], '/') == NULL ? strdup(argv[0]) : |
/* |
| strdup(strrchr(argv[0], '/') + 1); |
* Creating global variable argv0. |
| |
*/ |
| |
argv0 = strrchr(argv[0], '/') == NULL |
| |
? strdup(argv[0]) |
| |
: strdup(strrchr(argv[0], '/') + 1); |
| |
|
| if (argv0 == NULL) { |
if (argv0 == NULL) { |
| fprintf(stderr, "fatal-error: not enough memory\n"); |
fprintf(stderr, "fatal-error: not enough memory\n"); |
| return 1; |
return 1; |
| } |
} |
| |
|
| if (0 && argc < 2) { |
/* |
| |
* Registering atexit() funcion. |
| |
*/ |
| |
if (atexit(exit_fnc) < 0) { |
| |
msg_error_print("cannot register atexit() function\n"); |
| |
return 1; |
| |
} |
| |
|
| |
if (argc < 2) { |
| msg_usage_print(); |
msg_usage_print(); |
| return 1; |
return 1; |
| } |
} |
| |
|
| #if MENU |
#if MENU |
| printf("hihi\n"); |
/* |
| |
* Ncurses menu initialization |
| |
*/ |
| menu_curses_init(); |
menu_curses_init(); |
| #endif |
#endif |
| |
|
| /* ptbl = proctable_get_from_cmdline(argc, argv); */ |
/* |
| |
* Initializing configuration module |
| |
*/ |
| |
if (! conf_init()) { |
| |
msg_error_print("cannot init configuration parsing structures\n"); |
| |
return 1; |
| |
} |
| |
|
| |
/* |
| |
* Parsing command line and all config files (global, user and specified) |
| |
*/ |
| ptbl = conf_parse_all(argc, argv); |
ptbl = conf_parse_all(argc, argv); |
| |
|
| if (ptbl == NULL) { |
if (ptbl == NULL) { |
| /* msg_error_print("command line fails, terminating\n"); */ |
|
| return 1; |
return 1; |
| } |
} |
| #if DEBUG |
#if DEBUG |
| Line 134 main(argc, argv) |
|
| Line 170 main(argc, argv) |
|
| else |
else |
| msg_debug_print("proctable check: OK\n"); |
msg_debug_print("proctable check: OK\n"); |
| #endif |
#endif |
| |
/* |
| |
* Creating pipes via pipe() syscalls |
| |
*/ |
| if (proctable_create_pipes(ptbl) < 0) { |
if (proctable_create_pipes(ptbl) < 0) { |
| msg_error_print("cannot create pipes\n"); |
msg_error_print("cannot create pipes\n"); |
| return 1; |
return 1; |
| Line 144 main(argc, argv) |
|
| Line 182 main(argc, argv) |
|
| msg_debug_print("creating pipes: OK\n"); |
msg_debug_print("creating pipes: OK\n"); |
| #endif |
#endif |
| |
|
| /* Fork processes and dup pipes. */ |
/* |
| /* Exec the processes via execvp(). */ |
* Fork processes and dup pipes. |
| |
* Exec the processes via execvp(). |
| |
*/ |
| if (proctable_exec(ptbl) < 0) { |
if (proctable_exec(ptbl) < 0) { |
| msg_error_print("fork() failure: %s\n", strerror(errno)); |
msg_error_print("fork() failure: %s\n", strerror(errno)); |
| return 1; |
return 1; |
| Line 156 main(argc, argv) |
|
| Line 196 main(argc, argv) |
|
| #endif |
#endif |
| |
|
| |
|
| /* Closing 2nd sides of pipes. */ |
/* |
| |
* Closing 2nd sides of pipes. |
| |
*/ |
| proctable_close_2nd_sides_of_pipes(ptbl); |
proctable_close_2nd_sides_of_pipes(ptbl); |
| |
|
| /* Registering atexit() funcion. */ |
/* |
| if (atexit(exit_fnc) < 0) { |
* Instaling signal handler. |
| msg_error_print("cannot register atexit() function\n"); |
*/ |
| return 1; |
|
| } |
|
| |
|
| /* Instaling signal handler. */ |
|
| /* sigserv_init(ptbl); */ |
/* sigserv_init(ptbl); */ |
| |
|
| #if DEBUG |
#if DEBUG |
| /* Proctable print. */ |
/* |
| |
* Proctable print. |
| |
*/ |
| proctable_print(ptbl); |
proctable_print(ptbl); |
| #endif |
#endif |
| |
|
| /* Main loop. */ |
/* |
| |
* Main loop |
| |
*/ |
| while (1) { |
while (1) { |
| register int size; |
register int size; |
| |
|
| do { |
/* Set rfds and efds. */ |
| |
FD_ZERO(&rfds); |
| /* Set rfds and efds. */ |
FD_ZERO(&wfds); |
| FD_ZERO(&rfds); |
FD_ZERO(&efds); |
| FD_ZERO(&efds); |
|
| |
for (i = 0; ptbl[i] != NULL; i++) { |
| for (i = 0; ptbl[i] != NULL; i++) { |
|
| |
for (k = 0; k < N_FD; k++) { |
| for (k = 0; k < N_FD; k++) { |
if (ptbl[i]->fd[k].n_link != 0) { |
| if (ptbl[i]->fd[k].n_link != 0) { |
if ((!i && !k) || (i && k)) { |
| if ((!i && !k) || (i && k)) |
FD_SET(ptbl[i]->fd[k].pipe[0], &rfds); |
| FD_SET(ptbl[i]->fd[k].pipe[0], &rfds); |
} |
| |
else { |
| FD_SET(ptbl[i]->fd[k].pipe[k ? 0 : 1], &efds); |
FD_SET(ptbl[i]->fd[k].pipe[1], &wfds); |
| } |
} |
| } |
|
| } |
|
| size = proctable_get_size(ptbl); |
|
| if (size < 2) |
|
| break; |
|
| |
|
| /* Check if processes still running. */ |
|
| pid = proctable_wait(&ptbl); |
|
| |
|
| if (pid < 0) { |
/* FD_SET(ptbl[i]->fd[k].pipe[k ? 0 : 1], &efds); */ |
| msg_error_print("waitpid() failure: %s\n", strerror(errno)); |
} |
| proctable_destroy(&ptbl); |
|
| return errno; |
|
| } |
} |
| |
} |
| size = proctable_get_size(ptbl); |
|
| |
|
| } while (pid > 1 && size > 1); |
|
| |
|
| #if 0 && DEBUG |
|
| msg_debug_print("main(): proctable_get_size() = %d\n", size); |
|
| #endif |
|
| if (size < 2 /* and 0 is closed */) |
|
| break; |
|
| |
|
| /* TODO: if closed fd 0, always use timeout */ |
/* TODO: if closed fd 0, always use timeout */ |
| if (pid == 1) { |
if (pid == 1) { |
| Line 223 main(argc, argv) |
|
| Line 246 main(argc, argv) |
|
| tv.tv_usec = 1000; |
tv.tv_usec = 1000; |
| } |
} |
| |
|
| ret = select(FD_SETSIZE, &rfds, NULL, &efds, pid == 1 ? &tv : NULL); |
ret = select(FD_SETSIZE, &rfds, &wfds, &efds, pid == 1 ? &tv : NULL); |
| |
|
| if (ret < 0) { |
if (ret < 0) { |
| msg_error_print("select() failure: %s\n", strerror(errno)); |
/* NOTE: this stuff around EBADF will be probably neccessary |
| proctable_destroy(&ptbl); |
in the future. Although this, it is commented now, for |
| return errno; |
better extended pipelinign debugging. */ |
| |
if (1 || errno != EBADF) { |
| |
msg_error_print("select() failure: %s\n", strerror(errno)); |
| |
break; |
| |
} |
| |
|
| |
sleep(1); |
| } |
} |
| |
|
| #if MENU |
#if MENU |
| Line 236 main(argc, argv) |
|
| Line 265 main(argc, argv) |
|
| int c; |
int c; |
| c = getch(); |
c = getch(); |
| switch (c) { |
switch (c) { |
| case '\033': // ESC |
case '\033': /* ESC */ |
| case KEY_F(9): |
case KEY_F(9): |
| menu_main(&ptbl); |
menu_main(&ptbl); |
| touchwin(stdscr); |
touchwin(stdscr); |
| refresh(); |
refresh(); |
| break; |
break; |
| case 12: // ^L |
case 12: /* ^L */ |
| touchwin(stdscr); |
touchwin(stdscr); |
| refresh(); |
refresh(); |
| break; |
break; |
| Line 253 main(argc, argv) |
|
| Line 282 main(argc, argv) |
|
| } |
} |
| #endif /* #if HAVE_MENU */ |
#endif /* #if HAVE_MENU */ |
| |
|
| /* Read and transfer data. */ |
/* |
| while (proctable_read(&ptbl, &rfds, &efds) == 0) { |
* Read and transfer data. |
| |
*/ |
| |
|
| |
if (ret > 0) { |
| |
while (proctable_read(&ptbl, &rfds, &wfds, &efds) == 0) { |
| #if DEBUG |
#if DEBUG |
| msg_debug_print("main(): repeating proctable_read()\n"); |
msg_debug_print("main(): repeating proctable_read()\n"); |
| #endif |
#endif |
| |
} |
| |
} |
| |
|
| |
/* |
| |
* Check if processes still running. |
| |
*/ |
| |
|
| |
while (1) { |
| |
pid = proctable_wait(&ptbl); |
| |
/* printf("pid = %d\n", pid); */ |
| |
|
| |
if (pid < 0) { |
| |
msg_error_print("waitpid() failure: %s\n", strerror(errno)); |
| |
break; |
| |
} |
| |
|
| |
size = proctable_get_size(ptbl); |
| |
if (size < 2 /* and 0 is closed */) { |
| |
pid = -1; |
| |
break; |
| |
} |
| |
|
| |
if (pid == 0 || pid == 1) |
| |
break; |
| |
/* |
| |
if (pid == 1) { |
| |
if (proctable_wait(&ptbl) <= 1) |
| |
break; |
| |
} |
| |
*/ |
| } |
} |
| |
|
| |
if (pid < 0) |
| |
break; |
| |
|
| |
|
| #if DEBUG |
#if DEBUG |
| proctable_print(ptbl); |
proctable_print(ptbl); |
| #endif |
#endif |
| } |
} |
| |
|
| |
/* |
| |
* Destroying used process table. |
| |
*/ |
| |
|
| proctable_destroy(&ptbl); |
proctable_destroy(&ptbl); |
| |
|
| return 0; |
return errno > 0 ? errno : (errno < 0 ? -errno : 0); |
| } |
} |
| |
|