00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "mit-copyright.h"
00010
00011
00012
00013
00014
00015
00016
00017 #include "mux.h"
00018 #include "error.h"
00019 #include "main.h"
00020 #include "pointer.h"
00021
00022 #ifdef _AIX
00023 #include <sys/select.h>
00024 #endif
00025
00026
00027
00028
00029
00030
00031 int mux_end_loop_p;
00032
00033
00034
00035
00036
00037
00038
00039 static int have_tty = 0;
00040
00041
00042
00043
00044
00045
00046 static int max_source = -1;
00047
00048
00049
00050
00051
00052
00053 static fd_set input_sources;
00054 static void (*input_handler[MAX_SOURCES]) ();
00055 static pointer input_handler_arg[MAX_SOURCES];
00056
00057 static int check_tty();
00058
00059
00060
00061
00062
00063
00064
00065
00066 void
00067 mux_init()
00068 {
00069 int i;
00070
00071 FD_ZERO(&input_sources);
00072
00073 for (i = 0; i < MAX_SOURCES; i++)
00074 input_handler[i] = NULL;
00075
00076 have_tty = check_tty();
00077 }
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089 void
00090 mux_add_input_source(descriptor, handler, arg)
00091 int descriptor;
00092 void (*handler) ();
00093 pointer arg;
00094 {
00095 dprintf(dPoll, "Adding handler on fd %d, will call %x(%x)\n",
00096 descriptor, handler, arg);
00097 input_handler[descriptor] = handler;
00098 input_handler_arg[descriptor] = arg;
00099 FD_SET(descriptor, &input_sources);
00100 if (descriptor > max_source)
00101 max_source = descriptor;
00102 }
00103
00104 void
00105 mux_delete_input_source(descriptor)
00106 int descriptor;
00107 {
00108 input_handler[descriptor] = NULL;
00109 input_handler_arg[descriptor] = NULL;
00110 FD_CLR(descriptor, &input_sources);
00111 }
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128 void
00129 mux_loop()
00130 {
00131 int i;
00132 fd_set input_sources_copy;
00133 struct timeval tv;
00134
00135 mux_end_loop_p = 0;
00136
00137 for (;;) {
00138
00139
00140
00141 if (mux_end_loop_p)
00142 break;
00143
00144 if (have_tty) {
00145 tv.tv_sec = 10;
00146 tv.tv_usec = 0;
00147 }
00148 else {
00149 tv.tv_sec = tv.tv_usec = 0;
00150 }
00151
00152
00153
00154
00155
00156 input_sources_copy = input_sources;
00157
00158 i = select(max_source + 1, &input_sources_copy, (fd_set *) 0,
00159 (fd_set *) NULL, have_tty ? &tv : (struct timeval *) 0);
00160
00161 if (i == -1) {
00162 if (errno == EINTR)
00163 continue;
00164
00165
00166
00167
00168 }
00169 else if (i == 0) {
00170 if (have_tty && !check_tty()) {
00171 mux_end_loop_p = 1;
00172 continue;
00173 }
00174 }
00175
00176
00177
00178
00179
00180 for (i = 0; i <= max_source; i++)
00181 if (FD_ISSET(i, &input_sources_copy) && input_handler[i]) {
00182 dprintf(dPoll, "mux_loop...activity on fd %d, calling %x(%x)\n",
00183 i, input_handler[i], input_handler_arg[i]);
00184 input_handler[i] (input_handler_arg[i]);
00185 }
00186 }
00187 }
00188
00189 static int
00190 check_tty()
00191 {
00192 register int result;
00193 int pgrp;
00194 int tty = open("/dev/tty", O_RDONLY | O_NDELAY);
00195
00196 if (tty < 0)
00197 return 0;
00198
00199 #if defined(_POSIX_VERSION)
00200 result = (((pgrp = tcgetpgrp(tty)) < 0) ? 0 : 1);
00201 #else
00202 result = ((ioctl(tty, TIOCGPGRP, &pgrp) < 0) ? 0 : 1);
00203 #endif
00204
00205 close(tty);
00206 return (result);
00207 }