Error.c revision 444c061a
1444c061aSmrg/* $Xorg: Error.c,v 1.5 2001/02/09 02:03:54 xorgcvs Exp $ */
2444c061aSmrg
3444c061aSmrg/***********************************************************
4444c061aSmrgCopyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts
5444c061aSmrgCopyright 1993 by Sun Microsystems, Inc. Mountain View, CA.
6444c061aSmrg
7444c061aSmrg                        All Rights Reserved
8444c061aSmrg
9444c061aSmrgPermission to use, copy, modify, and distribute this software and its
10444c061aSmrgdocumentation for any purpose and without fee is hereby granted,
11444c061aSmrgprovided that the above copyright notice appear in all copies and that
12444c061aSmrgboth that copyright notice and this permission notice appear in
13444c061aSmrgsupporting documentation, and that the names of Digital or Sun not be
14444c061aSmrgused in advertising or publicity pertaining to distribution of the
15444c061aSmrgsoftware without specific, written prior permission.
16444c061aSmrg
17444c061aSmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
18444c061aSmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
19444c061aSmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
20444c061aSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
21444c061aSmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
22444c061aSmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
23444c061aSmrgSOFTWARE.
24444c061aSmrg
25444c061aSmrgSUN DISCLAIMS ALL WARRANTIES WITH REGARD TO  THIS  SOFTWARE,
26444c061aSmrgINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
27444c061aSmrgNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE  LI-
28444c061aSmrgABLE  FOR  ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
29444c061aSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,  DATA  OR
30444c061aSmrgPROFITS,  WHETHER  IN  AN  ACTION OF CONTRACT, NEGLIGENCE OR
31444c061aSmrgOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
32444c061aSmrgTHE USE OR PERFORMANCE OF THIS SOFTWARE.
33444c061aSmrg
34444c061aSmrg******************************************************************/
35444c061aSmrg/* $XFree86: xc/lib/Xt/Error.c,v 3.13tsi Exp $ */
36444c061aSmrg
37444c061aSmrg/*
38444c061aSmrg
39444c061aSmrgCopyright 1987, 1988, 1998  The Open Group
40444c061aSmrg
41444c061aSmrgPermission to use, copy, modify, distribute, and sell this software and its
42444c061aSmrgdocumentation for any purpose is hereby granted without fee, provided that
43444c061aSmrgthe above copyright notice appear in all copies and that both that
44444c061aSmrgcopyright notice and this permission notice appear in supporting
45444c061aSmrgdocumentation.
46444c061aSmrg
47444c061aSmrgThe above copyright notice and this permission notice shall be included in
48444c061aSmrgall copies or substantial portions of the Software.
49444c061aSmrg
50444c061aSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
51444c061aSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
52444c061aSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
53444c061aSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
54444c061aSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
55444c061aSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
56444c061aSmrg
57444c061aSmrgExcept as contained in this notice, the name of The Open Group shall not be
58444c061aSmrgused in advertising or otherwise to promote the sale, use or other dealings
59444c061aSmrgin this Software without prior written authorization from The Open Group.
60444c061aSmrg
61444c061aSmrg*/
62444c061aSmrg
63444c061aSmrg#ifdef HAVE_CONFIG_H
64444c061aSmrg#include <config.h>
65444c061aSmrg#endif
66444c061aSmrg#include "IntrinsicI.h"
67444c061aSmrg#include <stdio.h>
68444c061aSmrg#include <stdlib.h>
69444c061aSmrg
70444c061aSmrg/* The error handlers in the application context aren't used since we can't
71444c061aSmrg   come up with a uniform way of using them.  If you can, define
72444c061aSmrg   GLOBALERRORS to be FALSE (or 0). */
73444c061aSmrg
74444c061aSmrg#ifndef GLOBALERRORS
75444c061aSmrg#define GLOBALERRORS 1
76444c061aSmrg#endif
77444c061aSmrg
78444c061aSmrgstatic void InitErrorHandling(XrmDatabase *);
79444c061aSmrg#if GLOBALERRORS
80444c061aSmrgstatic XrmDatabase errorDB = NULL;
81444c061aSmrgstatic Boolean error_inited = FALSE;
82444c061aSmrgvoid _XtDefaultErrorMsg(String, String, String, String, String*, Cardinal*);
83444c061aSmrgvoid _XtDefaultWarningMsg(String, String, String, String, String*, Cardinal*);
84444c061aSmrgvoid _XtDefaultError(String);
85444c061aSmrgvoid _XtDefaultWarning(String);
86444c061aSmrgstatic XtErrorMsgHandler errorMsgHandler = _XtDefaultErrorMsg;
87444c061aSmrgstatic XtErrorMsgHandler warningMsgHandler = _XtDefaultWarningMsg;
88444c061aSmrgstatic XtErrorHandler errorHandler = _XtDefaultError;
89444c061aSmrgstatic XtErrorHandler warningHandler = _XtDefaultWarning;
90444c061aSmrg#endif /* GLOBALERRORS */
91444c061aSmrg
92444c061aSmrgXrmDatabase *XtGetErrorDatabase(void)
93444c061aSmrg{
94444c061aSmrg    XrmDatabase* retval;
95444c061aSmrg#if GLOBALERRORS
96444c061aSmrg    LOCK_PROCESS;
97444c061aSmrg    retval = &errorDB;
98444c061aSmrg    UNLOCK_PROCESS;
99444c061aSmrg#else
100444c061aSmrg    retval = XtAppGetErrorDatabase(_XtDefaultAppContext());
101444c061aSmrg#endif /* GLOBALERRORS */
102444c061aSmrg    return retval;
103444c061aSmrg}
104444c061aSmrg
105444c061aSmrgXrmDatabase *XtAppGetErrorDatabase(
106444c061aSmrg	XtAppContext app)
107444c061aSmrg{
108444c061aSmrg    XrmDatabase* retval;
109444c061aSmrg#if GLOBALERRORS
110444c061aSmrg    LOCK_PROCESS;
111444c061aSmrg    retval = &errorDB;
112444c061aSmrg    UNLOCK_PROCESS;
113444c061aSmrg#else
114444c061aSmrg    LOCK_APP(app);
115444c061aSmrg    retval= &app->errorDB;
116444c061aSmrg    UNLOCK_APP(app);
117444c061aSmrg#endif /* GLOBALERRORS */
118444c061aSmrg    return retval;
119444c061aSmrg}
120444c061aSmrg
121444c061aSmrgvoid XtGetErrorDatabaseText(
122444c061aSmrg    register _Xconst char* name,
123444c061aSmrg    register _Xconst char* type,
124444c061aSmrg    register _Xconst char* class,
125444c061aSmrg    _Xconst char* defaultp,
126444c061aSmrg    String buffer,
127444c061aSmrg    int nbytes)
128444c061aSmrg{
129444c061aSmrg#if GLOBALERRORS
130444c061aSmrg    XtAppGetErrorDatabaseText(NULL,
131444c061aSmrg	    name,type,class,defaultp, buffer, nbytes, NULL);
132444c061aSmrg#else
133444c061aSmrg    XtAppGetErrorDatabaseText(_XtDefaultAppContext(),
134444c061aSmrg	    name,type,class,defaultp, buffer, nbytes, NULL);
135444c061aSmrg#endif /* GLOBALERRORS */
136444c061aSmrg}
137444c061aSmrg
138444c061aSmrgvoid XtAppGetErrorDatabaseText(
139444c061aSmrg    XtAppContext app,
140444c061aSmrg    register _Xconst char* name,
141444c061aSmrg    register _Xconst char* type,
142444c061aSmrg    register _Xconst char* class,
143444c061aSmrg    _Xconst char* defaultp,
144444c061aSmrg    String buffer,
145444c061aSmrg    int nbytes,
146444c061aSmrg    XrmDatabase db)
147444c061aSmrg{
148444c061aSmrg    String str_class;
149444c061aSmrg    String type_str;
150444c061aSmrg    XrmValue result;
151444c061aSmrg    char *str_name = NULL;
152444c061aSmrg    char *temp = NULL;
153444c061aSmrg
154444c061aSmrg#if GLOBALERRORS
155444c061aSmrg    LOCK_PROCESS;
156444c061aSmrg    if (error_inited == FALSE) {
157444c061aSmrg        InitErrorHandling (&errorDB);
158444c061aSmrg        error_inited = TRUE;
159444c061aSmrg    }
160444c061aSmrg#else
161444c061aSmrg    LOCK_APP(app);
162444c061aSmrg    if (app->error_inited == FALSE) {
163444c061aSmrg        InitErrorHandling (&app->errorDB);
164444c061aSmrg        app->error_inited = TRUE;
165444c061aSmrg    }
166444c061aSmrg#endif /* GLOBALERRORS */
167444c061aSmrg    if (!(str_name = ALLOCATE_LOCAL(strlen(name) + strlen(type) + 2)))
168444c061aSmrg	_XtAllocError(NULL);
169444c061aSmrg    (void) sprintf(str_name, "%s.%s", name, type);
170444c061aSmrg    /* XrmGetResource requires the name and class to be fully qualified
171444c061aSmrg     * and to have the same number of components. */
172444c061aSmrg    str_class = (char *)class;
173444c061aSmrg    if (! strchr(class, '.')) {
174444c061aSmrg	if (!(temp = ALLOCATE_LOCAL(2 * strlen(class) + 2)))
175444c061aSmrg	    _XtAllocError(NULL);
176444c061aSmrg	(void) sprintf(temp, "%s.%s", class, class);
177444c061aSmrg	str_class = temp;
178444c061aSmrg    }
179444c061aSmrg    if (db == NULL) {
180444c061aSmrg#if GLOBALERRORS
181444c061aSmrg	(void) XrmGetResource(errorDB, str_name, str_class, &type_str,
182444c061aSmrg			      &result);
183444c061aSmrg#else
184444c061aSmrg	(void) XrmGetResource(app->errorDB, str_name, str_class, &type_str,
185444c061aSmrg			      &result);
186444c061aSmrg#endif /* GLOBALERRORS */
187444c061aSmrg    } else (void) XrmGetResource(db, str_name, str_class, &type_str, &result);
188444c061aSmrg    if (result.addr) {
189444c061aSmrg        (void) strncpy (buffer, result.addr, nbytes);
190444c061aSmrg        if (result.size > (unsigned) nbytes) buffer[nbytes-1] = 0;
191444c061aSmrg    } else {
192444c061aSmrg	int len = strlen(defaultp);
193444c061aSmrg	if (len >= nbytes) len = nbytes-1;
194444c061aSmrg	(void) memmove(buffer, defaultp, len);
195444c061aSmrg	buffer[len] = '\0';
196444c061aSmrg    }
197444c061aSmrg    if (str_name)
198444c061aSmrg	DEALLOCATE_LOCAL(str_name);
199444c061aSmrg    if (temp)
200444c061aSmrg	DEALLOCATE_LOCAL(temp);
201444c061aSmrg#if GLOBALERRORS
202444c061aSmrg    UNLOCK_PROCESS;
203444c061aSmrg#else
204444c061aSmrg    UNLOCK_APP(app);
205444c061aSmrg#endif
206444c061aSmrg}
207444c061aSmrg
208444c061aSmrgstatic void InitErrorHandling (
209444c061aSmrg    XrmDatabase *db)
210444c061aSmrg{
211444c061aSmrg    XrmDatabase errordb;
212444c061aSmrg
213444c061aSmrg    errordb = XrmGetFileDatabase(ERRORDB);
214444c061aSmrg    XrmMergeDatabases(errordb, db);
215444c061aSmrg}
216444c061aSmrg
217444c061aSmrgstatic void DefaultMsg (
218444c061aSmrg    String name,
219444c061aSmrg    String type,
220444c061aSmrg    String class,
221444c061aSmrg    String defaultp,
222444c061aSmrg    String* params,
223444c061aSmrg    Cardinal* num_params,
224444c061aSmrg    Bool error,
225444c061aSmrg    void (*fn)(_Xconst _XtString))
226444c061aSmrg{
227444c061aSmrg#define BIGBUF 1024
228444c061aSmrg#ifdef notyet /* older versions don't, might want to wait until more do */
229444c061aSmrg#if defined(__linux__)  || defined(CSRG_BASED) /* everyone else needs to get with the program */
230444c061aSmrg#define USE_SNPRINTF
231444c061aSmrg#endif
232444c061aSmrg#endif
233444c061aSmrg    char buffer[BIGBUF];
234444c061aSmrg    char* message;
235444c061aSmrg    XtGetErrorDatabaseText(name,type,class,defaultp, buffer, BIGBUF);
236444c061aSmrg/*need better solution here, perhaps use lower level printf primitives? */
237444c061aSmrg    if (params == NULL || num_params == NULL || *num_params == 0)
238444c061aSmrg	(*fn)(buffer);
239444c061aSmrg#ifndef WIN32 /* and OS/2 */
240444c061aSmrg    else if ((getuid () != geteuid ()) || getuid() == 0) {
241444c061aSmrg	if ((error && errorHandler == _XtDefaultError) ||
242444c061aSmrg	    (!error && warningHandler == _XtDefaultWarning)) {
243444c061aSmrg	    /*
244444c061aSmrg	     * if it's just going to go to stderr anyway, then we'll
245444c061aSmrg	     * fprintf to stderr ourselves and skip the insecure sprintf.
246444c061aSmrg	     */
247444c061aSmrg	    Cardinal i = *num_params;
248444c061aSmrg	    String par[10];
249444c061aSmrg	    if (i > 10) i = 10;
250444c061aSmrg	    (void) memmove((char*)par, (char*)params, i * sizeof(String) );
251444c061aSmrg	    bzero( &par[i], (10-i) * sizeof(String) );
252444c061aSmrg	    (void) fprintf (stderr, "%s%s",
253444c061aSmrg			    error ? XTERROR_PREFIX : XTWARNING_PREFIX,
254444c061aSmrg			    error ? "Error: " : "Warning: ");
255444c061aSmrg	    (void) fprintf (stderr, buffer,
256444c061aSmrg			    par[0], par[1], par[2], par[3], par[4],
257444c061aSmrg			    par[5], par[6], par[7], par[8], par[9]);
258444c061aSmrg	    (void) fprintf (stderr, "%c", '\n');
259444c061aSmrg	    if (i != *num_params)
260444c061aSmrg		(*fn) ( "Some arguments in previous message were lost" );
261444c061aSmrg	    else if (error) exit (1);
262444c061aSmrg	} else {
263444c061aSmrg	    /*
264444c061aSmrg	     * can't tell what it might do, so we'll play it safe
265444c061aSmrg	     */
266444c061aSmrg	    XtWarning ("\
267444c061aSmrgThis program is an suid-root program or is being run by the root user.\n\
268444c061aSmrgThe full text of the error or warning message cannot be safely formatted\n\
269444c061aSmrgin this environment. You may get a more descriptive message by running the\n\
270444c061aSmrgprogram as a non-root user or by removing the suid bit on the executable.");
271444c061aSmrg	    (*fn)(buffer); /* if *fn is an ErrorHandler it should exit */
272444c061aSmrg	}
273444c061aSmrg    }
274444c061aSmrg#endif
275444c061aSmrg    else {
276444c061aSmrg	/*
277444c061aSmrg	 * If you have snprintf the worst thing that could happen is you'd
278444c061aSmrg	 * lose some information. Without snprintf you're probably going to
279444c061aSmrg	 * scramble your heap and perhaps SEGV -- sooner or later.
280444c061aSmrg	 * If it hurts when you go like this then don't go like this! :-)
281444c061aSmrg	 */
282444c061aSmrg	Cardinal i = *num_params;
283444c061aSmrg	String par[10];
284444c061aSmrg	if (i > 10) i = 10;
285444c061aSmrg	(void) memmove((char*)par, (char*)params, i * sizeof(String) );
286444c061aSmrg	bzero( &par[i], (10-i) * sizeof(String) );
287444c061aSmrg	if (i != *num_params)
288444c061aSmrg	    XtWarning( "Some arguments in following message were lost" );
289444c061aSmrg	/*
290444c061aSmrg	 * resist any temptation you might have to make `message' a
291444c061aSmrg	 * local buffer on the stack. Doing so is a security hole
292444c061aSmrg	 * in programs executing as root. Error and Warning
293444c061aSmrg	 * messages shouldn't be called frequently enough for this
294444c061aSmrg	 * to be a performance issue.
295444c061aSmrg	 */
296444c061aSmrg	if ((message = __XtMalloc (BIGBUF))) {
297444c061aSmrg#ifndef USE_SNPRINTF
298444c061aSmrg	    message[BIGBUF-1] = 0;
299444c061aSmrg	    (void) sprintf (message, buffer,
300444c061aSmrg#else
301444c061aSmrg	    (void) snprintf (message, BIGBUF, buffer,
302444c061aSmrg#endif
303444c061aSmrg			    par[0], par[1], par[2], par[3], par[4],
304444c061aSmrg			    par[5], par[6], par[7], par[8], par[9]);
305444c061aSmrg#ifndef USE_SNPRINTF
306444c061aSmrg	    if (message[BIGBUF-1] != '\0')
307444c061aSmrg		XtWarning ("Possible heap corruption in Xt{Error,Warning}MsgHandler");
308444c061aSmrg#endif
309444c061aSmrg	    (*fn)(message);
310444c061aSmrg	    XtFree(message);
311444c061aSmrg	} else {
312444c061aSmrg	    XtWarning ("Memory allocation failed, arguments in the following message were lost");
313444c061aSmrg	    (*fn)(buffer);
314444c061aSmrg	}
315444c061aSmrg    }
316444c061aSmrg}
317444c061aSmrg
318444c061aSmrgvoid _XtDefaultErrorMsg (
319444c061aSmrg    String name,
320444c061aSmrg    String type,
321444c061aSmrg    String class,
322444c061aSmrg    String defaultp,
323444c061aSmrg    String* params,
324444c061aSmrg    Cardinal* num_params)
325444c061aSmrg{
326444c061aSmrg    DefaultMsg (name,type,class,defaultp,params,num_params,True,XtError);
327444c061aSmrg}
328444c061aSmrg
329444c061aSmrgvoid _XtDefaultWarningMsg (
330444c061aSmrg    String name,
331444c061aSmrg    String type,
332444c061aSmrg    String class,
333444c061aSmrg    String defaultp,
334444c061aSmrg    String* params,
335444c061aSmrg    Cardinal* num_params)
336444c061aSmrg{
337444c061aSmrg    DefaultMsg (name,type,class,defaultp,params,num_params,False,XtWarning);
338444c061aSmrg}
339444c061aSmrg
340444c061aSmrgvoid XtErrorMsg(
341444c061aSmrg    _Xconst char* name,
342444c061aSmrg    _Xconst char* type,
343444c061aSmrg    _Xconst char* class,
344444c061aSmrg    _Xconst char* defaultp,
345444c061aSmrg    String* params,
346444c061aSmrg    Cardinal* num_params)
347444c061aSmrg{
348444c061aSmrg#if GLOBALERRORS
349444c061aSmrg    LOCK_PROCESS;
350444c061aSmrg    (*errorMsgHandler)((String)name,(String)type,(String)class,
351444c061aSmrg		       (String)defaultp,params,num_params);
352444c061aSmrg    UNLOCK_PROCESS;
353444c061aSmrg#else
354444c061aSmrg    XtAppErrorMsg(_XtDefaultAppContext(),name,type,class,
355444c061aSmrg	    defaultp,params,num_params);
356444c061aSmrg#endif /* GLOBALERRORS */
357444c061aSmrg}
358444c061aSmrg
359444c061aSmrgvoid XtAppErrorMsg(
360444c061aSmrg    XtAppContext app,
361444c061aSmrg    _Xconst char* name,
362444c061aSmrg    _Xconst char* type,
363444c061aSmrg    _Xconst char* class,
364444c061aSmrg    _Xconst char* defaultp,
365444c061aSmrg    String* params,
366444c061aSmrg    Cardinal* num_params)
367444c061aSmrg{
368444c061aSmrg#if GLOBALERRORS
369444c061aSmrg    LOCK_PROCESS;
370444c061aSmrg    (*errorMsgHandler)((String)name,(String)type,(String)class,
371444c061aSmrg		       (String)defaultp,params,num_params);
372444c061aSmrg    UNLOCK_PROCESS;
373444c061aSmrg#else
374444c061aSmrg    LOCK_APP(app);
375444c061aSmrg    (*app->errorMsgHandler)(name,type,class,defaultp,params,num_params);
376444c061aSmrg    UNLOCK_APP(app);
377444c061aSmrg#endif /* GLOBALERRORS */
378444c061aSmrg}
379444c061aSmrg
380444c061aSmrgvoid XtWarningMsg(
381444c061aSmrg    _Xconst char* name,
382444c061aSmrg    _Xconst char* type,
383444c061aSmrg    _Xconst char* class,
384444c061aSmrg    _Xconst char* defaultp,
385444c061aSmrg    String* params,
386444c061aSmrg    Cardinal* num_params)
387444c061aSmrg{
388444c061aSmrg#if GLOBALERRORS
389444c061aSmrg    LOCK_PROCESS;
390444c061aSmrg    (*warningMsgHandler)((String)name,(String)type,(String)class,
391444c061aSmrg			 (String)defaultp,params,num_params);
392444c061aSmrg    UNLOCK_PROCESS;
393444c061aSmrg#else
394444c061aSmrg    XtAppWarningMsg(_XtDefaultAppContext(),name,type,class,
395444c061aSmrg	    defaultp,params,num_params);
396444c061aSmrg#endif /* GLOBALERRORS */
397444c061aSmrg}
398444c061aSmrg
399444c061aSmrgvoid XtAppWarningMsg(
400444c061aSmrg    XtAppContext app,
401444c061aSmrg    _Xconst char* name,
402444c061aSmrg    _Xconst char* type,
403444c061aSmrg    _Xconst char* class,
404444c061aSmrg    _Xconst char* defaultp,
405444c061aSmrg    String* params,
406444c061aSmrg    Cardinal* num_params)
407444c061aSmrg{
408444c061aSmrg#if GLOBALERRORS
409444c061aSmrg    LOCK_PROCESS;
410444c061aSmrg    (*warningMsgHandler)((String)name,(String)type,(String)class,
411444c061aSmrg			 (String)defaultp,params,num_params);
412444c061aSmrg    UNLOCK_PROCESS;
413444c061aSmrg#else
414444c061aSmrg    LOCK_APP(app);
415444c061aSmrg    (*app->warningMsgHandler)(name,type,class,defaultp,params,num_params);
416444c061aSmrg    UNLOCK_APP(app);
417444c061aSmrg#endif /* GLOBALERRORS */
418444c061aSmrg}
419444c061aSmrg
420444c061aSmrgvoid XtSetErrorMsgHandler(
421444c061aSmrg    XtErrorMsgHandler handler)
422444c061aSmrg{
423444c061aSmrg#if GLOBALERRORS
424444c061aSmrg    LOCK_PROCESS;
425444c061aSmrg    if (handler != NULL) errorMsgHandler = handler;
426444c061aSmrg    else errorMsgHandler  = _XtDefaultErrorMsg;
427444c061aSmrg    UNLOCK_PROCESS;
428444c061aSmrg#else
429444c061aSmrg    XtAppSetErrorMsgHandler(_XtDefaultAppContext(), handler);
430444c061aSmrg#endif /* GLOBALERRORS */
431444c061aSmrg}
432444c061aSmrg
433444c061aSmrgXtErrorMsgHandler XtAppSetErrorMsgHandler(
434444c061aSmrg    XtAppContext app,
435444c061aSmrg    XtErrorMsgHandler handler)
436444c061aSmrg{
437444c061aSmrg    XtErrorMsgHandler old;
438444c061aSmrg#if GLOBALERRORS
439444c061aSmrg    LOCK_PROCESS;
440444c061aSmrg    old = errorMsgHandler;
441444c061aSmrg    if (handler != NULL) errorMsgHandler = handler;
442444c061aSmrg    else errorMsgHandler  = _XtDefaultErrorMsg;
443444c061aSmrg    UNLOCK_PROCESS;
444444c061aSmrg#else
445444c061aSmrg    LOCK_APP(app);
446444c061aSmrg    old = app->errorMsgHandler;
447444c061aSmrg    if (handler != NULL) app->errorMsgHandler = handler;
448444c061aSmrg    else app->errorMsgHandler  = _XtDefaultErrorMsg;
449444c061aSmrg    UNLOCK_APP(app);
450444c061aSmrg#endif /* GLOBALERRORS */
451444c061aSmrg    return old;
452444c061aSmrg}
453444c061aSmrg
454444c061aSmrgvoid XtSetWarningMsgHandler(
455444c061aSmrg    XtErrorMsgHandler handler)
456444c061aSmrg{
457444c061aSmrg#if GLOBALERRORS
458444c061aSmrg    LOCK_PROCESS;
459444c061aSmrg    if (handler != NULL) warningMsgHandler  = handler;
460444c061aSmrg    else warningMsgHandler = _XtDefaultWarningMsg;
461444c061aSmrg    UNLOCK_PROCESS;
462444c061aSmrg#else
463444c061aSmrg    XtAppSetWarningMsgHandler(_XtDefaultAppContext(),handler);
464444c061aSmrg#endif /* GLOBALERRORS */
465444c061aSmrg}
466444c061aSmrg
467444c061aSmrgXtErrorMsgHandler XtAppSetWarningMsgHandler(
468444c061aSmrg    XtAppContext app,
469444c061aSmrg    XtErrorMsgHandler handler)
470444c061aSmrg{
471444c061aSmrg    XtErrorMsgHandler old;
472444c061aSmrg#if GLOBALERRORS
473444c061aSmrg    LOCK_PROCESS;
474444c061aSmrg    old = warningMsgHandler;
475444c061aSmrg    if (handler != NULL) warningMsgHandler  = handler;
476444c061aSmrg    else warningMsgHandler = _XtDefaultWarningMsg;
477444c061aSmrg    UNLOCK_PROCESS;
478444c061aSmrg#else
479444c061aSmrg    LOCK_APP(app);
480444c061aSmrg    old = app->warningMsgHandler;
481444c061aSmrg    if (handler != NULL) app->warningMsgHandler  = handler;
482444c061aSmrg    else app->warningMsgHandler = _XtDefaultWarningMsg;
483444c061aSmrg    UNLOCK_APP(app);
484444c061aSmrg#endif /* GLOBALERRORS */
485444c061aSmrg    return old;
486444c061aSmrg}
487444c061aSmrg
488444c061aSmrgvoid _XtDefaultError(String message)
489444c061aSmrg{
490444c061aSmrg    if (message && *message)
491444c061aSmrg	(void)fprintf(stderr, "%sError: %s\n", XTERROR_PREFIX, message);
492444c061aSmrg    exit(1);
493444c061aSmrg}
494444c061aSmrg
495444c061aSmrgvoid _XtDefaultWarning(String message)
496444c061aSmrg{
497444c061aSmrg    if (message && *message)
498444c061aSmrg       (void)fprintf(stderr, "%sWarning: %s\n", XTWARNING_PREFIX, message);
499444c061aSmrg    return;
500444c061aSmrg}
501444c061aSmrg
502444c061aSmrgvoid XtError(
503444c061aSmrg    _Xconst char* message)
504444c061aSmrg{
505444c061aSmrg#if GLOBALERRORS
506444c061aSmrg    LOCK_PROCESS;
507444c061aSmrg    (*errorHandler)((String)message);
508444c061aSmrg    UNLOCK_PROCESS;
509444c061aSmrg#else
510444c061aSmrg    XtAppError(_XtDefaultAppContext(),message);
511444c061aSmrg#endif /* GLOBALERRORS */
512444c061aSmrg}
513444c061aSmrg
514444c061aSmrgvoid XtAppError(
515444c061aSmrg    XtAppContext app,
516444c061aSmrg    _Xconst char* message)
517444c061aSmrg{
518444c061aSmrg#if GLOBALERRORS
519444c061aSmrg    LOCK_PROCESS;
520444c061aSmrg    (*errorHandler)((String)message);
521444c061aSmrg    UNLOCK_PROCESS;
522444c061aSmrg#else
523444c061aSmrg    LOCK_APP(app);
524444c061aSmrg    (*app->errorHandler)(message);
525444c061aSmrg    UNLOCK_APP(app);
526444c061aSmrg#endif /* GLOBALERRORS */
527444c061aSmrg}
528444c061aSmrg
529444c061aSmrgvoid XtWarning(
530444c061aSmrg    _Xconst char* message)
531444c061aSmrg{
532444c061aSmrg#if GLOBALERRORS
533444c061aSmrg    LOCK_PROCESS;
534444c061aSmrg    (*warningHandler)((String)message);
535444c061aSmrg    UNLOCK_PROCESS;
536444c061aSmrg#else
537444c061aSmrg    XtAppWarning(_XtDefaultAppContext(),message);
538444c061aSmrg#endif /* GLOBALERRORS */
539444c061aSmrg}
540444c061aSmrg
541444c061aSmrgvoid XtAppWarning(
542444c061aSmrg    XtAppContext app,
543444c061aSmrg    _Xconst char* message)
544444c061aSmrg{
545444c061aSmrg#if GLOBALERRORS
546444c061aSmrg    LOCK_PROCESS;
547444c061aSmrg    (*warningHandler)((String)message);
548444c061aSmrg    UNLOCK_PROCESS;
549444c061aSmrg#else
550444c061aSmrg    LOCK_APP(app);
551444c061aSmrg    (*app->warningHandler)(message);
552444c061aSmrg    UNLOCK_APP(app);
553444c061aSmrg#endif /* GLOBALERRORS */
554444c061aSmrg}
555444c061aSmrg
556444c061aSmrgvoid XtSetErrorHandler(XtErrorHandler handler)
557444c061aSmrg{
558444c061aSmrg#if GLOBALERRORS
559444c061aSmrg    LOCK_PROCESS;
560444c061aSmrg    if (handler != NULL) errorHandler = handler;
561444c061aSmrg    else errorHandler  = _XtDefaultError;
562444c061aSmrg    UNLOCK_PROCESS;
563444c061aSmrg#else
564444c061aSmrg    XtAppSetErrorHandler(_XtDefaultAppContext(),handler);
565444c061aSmrg#endif /* GLOBALERRORS */
566444c061aSmrg}
567444c061aSmrg
568444c061aSmrgXtErrorHandler XtAppSetErrorHandler(
569444c061aSmrg    XtAppContext app,
570444c061aSmrg    XtErrorHandler handler)
571444c061aSmrg{
572444c061aSmrg    XtErrorHandler old;
573444c061aSmrg#if GLOBALERRORS
574444c061aSmrg    LOCK_PROCESS;
575444c061aSmrg    old = errorHandler;
576444c061aSmrg    if (handler != NULL) errorHandler = handler;
577444c061aSmrg    else errorHandler  = _XtDefaultError;
578444c061aSmrg    UNLOCK_PROCESS;
579444c061aSmrg#else
580444c061aSmrg    LOCK_APP(app);
581444c061aSmrg    old = app->errorHandler;
582444c061aSmrg    if (handler != NULL) app->errorHandler = handler;
583444c061aSmrg    else app->errorHandler  = _XtDefaultError;
584444c061aSmrg    UNLOCK_APP(app);
585444c061aSmrg#endif /* GLOBALERRORS */
586444c061aSmrg    return old;
587444c061aSmrg}
588444c061aSmrg
589444c061aSmrgvoid XtSetWarningHandler(XtErrorHandler handler)
590444c061aSmrg{
591444c061aSmrg#if GLOBALERRORS
592444c061aSmrg    LOCK_PROCESS;
593444c061aSmrg    if (handler != NULL) warningHandler = handler;
594444c061aSmrg    else warningHandler = _XtDefaultWarning;
595444c061aSmrg    UNLOCK_PROCESS;
596444c061aSmrg#else
597444c061aSmrg    XtAppSetWarningHandler(_XtDefaultAppContext(),handler);
598444c061aSmrg#endif /* GLOBALERRORS */
599444c061aSmrg}
600444c061aSmrg
601444c061aSmrgXtErrorHandler XtAppSetWarningHandler(
602444c061aSmrg    XtAppContext app,
603444c061aSmrg    XtErrorHandler handler)
604444c061aSmrg{
605444c061aSmrg    XtErrorHandler old;
606444c061aSmrg#if GLOBALERRORS
607444c061aSmrg    LOCK_PROCESS;
608444c061aSmrg    old = warningHandler;
609444c061aSmrg    if (handler != NULL) warningHandler  = handler;
610444c061aSmrg    else warningHandler = _XtDefaultWarning;
611444c061aSmrg    UNLOCK_PROCESS;
612444c061aSmrg#else
613444c061aSmrg    LOCK_APP(app);
614444c061aSmrg    old = app->warningHandler;
615444c061aSmrg    if (handler != NULL) app->warningHandler  = handler;
616444c061aSmrg    else app->warningHandler = _XtDefaultWarning;
617444c061aSmrg    UNLOCK_APP(app);
618444c061aSmrg#endif /* GLOBALERRORS */
619444c061aSmrg    return old;
620444c061aSmrg}
621444c061aSmrg
622444c061aSmrgvoid _XtSetDefaultErrorHandlers(
623444c061aSmrg    XtErrorMsgHandler *errMsg,
624444c061aSmrg    XtErrorMsgHandler *warnMsg,
625444c061aSmrg    XtErrorHandler *err,
626444c061aSmrg    XtErrorHandler *warn)
627444c061aSmrg{
628444c061aSmrg#ifndef GLOBALERRORS
629444c061aSmrg    LOCK_PROCESS;
630444c061aSmrg    *errMsg = _XtDefaultErrorMsg;
631444c061aSmrg    *warnMsg = _XtDefaultWarningMsg;
632444c061aSmrg    *err = _XtDefaultError;
633444c061aSmrg    *warn = _XtDefaultWarning;
634444c061aSmrg    UNLOCK_PROCESS;
635444c061aSmrg#endif /* GLOBALERRORS */
636444c061aSmrg}
637