Initial import of the CDE 2.1.30 sources from the Open Group.
[oweals/cde.git] / cde / programs / dtsession / SmConMgmt.c
1 /* $TOG: SmConMgmt.c /main/6 1998/04/06 14:35:42 mgreess $ */
2 /*                                                                      *
3  * (c) Copyright 1993, 1994 Hewlett-Packard Company                     *
4  * (c) Copyright 1993, 1994 International Business Machines Corp.       *
5  * (c) Copyright 1993, 1994 Sun Microsystems, Inc.                      *
6  * (c) Copyright 1993, 1994 Novell, Inc.                                *
7  */
8
9 /*************************************<+>*************************************
10  *****************************************************************************
11  **
12  **  File:        SmConMgmt.c
13  **
14  **  Project:     HP DT Session Manager (dtsession)
15  **
16  **  Description:
17  **  -----------
18  **      Contains all code which performs contention management functionality
19  **
20  **
21  *******************************************************************
22  **  (c) Copyright Hewlett-Packard Company, 1990.  All rights are  
23  **  reserved.  Copying or other reproduction of this program      
24  **  except for archival purposes is prohibited without prior      
25  **  written consent of Hewlett-Packard Company.                     
26  ********************************************************************
27  **
28  **
29  **
30  *****************************************************************************
31  *************************************<+>*************************************/
32
33
34 #include <stdio.h>
35 #include <fcntl.h>
36 #if !defined(linux)
37 #include <nlist.h>
38 #endif
39 #include <X11/Intrinsic.h>
40 #include "Sm.h"
41 #include "SmProtocol.h"
42 #include "SmConMgmt.h"
43 #include "SmCommun.h"
44
45 /*
46  * Define statements
47  */
48
49 #ifdef mips
50 #include <sys/fixpoint.h>
51 #endif /* mips */
52
53 #ifndef KMEM_FILE
54 #define KMEM_FILE "/dev/kmem"
55 #endif
56
57 #ifndef KERNEL_FILE
58 # ifdef mips
59 #  define KERNEL_FILE "/vmunix"
60 # else /* not mips */
61 #  define KERNEL_FILE "/hp-ux"
62 # endif /* mips */
63 #endif
64
65 #ifdef mips
66 #define GPGSLIM "gpgslim"
67 #define FREEMEM "freemem"
68 #else /* not mips */
69 # ifdef __hpux
70 #  ifdef __hp9000s800
71 #   define GPGSLIM "gpgslim"
72 #   define FREEMEM "freemem"
73 #  endif /* __hp9000s800 */
74 # endif /* __hpux */
75 #endif /* mips */
76
77 #ifndef GPGSLIM
78 #define GPGSLIM "_gpgslim"
79 #endif /* not defined GPGSLIM */
80
81 #ifndef FREEMEM
82 #define FREEMEM "_freemem"
83 #endif /* not defined FREEMEM */
84
85
86 int clientRunning;
87 /*
88  * Variables global to this module only
89  */
90 #if !defined(linux)
91 static struct nlist namelist[3];
92 #endif
93 static int freemem_loc, gpgslim_loc, gpgslim, freemem;
94 static int clientTimeout;
95
96 /*
97  * Functions local to this module
98  */
99
100 static void HandleClientMessage(Widget smWidget, XtPointer dummy, 
101                                 XEvent *event);
102 static void WaitClientTimeout(XtPointer, XtIntervalId *);
103
104
105 \f
106 /*************************************<->*************************************
107  *
108  *  GetMemoryUtilization ()
109  *
110  *
111  *  Description:
112  *  -----------
113  *  Returns 1 of 3 values.  Tells the calling program that memory is not
114  *  available, that it is full (paging has started), or that it is not
115  *  full.
116  *
117  *
118  *  Inputs:
119  *  ------
120  *
121  * 
122  *  Outputs:
123  *  -------
124  *  An integer value representing the current memory utilization of the
125  *  system.
126  *
127  *
128  *  Comments:
129  *  --------
130  *  WARNING:  This routine, by its very nature is non-portable.  It depends
131  *  on an OS having some kind of access to its memory utilization.
132  *
133  *  DOUBLE WARNING: The mips architecture code has never been tested.
134  *  
135  * 
136  *************************************<->***********************************/
137
138 int 
139 GetMemoryUtilization(void)
140 {
141 #if !defined(linux)
142     static int init = 0;
143     static kmem;
144 #if !defined(SVR4) && !defined(sco) && !defined(hpV4) && !defined(_POWER) && !defined (__osf__)
145     extern void nlist();
146 #endif
147     int i;
148
149
150 #ifdef __hpux
151     setresgid(-1, smGD.conMgmtGID, -1);
152 #else
153 #ifndef SVR4
154     setregid(smGD.runningGID, smGD.conMgmtGID);
155 #else
156     setgid(smGD.runningGID);
157     setegid(smGD.conMgmtGID);
158 #endif
159 #endif
160
161     if(!init)
162     {
163         namelist[0].n_name = FREEMEM;
164         namelist[1].n_name = GPGSLIM;
165         namelist[2].n_name = (char *) NULL;
166         nlist( KERNEL_FILE, namelist);
167         for(i = 0; i < 2; i++)
168         {
169             if (namelist[i].n_type == 0 ||
170                 namelist[i].n_value == 0)
171             {
172 #ifdef __hpux
173                 setresgid(-1, smGD.runningGID, -1);
174 #else
175 #ifndef SVR4
176                 setregid(smGD.conMgmtGID, smGD.runningGID);
177 #else
178                 setgid(smGD.conMgmtGID);
179                 setegid(smGD.runningGID);
180 #endif
181 #endif
182                 return(MEM_NOT_AVAILABLE);
183             }
184         }
185         
186         freemem_loc =  namelist[0].n_value;
187         gpgslim_loc =  namelist[1].n_value;
188         
189         kmem = open(KMEM_FILE, O_RDONLY);
190         if (kmem < 0)
191         {
192 #ifdef __hpux
193             setresgid(-1, smGD.runningGID, -1);
194 #else
195 #ifndef SVR4
196             setregid(smGD.conMgmtGID, smGD.runningGID);
197 #else
198             setgid(smGD.conMgmtGID);
199             setegid(smGD.runningGID);
200 #endif
201 #endif
202             return(MEM_NOT_AVAILABLE);
203         }
204         (void) lseek(kmem, gpgslim_loc, 0);
205 #ifdef mips
206         {
207             fix temp;
208             (void) read(kmem, (char *)&temp, sizeof(fix));
209             gpgslim = FIX_TO_DBL(temp);
210         }
211 #else /* not mips */
212         (void) read(kmem, (char *)&gpgslim, sizeof(int));
213 #endif /* mips */
214         init = 1;
215     }
216     
217     (void) lseek(kmem, freemem_loc, 0);
218 #ifdef mips
219     {
220         fix temp;
221         (void) read(kmem, (char *)&temp, sizeof(fix));
222         freemem = FIX_TO_DBL(temp);
223     }
224 #else /* not mips */
225     (void) read(kmem, (char *)&freemem, sizeof(int));
226 #endif /* mips */
227
228 #ifdef __hpux
229     setresgid(-1, smGD.runningGID, -1);
230 #else
231 #ifndef SVR4
232     setregid(smGD.conMgmtGID, smGD.runningGID);
233 #else
234     setgid(smGD.conMgmtGID);
235     setegid(smGD.runningGID);
236 #endif
237 #endif
238
239     if(freemem >= gpgslim)
240     {
241         return(MEM_NOT_FULL);
242     }
243     else
244     {
245         return(MEM_FULL);
246     }
247 #else /* linux */
248     return(MEM_NOT_FULL);
249 #endif /* linux */
250 }
251
252
253 \f
254 /*************************************<->*************************************
255  *
256  *  WaitForClientMap ()
257  *
258  *
259  *  Description:
260  *  -----------
261  *  This routine waits for the workspace manager to send it information
262  *  about a client being mapped, before returning to start the next client
263  *
264  *
265  *  Inputs:
266  *  ------
267  *
268  * 
269  *  Outputs:
270  *  -------
271  *
272  *  Comments:
273  *  --------
274  * 
275  *************************************<->***********************************/
276 void 
277 WaitForClientMap( void )
278 {
279     XtInputMask         isThere;
280     XEvent              event;
281     XClientMessageEvent *cEvent = (XClientMessageEvent *) &event;
282     XtIntervalId        clientTimerId;
283     
284     XtAddEventHandler(smGD.topLevelWid,
285                       0,
286                       True,
287                       (XtEventHandler)HandleClientMessage,
288                       (XtPointer) NULL);
289     
290     /*
291      * Set a timer which stops the block on waiting for the
292      * client to start.  This value is fetched from the 
293      * waitClientTimeout resource.
294      */
295     clientRunning = False;
296     clientTimeout = False;
297     clientTimerId = XtAppAddTimeOut(smGD.appCon, 
298                                     smRes.waitClientTimeout,
299                                     WaitClientTimeout, NULL);
300     
301     while((clientRunning == False) && (clientTimeout == False))
302     {
303         XtAppProcessEvent(smGD.appCon, XtIMAll);
304     }
305     
306     XtRemoveTimeOut(clientTimerId);
307     XtRemoveEventHandler(smGD.topLevelWid,
308                       0,
309                       True,
310                       (XtEventHandler)HandleClientMessage,
311                       (XtPointer) NULL);
312     return;
313 }
314
315 \f
316 /*************************************<->*************************************
317  *
318  *  WaitClientTimeout
319  *
320  *
321  *  Description:
322  *  -----------
323  *  Timeout procedure the WaitForClientMap routine.  It stops a loop waiting
324  *  for the last started app to get mapped.
325  *
326  *
327  *  Inputs:
328  *  ------
329  *
330  * 
331  *  Outputs:
332  *  -------
333  *  clientTimeout = (global) flag that stops the loop
334  *
335  *  Comments:
336  *  --------
337  * 
338  *************************************<->***********************************/
339 static void 
340 WaitClientTimeout(
341                   XtPointer client_data,
342                   XtIntervalId *id )
343 {
344     clientTimeout = True;
345     return;
346 }
347
348 \f
349 /*************************************<->*************************************
350  *
351  *  HandleClientMessage
352  *
353  *
354  *  Description:
355  *  -----------
356  *  This is the event handler registered to recieve the client message
357  *  from dtwm when a client has beem managed
358  *
359  * 
360  *************************************<->***********************************/
361 static void 
362 HandleClientMessage( Widget smWidget,
363                     XtPointer dummy,
364                     XEvent *event)
365 {
366     if (event->type == ClientMessage)
367     {
368         ProcessClientMessage(event);
369     }
370     return;
371 } /* END OF FUNCTION HandleClientMessage */
372
373