Jabber WindowGram Client (JWGC)

Introduction Screenshots Installation Downloads
Documentation Browse Source Resources Project Site

Stable Version
-none-

Latest Version
beta5



Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

mux.c

Go to the documentation of this file.
00001 /*
00002  *      Copyright (c) 1989 by the Massachusetts Institute of Technology.
00003  *      For copying and distribution information, see the file
00004  *      "mit-copyright.h".
00005  *
00006  *      Modified for jwgc by Daniel Henninger.
00007  */
00008 
00009 #include "mit-copyright.h"
00010 
00011 /****************************************************************************/
00012 /* */
00013 /* Module containing code to wait on multiple file descriptors:      */
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  * mux_end_loop_p - Setting this to true during a mux_loop causes the mux_loop
00028  *                  to be exited.
00029  */
00030 
00031 int mux_end_loop_p;
00032 
00033 /*
00034  * have_tty - is defined to be true if there is a controlling tty for this
00035  *            process.  When we can no longer access the controlling tty,
00036  *            the process will die.
00037  */
00038 
00039 static int have_tty = 0;
00040 
00041 /*
00042  * max_source - the maximum file descriptor that a handler was ever
00043  *              registered for:
00044  */
00045 
00046 static int max_source = -1;
00047 
00048 /*
00049  * Which file descriptors we're waiting on for input & the accompanying
00050  * input handlers & their arguments:
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  *    void mux_init()
00061  *        Requires: mux_init has never been called before
00062  *        Effects: Initializes the mux module.  Must be called before
00063  *                 any other mux call.
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  *    void mux_add_input_source(int descriptor; void (*handler)(); pointer arg)
00081  *        Requires: 0<=descriptor<MAX_SOURCES, mux_init has been called
00082  *        Modifies: Removes the previous input handler if any for descriptor
00083  *        Effects: Registers handler as the input handler for file descriptor
00084  *                 descriptor.  When mux_loop() is running and input is
00085  *                 available on descriptor, handler will be called with
00086  *                 argument arg.
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  *    void mux_loop()
00115  *        Requires: mux_init has been called.
00116  *        Effects: Loops until mux_end_loop_p becomes true.  (Sets
00117  *                 mux_end_loop_p false to start).  Whenever input is
00118  *                 available on an input source which has a registered
00119  *                 handler (see mux_add_input_source), that handler is
00120  *                 called with its argument.  It is guaranteed that if
00121  *                 input is available on a source, its respective input
00122  *                 handler, if any, will eventually be called.  No other
00123  *                 ordering guarantees are made.  When some signal handler
00124  *                 or input handler eventually sets mux_end_loop_p to
00125  *                 true, we return.
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                  * Exit if mux_end_loop_p has been set to true by a handler:
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                  * Do a select on all the file descriptors we care about to
00154                  * wait until at least one of them has input available:
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;       /* on a signal restart
00164                                                  * checking mux_loop_end_p */
00165                         /*
00166                          * else FATAL_TRAP( errno, "while selecting" );
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                  * Call all input handlers whose corresponding file descriptors have
00178                  * input:
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 }


Last updated at Tue Dec 18 21:07:42 PST 2007. This site and project hosted by...SourceForge.net Logo
Source Perspective by Fisheye