2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these libraries and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
24 * File: spcd_event.c $XConsortium: spcd_event.c /main/4 1996/01/15 13:49:32 rswiston $
27 * (c) Copyright 1988, Hewlett-Packard Company, all rights reserved.
29 * (c) Copyright 1993, 1994 Hewlett-Packard Company *
30 * (c) Copyright 1993, 1994 International Business Machines Corp. *
31 * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
32 * (c) Copyright 1993, 1994 Novell, Inc. *
37 #include <bms/sbport.h> /* NOTE: sbport.h must be the first include. */
39 #include <bms/SbEvent.h>
40 #include <sys/types.h> /* for fd_set, FD_SET macros, et. al. */
44 # define FD_SET_CAST(x) (x)
46 # define FD_SET_CAST(x) ((int *)(x))
49 struct {SbInputCallbackProc handler; void* data; }
50 SPCD_input_handlers [FD_SETSIZE],
51 SPCD_except_handlers[FD_SETSIZE];
55 fd_set Sb_Input_Mask, Sb_Except_Mask;
57 SbInputId SPCD_AddInput(int fd, SbInputCallbackProc proc, void* data)
58 {SPCD_input_handlers[fd].handler = proc;
59 SPCD_input_handlers[fd].data = data;
60 FD_SET(fd, &Sb_Input_Mask);
61 if (SPCD_max_fd < fd) SPCD_max_fd = fd;
64 SbInputId SPCD_AddException(int fd, SbInputCallbackProc proc, void* data)
65 {SPCD_except_handlers[fd].handler = proc;
66 SPCD_except_handlers[fd].data = data;
67 FD_SET(fd, &Sb_Except_Mask);
68 if (SPCD_max_fd < fd) SPCD_max_fd = fd;
71 void SPCD_RemoveInput(SbInputId id)
72 {FD_CLR(id, &Sb_Input_Mask);
75 void SPCD_RemoveException(SbInputId id)
76 {FD_CLR(id, &Sb_Except_Mask);
80 void SPCD_MainLoopUntil(Boolean *flag)
83 int fd_vec_size = howmany(SPCD_max_fd, NFDBITS);
84 fd_set input_mask, except_mask;
89 memcpy(&input_mask, &Sb_Input_Mask, sizeof(fd_set));
90 memcpy(&except_mask, &Sb_Except_Mask, sizeof(fd_set));
93 do result=select(SPCD_max_fd + 1, FD_SET_CAST(&input_mask),
95 FD_SET_CAST(&except_mask), NULL);
96 while(result == -1 && errno==EINTR);
99 SPC_Error(SPC_Bad_Select);
100 SPC_Format_Log((XeString)"Exiting server ...");
105 /* Modified loop to break after a single hit on the select. This */
106 /* is necessary because there is nothing which stops the lower */
107 /* level input handlers from reading the data from a random file */
108 /* descriptor. If this happens, and the random file descriptor */
109 /* happens to be one on which this loop detected input, the */
110 /* process might hang. The solution is therefore to go back to */
111 /* the select after every input handler call. */
113 for (fd=0; fd < SPCD_max_fd+1; fd++)
116 if(FD_ISSET(fd, &except_mask)) {
117 (*SPCD_except_handlers[fd].handler)(SPCD_except_handlers[fd].data, &fd, &id);
120 if(FD_ISSET(fd, &input_mask)) {
121 (*SPCD_input_handlers[fd].handler)(SPCD_input_handlers[fd].data, &fd, &id);
128 void SPCD_BreakMainLoop(void)
130 /* no need to do anything */