diff --git a/src/cmd/ksh93/include/shell.h b/src/cmd/ksh93/include/shell.h index bffe18b944d1..659c6d28e93a 100644 --- a/src/cmd/ksh93/include/shell.h +++ b/src/cmd/ksh93/include/shell.h @@ -80,7 +80,7 @@ typedef union Shnode_u Shnode_t; #define SH_INIT 15 /* set when initializing the shell */ #define SH_TTYWAIT 16 /* waiting for keyboard input */ #define SH_FCOMPLETE 17 /* set for filename completion */ -#define SH_PREINIT 18 /* set with SH_INIT before parsing options */ +#define SH_LCINIT 18 /* set with SH_INIT while initializing locale */ #define SH_COMPLETE 19 /* set for command completion */ #define SH_XARG 21 /* set while in xarg (command -x) mode */ #define SH_NOTILDEXP 22 /* set to disable tilde expansion */ diff --git a/src/cmd/ksh93/sh/init.c b/src/cmd/ksh93/sh/init.c index 17d1243013e6..eeeb4973d096 100644 --- a/src/cmd/ksh93/sh/init.c +++ b/src/cmd/ksh93/sh/init.c @@ -424,11 +424,33 @@ static void put_cdpath(Namval_t* np,const char *val,int flags,Namfun_t *fp) sh.cdpathlist = path_addpath((Pathcomp_t*)sh.cdpathlist,val,PATH_CDPATH); } +static struct put_lang_defer_s +{ + Namval_t *np; + const char *val; + int flags; + Namfun_t *fp; + struct put_lang_defer_s *next; +} *put_lang_defer; + /* Trap for the LC_* and LANG variables */ static void put_lang(Namval_t* np,const char *val,int flags,Namfun_t *fp) { int type; - char *name = nv_name(np); + char *name; + if (val && sh_isstate(SH_INIT) && !sh_isstate(SH_LCINIT)) + { + /* defer setting locale while importing environment */ + struct put_lang_defer_s *p = sh_malloc(sizeof(struct put_lang_defer_s)); + p->np = np; + p->val = val; + p->flags = flags; + p->fp = fp; + p->next = put_lang_defer; + put_lang_defer = p; + return; + } + name = nv_name(np); if(name==(LCALLNOD)->nvname) type = LC_ALL; else if(name==(LCTYPENOD)->nvname) @@ -454,13 +476,9 @@ static void put_lang(Namval_t* np,const char *val,int flags,Namfun_t *fp) if(type>=0 || type==LC_ALL || type==LC_NUMERIC || type==LC_LANG) { char* r; -#ifdef AST_LC_setenv ast.locale.set |= AST_LC_setenv; -#endif r = setlocale(type,val?val:""); -#ifdef AST_LC_setenv ast.locale.set ^= AST_LC_setenv; -#endif if(!r && val) { if(!sh_isstate(SH_INIT) || !sh_isoption(SH_LOGIN_SHELL)) @@ -1913,6 +1931,19 @@ static void env_init(void) } if((cp = nv_getval(SHELLNOD)) && (sh_type(cp)&SH_TYPE_RESTRICTED)) sh_onoption(SH_RESTRICTED); /* restricted shell */ + /* + * Since AST setlocale() may use the environment (PATH, _AST_FEATURES), + * defer setting locale until all of the environment has been imported. + */ + sh_onstate(SH_LCINIT); + while (put_lang_defer) + { + struct put_lang_defer_s *p = put_lang_defer; + put_lang(p->np, p->val, p->flags, p->fp); + put_lang_defer = p->next; + free(p); + } + sh_offstate(SH_LCINIT); } /*