INT CommandAssoc(LPTSTR param)
{
+ INT retval = 0;
LPTSTR lpEqualSign;
/* Print help */
return 0;
}
- nErrorLevel = 0;
-
if (_tcslen(param) == 0)
{
PrintAllAssociations();
- return 0;
+ goto Quit;
}
lpEqualSign = _tcschr(param, _T('='));
{
WARN("Cannot allocate memory for extension!\n");
error_out_of_memory();
- return 1;
+ retval = 1;
+ goto Quit;
}
_tcsncpy(extension, param, lpEqualSign - param);
* in the string, then delete the key. */
if (_tcslen(fileType) == 0)
{
- RemoveAssociation(extension);
+ retval = RemoveAssociation(extension);
}
else
/* Otherwise, add the key and print out the association */
{
- AddAssociation(extension, fileType);
+ retval = AddAssociation(extension, fileType);
PrintAssociation(extension);
}
cmd_free(extension);
+
+ if (retval)
+ retval = 1; /* Fixup the error value */
}
else
{
/* No equal sign, print all associations */
- INT retval = PrintAssociation(param);
+ retval = PrintAssociation(param);
if (retval == 0) /* If nothing printed out */
+ {
ConOutResPrintf(STRING_ASSOC_ERROR, param);
+ retval = 1; /* Fixup the error value */
+ }
}
- return 0;
+Quit:
+ if (BatType != CMD_TYPE)
+ {
+ if (retval != 0)
+ nErrorLevel = retval;
+ }
+ else
+ {
+ nErrorLevel = retval;
+ }
+
+ return retval;
}
#endif /* INCLUDE_CMD_ASSOC */
/* The stack of current batch contexts.
* NULL when no batch is active.
*/
+BATCH_TYPE BatType = NONE;
PBATCH_CONTEXT bc = NULL;
BOOL bEcho = TRUE; /* The echo flag */
/* If there is no more batch contexts, notify the signal handler */
if (!bc)
+ {
CheckCtrlBreak(BREAK_OUTOFBATCH);
+ BatType = NONE;
+ }
}
/*
INT ret = 0;
INT i;
HANDLE hFile = NULL;
- BOOL bSameFn = FALSE;
+ BOOLEAN bSameFn = FALSE;
+ BOOLEAN bTopLevel;
BATCH_CONTEXT new;
PFOR_CONTEXT saved_fc;
}
}
+ /*
+ * Remember whether this is a top-level batch context, i.e. if there is
+ * no batch context existing prior (bc == NULL originally), and we are
+ * going to create one below.
+ */
+ bTopLevel = !bc;
+
if (bc != NULL && Cmd == bc->current)
{
/* Then we are transferring to another batch */
return 1;
}
- /* Check if this is a "CALL :label" */
- if (*firstword == _T(':'))
- ret = cmd_goto(firstword);
-
/* If we are calling from inside a FOR, hide the FOR variables */
saved_fc = fc;
fc = NULL;
+ /* Perform top-level batch initialization */
+ if (bTopLevel)
+ {
+ /* Default the top-level batch context type to .BAT */
+ BatType = BAT_TYPE;
+
+ /* If this is a .CMD file, adjust the type */
+ TCHAR *dot = _tcsrchr(bc->BatchFilePath, _T('.'));
+ if (dot && (!_tcsicmp(dot, _T(".cmd"))))
+ {
+ BatType = CMD_TYPE;
+ }
+ }
+
+ /* Check if this is a "CALL :label" */
+ if (*firstword == _T(':'))
+ ret = cmd_goto(firstword);
+
/* If we have created a new context, don't return
* until this batch file has completed. */
while (bc == &new && !bExit)
FreeCommand(Cmd);
}
+ /* Perform top-level batch cleanup */
+ if (!bc || bTopLevel)
+ {
+ /* Reset the top-level batch context type */
+ BatType = NONE;
+ }
+
/* Restore the FOR variables */
fc = saved_fc;
#pragma once
+/*
+ * This batch type enumeration allows us to adjust the behaviour of some commands
+ * depending on whether they are run from within a .BAT or a .CMD file.
+ * The behaviour is selected when the top-level batch file is loaded,
+ * and it remains the same for any child batch file that may be loaded later.
+ *
+ * See https://ss64.com/nt/errorlevel.html for more details.
+ */
+typedef enum _BATCH_TYPE
+{
+ NONE,
+ BAT_TYPE, /* Old-style DOS batch file */
+ CMD_TYPE /* New-style NT OS/2 batch file */
+} BATCH_TYPE;
+
typedef struct _BATCH_CONTEXT
{
struct _BATCH_CONTEXT *prev;
* The stack of current batch contexts.
* NULL when no batch is active.
*/
+extern BATCH_TYPE BatType;
extern PBATCH_CONTEXT bc;
extern PFOR_CONTEXT fc;
INT cmd_path(LPTSTR param)
{
+ INT retval = 0;
+
if (!_tcsncmp(param, _T("/?"), 2))
{
ConOutResPaging(TRUE, STRING_PATH_HELP1);
return 0;
}
- nErrorLevel = 0;
-
/* If param is empty, display the PATH environment variable */
if (!param || !*param)
{
if (!pszBuffer)
{
WARN("Cannot allocate memory for pszBuffer!\n");
- return 1;
+ error_out_of_memory();
+ retval = 1;
+ goto Quit;
}
dwBuffer = GetEnvironmentVariable(_T("PATH"), pszBuffer, ENV_BUFFER_SIZE);
{
cmd_free(pszBuffer);
ConErrResPrintf(STRING_SET_ENV_ERROR, _T("PATH"));
- return 0;
+ retval = 0;
+ goto Quit;
}
else if (dwBuffer > ENV_BUFFER_SIZE)
{
if (!pszBuffer)
{
WARN("Cannot reallocate memory for pszBuffer!\n");
+ error_out_of_memory();
cmd_free(pszOldBuffer);
- return 1;
+ retval = 1;
+ goto Quit;
}
GetEnvironmentVariable(_T("PATH"), pszBuffer, dwBuffer);
}
ConOutPrintf(_T("PATH=%s\n"), pszBuffer);
cmd_free(pszBuffer);
- return 0;
+ retval = 0;
+ goto Quit;
}
/* Skip leading '=' */
/* Set PATH environment variable */
if (!SetEnvironmentVariable(_T("PATH"), param))
{
- nErrorLevel = 1;
- return 1;
+ retval = 1;
+ }
+
+Quit:
+ if (BatType != CMD_TYPE)
+ {
+ if (retval != 0)
+ nErrorLevel = retval;
+ }
+ else
+ {
+ nErrorLevel = retval;
}
- return 0;
+ return retval;
}
#endif
INT cmd_prompt(LPTSTR param)
{
+ INT retval = 0;
+
if (!_tcsncmp(param, _T("/?"), 2))
{
ConOutResPaging(TRUE, STRING_PROMPT_HELP1);
-
#ifdef FEATURE_DIRECTORY_STACK
ConOutResPaging(FALSE, STRING_PROMPT_HELP2);
#endif
if (!SetEnvironmentVariable(_T("PROMPT"),
(param && param[0] != _T('\0') ? param : NULL)))
{
- return 1;
+ retval = 1;
+ }
+
+ if (BatType != CMD_TYPE)
+ {
+ if (retval != 0)
+ nErrorLevel = retval;
+ }
+ else
+ {
+ nErrorLevel = retval;
}
- return 0;
+ return retval;
}
#endif
INT cmd_set(LPTSTR param)
{
+ INT retval = 0;
LPTSTR p;
LPTSTR lpEnv;
LPTSTR lpOutput;
FreeEnvironmentStrings(lpEnv);
}
- return 0;
+ retval = 0;
+ goto Quit;
}
/* The /A does *NOT* have to be followed by a whitespace */
if (!Success)
{
/* Might seem random but this is what windows xp does -- This is a message ID */
- nErrorLevel = 9165;
+ retval = 9165;
+ }
+ // return !Success;
+ else
+ {
+ retval = 0;
}
- return !Success;
+ goto Quit;
}
if (!_tcsnicmp(param, _T("/P"), 2))
if (!p)
{
ConErrResPuts(STRING_SYNTAX_COMMAND_INCORRECT);
- nErrorLevel = 1;
- return 1;
+ retval = 1;
+ goto Quit;
}
*p++ = _T('\0');
if (!*value || !SetEnvironmentVariable(param, value))
{
- nErrorLevel = 1;
- return 1;
+ retval = 1;
+ goto Quit;
}
- return 0;
+ retval = 0;
+ goto Quit;
}
param = GetQuotedString(param);
{
/* Handle set =val case */
ConErrResPuts(STRING_SYNTAX_COMMAND_INCORRECT);
- nErrorLevel = 1;
- return 1;
+ retval = 1;
+ goto Quit;
}
*p++ = _T('\0');
if (!SetEnvironmentVariable(param, *p ? p : NULL))
{
- nErrorLevel = 1;
- return 1;
+ retval = 1;
+ goto Quit;
}
}
else
if (!bFound)
{
ConErrResPrintf(STRING_SET_ENV_ERROR, param);
- nErrorLevel = 1;
- return 1;
+ retval = 1;
+ goto Quit;
}
}
- return 0;
+Quit:
+ if (BatType != CMD_TYPE)
+ {
+ if (retval != 0)
+ nErrorLevel = retval;
+ }
+ else
+ {
+ nErrorLevel = retval;
+ }
+
+ return retval;
}
static INT