+void tcl_mainloop (Tcl_Interp *interp, int interactive)
+{
+ int i;
+ int res;
+ Tcl_DString command;
+ static fd_set fdset_tcl_r;
+ static fd_set fdset_tcl_w;
+ static fd_set fdset_tcl_x;
+ int min_fd;
+
+ min_fd = interactive ? 3 : 0;
+ if (interactive)
+ {
+ Tcl_DStringInit (&command);
+ printf ("%% "); fflush (stdout);
+ }
+ while (1)
+ {
+ FD_ZERO (&fdset_tcl_r);
+ FD_ZERO (&fdset_tcl_w);
+ FD_ZERO (&fdset_tcl_x);
+ if (interactive)
+ FD_SET (0, &fdset_tcl_r);
+ for (res=0, i=min_fd; i<=max_fd; i++)
+ {
+ if (callback_table[i].w_handle)
+ {
+ FD_SET (i, &fdset_tcl_w);
+ res++;
+ }
+ if (callback_table[i].r_handle)
+ {
+ FD_SET (i, &fdset_tcl_r);
+ res++;
+ }
+ if (callback_table[i].x_handle)
+ {
+ FD_SET (i, &fdset_tcl_x);
+ res++;
+ }
+ }
+ if (!interactive && !res)
+ return;
+ if ((res = select(max_fd+1, &fdset_tcl_r, &fdset_tcl_w,
+ &fdset_tcl_x, 0)) < 0)
+ {
+ perror("select");
+ exit(1);
+ }
+ if (!res)
+ continue;
+ for (i=min_fd; i<=max_fd; i++)
+ {
+ if (FD_ISSET (i, &fdset_tcl_r))
+ {
+ assert (callback_table[i].r_handle);
+ (*callback_table[i].r_handle) (callback_table[i].obj);
+ }
+ if (FD_ISSET (i, &fdset_tcl_w))
+ {
+ assert (callback_table[i].w_handle);
+ (*callback_table[i].w_handle) (callback_table[i].obj);
+ }
+ if (FD_ISSET (i, &fdset_tcl_x))
+ {
+ assert (callback_table[i].x_handle);
+ (*callback_table[i].x_handle) (callback_table[i].obj);
+ }
+ }
+ if (interactive && FD_ISSET(0, &fdset_tcl_r))
+ {
+ char input_buf[1024];
+ int count = read (0, input_buf, 1024);
+
+ if (count <= 0)
+ exit (0);
+ Tcl_DStringAppend (&command, input_buf, count);
+ if (Tcl_CommandComplete (Tcl_DStringValue (&command)))
+ {
+ int code = Tcl_Eval (interp, Tcl_DStringValue (&command));
+ Tcl_DStringFree (&command);
+ if (code)
+ printf ("Error: %s\n", interp->result);
+ else if (*interp->result)
+ printf ("%s\n", interp->result);
+ printf ("%% "); fflush (stdout);
+ }
+ }
+ }
+}
+
+void ir_select_add (int fd, void *obj)
+{
+ callback_table[fd].obj = obj;
+ callback_table[fd].r_handle = ir_select_read;
+ callback_table[fd].w_handle = NULL;
+ callback_table[fd].x_handle = NULL;
+ if (fd > max_fd)
+ max_fd = fd;
+}
+
+void ir_select_add_write (int fd, void *obj)
+{
+ callback_table[fd].w_handle = ir_select_write;
+ if (fd > max_fd)
+ max_fd = fd;
+}
+
+void ir_select_remove_write (int fd, void *obj)
+{
+ callback_table[fd].w_handle = NULL;
+}
+
+void ir_select_remove (int fd, void *obj)
+{
+ callback_table[fd].r_handle = NULL;
+ callback_table[fd].w_handle = NULL;
+ callback_table[fd].x_handle = NULL;
+}