/* Terminal Mixer - multi-point multi-user access to terminal applications Copyright (C) 2007 LluĂ­s Batlle i Rossell Please find the license in the provided COPYING file. */ #include #include #include #include #include #include #include #include #include "main.h" #include "handlers.h" static void loop() { fd_set read_set; sigset_t sigold,signoalarm; int maxfd; int stdin_opened; int res; if (command_line.s_param.nohup) stdin_opened = 0; else stdin_opened = 1; /* Prepare the sigset for blocking alarm */ sigemptyset(&signoalarm); sigaddset(&signoalarm, SIGALRM); do { FD_ZERO(&read_set); if (stdin_opened) FD_SET(0, &read_set); maxfd = 0; app_control_prepare_read_fdset(&read_set, &maxfd); if (command_line.s_param.serve_unix) s_unix_prepare_read_fdset(&read_set, &maxfd); if (command_line.s_param.serve_tcp) s_tcp_prepare_read_fdset(&read_set, &maxfd); #ifdef linux if (command_line.s_param.serve_eth) s_eth_prepare_read_fdset(&read_set, &maxfd); #endif /* linux */ /* Prepare checking for timeout */ sigprocmask(SIG_BLOCK, &signoalarm, &sigold); #ifdef linux if (command_line.s_param.serve_eth) /* This will check if the timeout occurred, * and will not do anything otherwise. */ eth_proto_process_timeouts(); #endif /* Will block */ res = pselect(maxfd + 1, &read_set, 0, 0, 0, &sigold); #ifdef linux if (command_line.s_param.serve_eth) eth_proto_process_timeouts(); #endif if (res == -1) { if (errno == EINTR) continue; else error("Error in select()"); } res = app_control_process_read_fdset(&read_set); if (res == -1) /* app_stdout and app_stderr closed */ break; if (stdin_opened && FD_ISSET(0, &read_set)) { res = read(0, stream_buffer, stream_buffer_size); /* if res is 0, the fcall will close app_stdin */ app_control_local_send_to_stdin(stream_buffer, res); if (res == 0) stdin_opened = 0; } if (command_line.s_param.serve_unix) s_unix_process_read_fdset(&read_set); if (command_line.s_param.serve_tcp) s_tcp_process_read_fdset(&read_set); #ifdef linux if (command_line.s_param.serve_eth) s_eth_process_read_fdset(&read_set); #endif /* linux */ } while(1); } int server() { int child; command_line.is_server = 1; app_control_start(); /* in raw mode, the signals for Control-C, ... will be generated by the * slave pty. The master will receive the key codes. */ if (command_line.s_param.serve_unix) s_unix_update_served(command_line.s_param.max_served); if (command_line.s_param.serve_tcp) s_tcp_update_served(command_line.s_param.max_served); #ifdef linux if (command_line.s_param.serve_eth) s_eth_init(); #endif /* linux */ child = fork_app(command_line.s_param.command); if (command_line.s_param.nohup) { ignore_sighup(); close(0); close(1); close(2); } else if (command_line.s_param.run_in_subterminal) prepare_user_terminal(); install_signal_forwarders(child); loop(); if (command_line.s_param.serve_unix) s_unix_shutdown(); if (command_line.s_param.serve_tcp) s_tcp_shutdown(); #ifdef linux if (command_line.s_param.serve_eth) s_eth_shutdown(); #endif /* linux */ if (!command_line.s_param.nohup && command_line.s_param.run_in_subterminal) restore_user_terminal(); return 0; }