mirror of
https://github.com/reactos/reactos.git
synced 2024-11-04 05:43:30 +00:00
527f2f9057
* Create a branch for some evul shell experiments. svn path=/branches/shell-experiments/; revision=61927
155 lines
4.3 KiB
C
155 lines
4.3 KiB
C
/*
|
|
* REDIR.C - redirection handling.
|
|
*
|
|
*
|
|
* History:
|
|
*
|
|
* 12/15/95 (Tim Norman)
|
|
* started.
|
|
*
|
|
* 12 Jul 98 (Hans B Pufal)
|
|
* Rewrote to make more efficient and to conform to new command.c
|
|
* and batch.c processing.
|
|
*
|
|
* 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
|
|
* Added config.h include
|
|
*
|
|
* 22-Jan-1999 (Eric Kohl)
|
|
* Unicode safe!
|
|
* Added new error redirection "2>" and "2>>".
|
|
*
|
|
* 26-Jan-1999 (Eric Kohl)
|
|
* Added new error AND output redirection "&>" and "&>>".
|
|
*
|
|
* 24-Jun-2005 (Brandon Turner <turnerb7@msu.edu>)
|
|
* simple check to fix > and | bug with 'rem'
|
|
*/
|
|
|
|
#include "precomp.h"
|
|
|
|
#ifdef FEATURE_REDIRECTION
|
|
|
|
|
|
/* cmd allows redirection of handles numbered 3-9 even though these don't
|
|
* correspond to any STD_ constant. */
|
|
static HANDLE ExtraHandles[10 - 3];
|
|
|
|
static HANDLE GetHandle(UINT Number)
|
|
{
|
|
if (Number < 3)
|
|
return GetStdHandle(STD_INPUT_HANDLE - Number);
|
|
else
|
|
return ExtraHandles[Number - 3];
|
|
}
|
|
|
|
static VOID SetHandle(UINT Number, HANDLE Handle)
|
|
{
|
|
if (Number < 3)
|
|
SetStdHandle(STD_INPUT_HANDLE - Number, Handle);
|
|
else
|
|
ExtraHandles[Number - 3] = Handle;
|
|
}
|
|
|
|
BOOL
|
|
PerformRedirection(REDIRECTION *RedirList)
|
|
{
|
|
REDIRECTION *Redir;
|
|
LPTSTR Filename;
|
|
HANDLE hNew;
|
|
UINT DupNumber;
|
|
|
|
static SECURITY_ATTRIBUTES SecAttr = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
|
|
|
|
/* Some parameters used for read, write, and append, respectively */
|
|
static struct REDIR_PARAMS
|
|
{
|
|
DWORD dwDesiredAccess;
|
|
DWORD dwShareMode;
|
|
DWORD dwCreationDisposition;
|
|
} RedirParams[] =
|
|
{
|
|
{GENERIC_READ , FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_EXISTING}, // REDIR_READ
|
|
{GENERIC_WRITE, FILE_SHARE_READ , CREATE_ALWAYS}, // REDIR_WRITE
|
|
{GENERIC_WRITE, FILE_SHARE_READ , OPEN_ALWAYS } // REDIR_APPEND
|
|
};
|
|
|
|
for (Redir = RedirList; Redir; Redir = Redir->Next)
|
|
{
|
|
Filename = DoDelayedExpansion(Redir->Filename);
|
|
if (!Filename)
|
|
goto redir_error;
|
|
StripQuotes(Filename);
|
|
|
|
if (*Filename == _T('&'))
|
|
{
|
|
DupNumber = Filename[1] - _T('0');
|
|
if (DupNumber >= 10 ||
|
|
!DuplicateHandle(GetCurrentProcess(),
|
|
GetHandle(DupNumber),
|
|
GetCurrentProcess(),
|
|
&hNew,
|
|
0,
|
|
TRUE,
|
|
DUPLICATE_SAME_ACCESS))
|
|
{
|
|
hNew = INVALID_HANDLE_VALUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hNew = CreateFile(Filename,
|
|
RedirParams[Redir->Mode].dwDesiredAccess,
|
|
RedirParams[Redir->Mode].dwShareMode,
|
|
&SecAttr,
|
|
RedirParams[Redir->Mode].dwCreationDisposition,
|
|
0,
|
|
NULL);
|
|
}
|
|
|
|
if (hNew == INVALID_HANDLE_VALUE)
|
|
{
|
|
/* TODO: Print a more detailed message */
|
|
ConErrResPrintf(Redir->Mode == REDIR_READ ? STRING_CMD_ERROR1 : STRING_CMD_ERROR3,
|
|
Filename);
|
|
cmd_free(Filename);
|
|
redir_error:
|
|
/* Undo all the redirections before this one */
|
|
UndoRedirection(RedirList, Redir);
|
|
return FALSE;
|
|
}
|
|
|
|
if (Redir->Mode == REDIR_APPEND)
|
|
SetFilePointer(hNew, 0, NULL, FILE_END);
|
|
Redir->OldHandle = GetHandle(Redir->Number);
|
|
SetHandle(Redir->Number, hNew);
|
|
|
|
TRACE("%d redirected to: %s\n", Redir->Number, debugstr_aw(Filename));
|
|
cmd_free(Filename);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
VOID
|
|
UndoRedirection(REDIRECTION *Redir, REDIRECTION *End)
|
|
{
|
|
for (; Redir != End; Redir = Redir->Next)
|
|
{
|
|
CloseHandle(GetHandle(Redir->Number));
|
|
SetHandle(Redir->Number, Redir->OldHandle);
|
|
Redir->OldHandle = INVALID_HANDLE_VALUE;
|
|
}
|
|
}
|
|
|
|
VOID
|
|
FreeRedirection(REDIRECTION *Redir)
|
|
{
|
|
REDIRECTION *Next;
|
|
for (; Redir; Redir = Next)
|
|
{
|
|
Next = Redir->Next;
|
|
ASSERT(Redir->OldHandle == INVALID_HANDLE_VALUE);
|
|
cmd_free(Redir);
|
|
}
|
|
}
|
|
|
|
#endif /* FEATURE_REDIRECTION */
|