Centralize catgets() calls through MsgCat
CDE has relied upon catgets() implementations following a relaxed interpretation of the XPG internationalization standard that ignored -1, the standard error value returned by catopen, as the catalog argument. However, this same behavior causes segmentation faults with the musl C library. This patch: - Centralizes (with the exception of ToolTalk) all calls to catopen(), catgets(), and catclose() through MsgCat within the DtSvc library. - Prevents calls to catgets() and catclose() that rely upon undefined behavior. - Eliminates a number of bespoke catgets() wrappers, including multiple redundant caching implementations designed to work around a design peculiarity in HP/UX. - Eases building CDE without XPG internationalization support by providing the appropriate macros.
This commit is contained in:
committed by
Jon Trulson
parent
3379999106
commit
a6ea2a2d52
@@ -42,7 +42,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <nl_types.h>
|
||||
#include <Dt/MsgCatP.h>
|
||||
#include "DtSvcLock.h"
|
||||
|
||||
/*****************************************************************************
|
||||
@@ -79,7 +79,7 @@ Dt11GetMessage(
|
||||
_DtSvcProcessLock();
|
||||
if ( NULL == nlmsg_filename || 0 != strcmp(nlmsg_filename, filename) )
|
||||
{
|
||||
nlmsg_fd = catopen(filename, NL_CAT_LOCALE);
|
||||
nlmsg_fd = CATOPEN(filename, NL_CAT_LOCALE);
|
||||
if (nlmsg_filename)
|
||||
{
|
||||
free(nlmsg_filename);
|
||||
@@ -87,7 +87,7 @@ Dt11GetMessage(
|
||||
}
|
||||
nlmsg_filename = strdup(filename);
|
||||
}
|
||||
msg=catgets(nlmsg_fd,set,n,s);
|
||||
msg=CATGETS(nlmsg_fd,set,n,s);
|
||||
_DtSvcProcessUnlock();
|
||||
return (msg);
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
************************************<+>*************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <nl_types.h>
|
||||
#include <Dt/MsgCatP.h>
|
||||
#include "DtSvcLock.h"
|
||||
|
||||
#if !defined(NL_CAT_LOCALE)
|
||||
@@ -80,8 +80,6 @@ _DtGetMessage(
|
||||
{
|
||||
char *msg;
|
||||
char *lang;
|
||||
nl_catd catopen();
|
||||
char *catgets();
|
||||
static int first = 1;
|
||||
static nl_catd nlmsg_fd;
|
||||
|
||||
@@ -89,9 +87,9 @@ _DtGetMessage(
|
||||
if ( first )
|
||||
{
|
||||
first = 0;
|
||||
nlmsg_fd = catopen(filename, NL_CAT_LOCALE);
|
||||
nlmsg_fd = CATOPEN(filename, NL_CAT_LOCALE);
|
||||
}
|
||||
msg=catgets(nlmsg_fd,set,n,s);
|
||||
msg=CATGETS(nlmsg_fd,set,n,s);
|
||||
_DtSvcProcessUnlock();
|
||||
return (msg);
|
||||
}
|
||||
|
||||
@@ -37,11 +37,18 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <nl_types.h>
|
||||
#include <X11/Intrinsic.h>
|
||||
#include <Dt/MsgCatP.h>
|
||||
#include <DtSvcLock.h>
|
||||
|
||||
#if defined(NO_XLIB)
|
||||
#define _DtSvcProcessLock()
|
||||
#define _DtSvcProcessUnlock()
|
||||
#else
|
||||
#include <X11/Intrinsic.h>
|
||||
#include <DtSvcLock.h>
|
||||
#endif /* NO_XLIB */
|
||||
|
||||
#include <Dt/MsgCatP.h>
|
||||
|
||||
#if defined(hpV4) && !defined(NO_XLIB)
|
||||
typedef struct _dt_msg_cache
|
||||
{
|
||||
char ***cached_msgs;
|
||||
@@ -56,8 +63,8 @@ static _DtMsgCache *catalog_message_caches = NULL;
|
||||
|
||||
static _DtMsgCache *get_msg_cache(nl_catd catd)
|
||||
{
|
||||
#define INITIAL_NMSGS_PER_SET 300
|
||||
#define INITIAL_NSETS 50
|
||||
const int initial_nmsgs_per_set = 300;
|
||||
const int initial_nsets = 50;
|
||||
|
||||
_DtMsgCache *c;
|
||||
|
||||
@@ -66,28 +73,23 @@ static _DtMsgCache *get_msg_cache(nl_catd catd)
|
||||
|
||||
c = (_DtMsgCache*) XtMalloc(sizeof(_DtMsgCache));
|
||||
c->cached_msgs = NULL;
|
||||
c->nmsgs_per_set = INITIAL_NMSGS_PER_SET;
|
||||
c->nsets = INITIAL_NSETS;
|
||||
c->nmsgs_per_set = initial_nmsgs_per_set;
|
||||
c->nsets = initial_nsets;
|
||||
c->catd = catd;
|
||||
c->next = catalog_message_caches;
|
||||
catalog_message_caches = c;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Wrapper around catgets -- this makes sure the message string is saved
|
||||
* in a safe location; so repeated calls to catgets() do not overwrite
|
||||
* the catgets() internal buffer. This has been a problem on HP systems.
|
||||
*/
|
||||
char *_DtCatgetsCached(nl_catd catd, int set, int num, char *dflt)
|
||||
char *_DtCatgetsCached(nl_catd catd, int set, int num, const char *dflt)
|
||||
{
|
||||
char *message;
|
||||
|
||||
#if !defined(hpV4)
|
||||
message = catgets(catd, set, num, dflt);
|
||||
#else
|
||||
_DtMsgCache *c;
|
||||
char *message = NULL;
|
||||
_DtMsgCache *c;
|
||||
char **setptr;
|
||||
int i, multiplier;
|
||||
int size;
|
||||
@@ -96,8 +98,6 @@ char *_DtCatgetsCached(nl_catd catd, int set, int num, char *dflt)
|
||||
int setIdx = set - 1;
|
||||
int numIdx = num - 1;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
|
||||
c = get_msg_cache(catd);
|
||||
if (NULL == c)
|
||||
{
|
||||
@@ -150,8 +150,32 @@ char *_DtCatgetsCached(nl_catd catd, int set, int num, char *dflt)
|
||||
|
||||
message = setptr[numIdx];
|
||||
|
||||
_DtSvcProcessUnlock();
|
||||
#endif /* hpV4 */
|
||||
|
||||
return message;
|
||||
}
|
||||
#endif /* hpV4 */
|
||||
|
||||
int _DtCatclose(nl_catd catd)
|
||||
{
|
||||
return (catd == (nl_catd) -1) ? 0 : catclose(catd);
|
||||
}
|
||||
|
||||
char *_DtCatgets(nl_catd catd, int set, int num, const char *dflt)
|
||||
{
|
||||
char *msg = NULL;
|
||||
|
||||
if (catd == (nl_catd) -1 || set < 0 || num < 0) {
|
||||
/* Some catgets() implementations will fault if catd is invalid. */
|
||||
msg = (char *) dflt;
|
||||
} else {
|
||||
/* Per POSIX, we cannot assume catgets() is thread-safe. */
|
||||
_DtSvcProcessLock();
|
||||
#if defined(hpV4) && !defined(NO_XLIB)
|
||||
msg = _DtCatgetsCached(catd, set, num, dflt);
|
||||
#else
|
||||
msg = catgets(catd, set, num, dflt);
|
||||
#endif /* hpV4 */
|
||||
_DtSvcProcessUnlock();
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user