123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378 |
- /*++
- Copyright (c) 2013 Minoca Corp.
- This file is licensed under the terms of the GNU General Public License
- version 3. Alternative licensing terms are available. Contact
- info@minocacorp.com for details. See the LICENSE file at the root of this
- project for complete licensing information.
- Module Name:
- consio.c
- Abstract:
- This module implements standard input and output functionality for the
- debugger.
- Author:
- Evan Green 30-Dec-2013
- Environment:
- Debug
- --*/
- //
- // ------------------------------------------------------------------- Includes
- //
- #include "dbgrtl.h"
- #include <minoca/debug/spproto.h>
- #include <minoca/lib/im.h>
- #include <minoca/debug/dbgext.h>
- #include "disasm.h"
- #include "dbgapi.h"
- #include "dbgrprof.h"
- #include "console.h"
- #include "symbols.h"
- #include "dbgrcomm.h"
- #include "dbgsym.h"
- #include "extsp.h"
- #include "consio.h"
- #include "remsrv.h"
- #include <assert.h>
- #include <errno.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/stat.h>
- #include <unistd.h>
- //
- // ---------------------------------------------------------------- Definitions
- //
- #define DBGR_IO_BUFFER_SIZE 1024
- //
- // ------------------------------------------------------ Data Type Definitions
- //
- //
- // ----------------------------------------------- Internal Function Prototypes
- //
- BOOL
- DbgrpFormatWriteCharacter (
- INT Character,
- PPRINT_FORMAT_CONTEXT Context
- );
- //
- // -------------------------------------------------------------------- Globals
- //
- //
- // Store a pointer to the global context. Currently only one debugger context
- // is supported for output functions.
- //
- PDEBUGGER_CONTEXT DbgConsoleContext;
- //
- // ------------------------------------------------------------------ Functions
- //
- INT
- DbgrInitializeConsoleIo (
- PDEBUGGER_CONTEXT Context
- )
- /*++
- Routine Description:
- This routine initializes console I/O for the debugger.
- Arguments:
- Context - Supplies a pointer to the debugger context.
- Return Value:
- 0 on success.
- Returns an error code on failure.
- --*/
- {
- BOOL EchoCommands;
- INT Result;
- assert(DbgConsoleContext == NULL);
- DbgConsoleContext = Context;
- EchoCommands = FALSE;
- Result = DbgrOsInitializeConsole(&EchoCommands);
- if (Result == FALSE) {
- Result = EINVAL;
- goto InitializeConsoleIoEnd;
- }
- if (EchoCommands != FALSE) {
- Context->Flags |= DEBUGGER_FLAG_ECHO_COMMANDS;
- }
- assert(Context->StandardOut.ConsoleBuffer == NULL);
- Context->StandardOut.ConsoleBuffer = malloc(DBGR_IO_BUFFER_SIZE);
- if (Context->StandardOut.ConsoleBuffer == NULL) {
- Result = ENOMEM;
- goto InitializeConsoleIoEnd;
- }
- Context->StandardOut.ConsoleBufferCapacity = DBGR_IO_BUFFER_SIZE;
- Context->StandardOut.ConsoleBufferSize = 0;
- Context->StandardOut.Lock = CreateDebuggerLock();
- if (Context->StandardOut.Lock == NULL) {
- Result = ENOMEM;
- goto InitializeConsoleIoEnd;
- }
- Context->StandardIn.Lock = CreateDebuggerLock();
- if (Context->StandardIn.Lock == NULL) {
- Result = ENOMEM;
- goto InitializeConsoleIoEnd;
- }
- Result = 0;
- InitializeConsoleIoEnd:
- return Result;
- }
- VOID
- DbgrDestroyConsoleIo (
- PDEBUGGER_CONTEXT Context
- )
- /*++
- Routine Description:
- This routine destroys console I/O for the debugger.
- Arguments:
- Context - Supplies a pointer to the debugger context.
- Return Value:
- None.
- --*/
- {
- DbgrOsDestroyConsole();
- if (Context->StandardOut.ConsoleBuffer != NULL) {
- free(Context->StandardOut.ConsoleBuffer);
- }
- if (Context->StandardOut.Prompt != NULL) {
- free(Context->StandardOut.Prompt);
- }
- if (Context->StandardOut.Lock != NULL) {
- DestroyDebuggerLock(Context->StandardOut.Lock);
- }
- if (Context->StandardIn.Lock != NULL) {
- DestroyDebuggerLock(Context->StandardIn.Lock);
- }
- DbgConsoleContext = NULL;
- return;
- }
- INT
- DbgOut (
- const char *Format,
- ...
- )
- /*++
- Routine Description:
- This routine prints a formatted string to the debugger console.
- Arguments:
- Format - Supplies the printf format string.
- ... - Supplies a variable number of arguments, as required by the printf
- format string argument.
- Return Value:
- Returns the number of bytes successfully converted, not including the null
- terminator.
- Returns a negative number if an error was encountered.
- --*/
- {
- va_list Arguments;
- int Result;
- assert(DbgConsoleContext != NULL);
- va_start(Arguments, Format);
- Result = DbgOutVaList(DbgConsoleContext, Format, Arguments);
- va_end(Arguments);
- return Result;
- }
- INT
- DbgOutVaList (
- PDEBUGGER_CONTEXT Context,
- const char *Format,
- va_list Arguments
- )
- /*++
- Routine Description:
- This routine prints a formatted string to the given debugger console.
- Arguments:
- Context - Supplies a pointer to the debugger context to output to.
- Format - Supplies the printf format string.
- Arguments - Supplies the argument list to the format string. The va_end
- macro is not invoked on this list.
- Return Value:
- Returns the number of bytes successfully converted. A null terminator is
- not written.
- Returns a negative number if an error was encountered.
- --*/
- {
- PRINT_FORMAT_CONTEXT PrintContext;
- if (Context == NULL) {
- Context = DbgConsoleContext;
- }
- memset(&PrintContext, 0, sizeof(PRINT_FORMAT_CONTEXT));
- PrintContext.Context = Context;
- PrintContext.WriteCharacter = DbgrpFormatWriteCharacter;
- RtlInitializeMultibyteState(&(PrintContext.State),
- CharacterEncodingDefault);
- AcquireDebuggerLock(Context->StandardOut.Lock);
- RtlFormat(&PrintContext, (PSTR)Format, Arguments);
- //
- // If something was written poke all the clients to send the data along to
- // them too.
- //
- if (PrintContext.CharactersWritten != 0) {
- DbgrpServerNotifyClients(Context);
- }
- ReleaseDebuggerLock(Context->StandardOut.Lock);
- return PrintContext.CharactersWritten;
- }
- //
- // --------------------------------------------------------- Internal Functions
- //
- BOOL
- DbgrpFormatWriteCharacter (
- INT Character,
- PPRINT_FORMAT_CONTEXT Context
- )
- /*++
- Routine Description:
- This routine writes a character to the output during a printf-style
- formatting operation.
- Arguments:
- Character - Supplies the character to be written.
- Context - Supplies a pointer to the printf-context.
- Return Value:
- TRUE on success.
- FALSE on failure.
- --*/
- {
- PDEBUGGER_CONTEXT DebuggerContext;
- PVOID NewBuffer;
- ULONGLONG NewCapacity;
- PDEBUGGER_STANDARD_OUT Out;
- DebuggerContext = Context->Context;
- Out = &(DebuggerContext->StandardOut);
- //
- // Reallocate the console buffer if needed.
- //
- if (Out->ConsoleBufferSize + 2 > Out->ConsoleBufferCapacity) {
- NewCapacity = Out->ConsoleBufferCapacity * 2;
- assert(NewCapacity > Out->ConsoleBufferSize + 2);
- NewBuffer = realloc(Out->ConsoleBuffer, NewCapacity);
- if (NewBuffer == NULL) {
- return FALSE;
- }
- Out->ConsoleBuffer = NewBuffer;
- Out->ConsoleBufferCapacity = NewCapacity;
- }
- //
- // Add the character to the console buffer.
- //
- Out->ConsoleBuffer[Out->ConsoleBufferSize] = Character;
- Out->ConsoleBufferSize += 1;
- if (fputc(Character, stdout) == -1) {
- return FALSE;
- }
- return TRUE;
- }
|