Constify the array of predefined shells. It turns out that we need two

versions of the structure definition for this: one with const char
pointers, because otherwise gcc won't let us initialize the fields with
constant strings, and one without the const, because we need to work
with the structure.
This commit is contained in:
harti 2004-11-30 15:35:51 +00:00
parent c87a620e46
commit 6a1de54fc3
2 changed files with 63 additions and 45 deletions

View File

@ -166,11 +166,10 @@ static int numCommands; /* The number of commands actually printed
*/
static char tfile[sizeof(TMPPAT)];
/*
* Descriptions for various shells.
*/
static Shell shells[] = {
static const DEF_SHELL_STRUCT(CShell, const) shells[] = {
/*
* CSH description. The csh can do echo control by playing
* with the setting of the 'echo' shell variable. Sadly,
@ -296,7 +295,7 @@ static void JobRestart(Job *);
static int JobStart(GNode *, int, Job *);
static char *JobOutput(Job *, char *, char *, int);
static void JobDoOutput(Job *, Boolean);
static Shell *JobMatchShell(char *);
static Shell *JobMatchShell(const char *);
static void JobInterrupt(int, int);
static void JobRestartJobs(void);
@ -2150,7 +2149,7 @@ Shell_Init(void)
{
if (commandShell == NULL)
commandShell = JobCopyShell(&shells[DEFSHELL]);
commandShell = JobMatchShell(shells[DEFSHELL].name);
if (shellPath == NULL) {
/*
@ -2253,12 +2252,6 @@ Job_Init(int maxproc)
}
Shell_Init();
if (commandShell->exit == NULL) {
commandShell->exit = "";
}
if (commandShell->echo == NULL) {
commandShell->echo = "";
}
/*
* Catch the four signals that POSIX specifies if they aren't ignored.
@ -2394,7 +2387,9 @@ Job_Empty(void)
* Find a matching shell in 'shells' given its final component.
*
* Results:
* A pointer to the Shell structure.
* A pointer to a freshly allocated Shell structure with is a copy
* of the static structure or NULL if no shell with the given name
* is found.
*
* Side Effects:
* None.
@ -2402,13 +2397,14 @@ Job_Empty(void)
*-----------------------------------------------------------------------
*/
static Shell *
JobMatchShell(char *name)
JobMatchShell(const char *name)
{
Shell *sh; /* Pointer into shells table */
Shell *match; /* Longest-matching shell */
char *cp1,
*cp2;
char *eoname;
const struct CShell *sh; /* Pointer into shells table */
const struct CShell *match; /* Longest-matching shell */
struct Shell *nsh;
const char *cp1;
const char *cp2;
const char *eoname;
eoname = name + strlen(name);
@ -2426,7 +2422,25 @@ JobMatchShell(char *name)
match = sh;
}
}
return(match);
if (match == NULL)
return (NULL);
/* make a copy */
nsh = emalloc(sizeof(*nsh));
nsh->name = estrdup(match->name);
nsh->echoOff = estrdup(match->echoOff);
nsh->echoOn = estrdup(match->echoOn);
nsh->hasEchoCtl = match->hasEchoCtl;
nsh->noPrint = estrdup(match->noPrint);
nsh->noPLen = match->noPLen;
nsh->hasErrCtl = match->hasErrCtl;
nsh->errCheck = estrdup(match->errCheck);
nsh->ignErr = estrdup(match->ignErr);
nsh->echo = estrdup(match->echo);
nsh->exit = estrdup(match->exit);
return (nsh);
}
/*-
@ -2480,7 +2494,8 @@ Job_ParseShell(char *line)
char **argv;
int argc;
char *path;
Shell newShell, *sh;
Shell newShell;
Shell *sh;
Boolean fullSpec = FALSE;
while (isspace((unsigned char) *line)) {
@ -2585,13 +2600,13 @@ Job_ParseShell(char *line)
return (FAILURE);
}
} else {
sh = &newShell;
sh = JobCopyShell(&newShell);
}
}
/* set the new shell */
JobFreeShell(commandShell);
commandShell = JobCopyShell(sh);
commandShell = sh;
shellName = commandShell->name;

View File

@ -175,30 +175,33 @@ typedef struct Job {
* strings is empty when hasErrCtl is FALSE, the command will be executed
* anyway as is and if it causes an error, so be it.
*/
typedef struct Shell {
char *name; /* the name of the shell. For Bourne and C
* shells, this is used only to find the
* shell description when used as the single
* source of a .SHELL target. For user-defined
* shells, this is the full path of the shell.
*/
Boolean hasEchoCtl; /* True if both echoOff and echoOn defined */
char *echoOff; /* command to turn off echo */
char *echoOn; /* command to turn it back on again */
char *noPrint; /* command to skip when printing output from
* shell. This is usually the command which
* was executed to turn off echoing */
int noPLen; /* length of noPrint command */
Boolean hasErrCtl; /* set if can control error checking for
* individual commands */
char *errCheck; /* string to turn error checking on */
char *ignErr; /* string to turn off error checking */
/*
* command-line flags
*/
char *echo; /* echo commands */
char *exit; /* exit on error */
} Shell;
#define DEF_SHELL_STRUCT(TAG, CONST) \
struct TAG { \
CONST char *name; /* the name of the shell. For Bourne and C \
* shells, this is used only to find the \
* shell description when used as the single \
* source of a .SHELL target. For user-defined \
* shells, this is the full path of the shell. \
*/ \
Boolean hasEchoCtl; /* True if both echoOff and echoOn defined */ \
CONST char *echoOff; /* command to turn off echo */ \
CONST char *echoOn; /* command to turn it back on again */ \
CONST char *noPrint; /* command to skip when printing output from \
* shell. This is usually the command which \
* was executed to turn off echoing */ \
int noPLen; /* length of noPrint command */ \
Boolean hasErrCtl; /* set if can control error checking for \
* individual commands */ \
CONST char *errCheck; /* string to turn error checking on */ \
CONST char *ignErr; /* string to turn off error checking */ \
/* \
* command-line flags \
*/ \
CONST char *echo; /* echo commands */ \
CONST char *exit; /* exit on error */ \
}
typedef DEF_SHELL_STRUCT(Shell,) Shell;
extern char *shellPath;
extern char *shellName;