Author: dreimer
Date: Wed Jan 27 20:03:52 2010
New Revision: 45287
URL:
http://svn.reactos.org/svn/reactos?rev=45287&view=rev
Log:
Update log2lines to Version 1.11 (Jan Roeloffzen) Bug 4342
- Added -P Pipeline option for Powershell support, see below
- Renaming some structs to avoid potential naming conflicts with windows.h
- stdin/out -> stdIn/Out for redirecting
- Fixed potential mem leak
- A little more tracing and cleanup
Updated piperead (Jan Roeloffzen) Bug 5146
- Added Pipe client function, based on msdn example
- Improved option handling (try piperead -h)
- logging, error handling
- Integrated in build (pipetools.mak)
Added:
trunk/reactos/tools/pipetools/pipetools.mak (with props)
Modified:
trunk/reactos/tools/pipetools/piperead.cpp
trunk/reactos/tools/rsym/log2lines.c
trunk/reactos/tools/tools.mak
Modified: trunk/reactos/tools/pipetools/piperead.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/tools/pipetools/piperead.c…
==============================================================================
--- trunk/reactos/tools/pipetools/piperead.cpp [iso-8859-1] (original)
+++ trunk/reactos/tools/pipetools/piperead.cpp [iso-8859-1] Wed Jan 27 20:03:52 2010
@@ -2,13 +2,10 @@
// piperead.cpp
//
// Martin Fuchs, 30.11.2003
-//
-
-//
-// Invoke as: "piperead [pipe_name]",
-// for example: "piperead com_1"
-//
-
+//
+// Jan Roeloffzen, 26.1.2010
+// Pipe client, based on msdn example
+
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
@@ -21,24 +18,15 @@
#endif
+#define BUFSIZE 1024
+
static void print_error(DWORD win32_error)
{
fprintf(stderr, "WIN32 error %lu\n", win32_error);
}
-
-int main(int argc, char** argv)
-{
- char path[MAX_PATH];
- const char* pipe_name;
-
- if (argc > 1)
- pipe_name = *++argv;
- else
- pipe_name = "com_1";
-
- sprintf(path, "\\\\.\\pipe\\%s", pipe_name);
-
+static int pipeServer(char *path)
+{
HANDLE hPipe = CreateNamedPipe(path, PIPE_ACCESS_DUPLEX|FILE_FLAG_FIRST_PIPE_INSTANCE,
PIPE_WAIT|PIPE_TYPE_BYTE, 1, 4096, 4096, 30000, NULL);
if (hPipe == INVALID_HANDLE_VALUE) {
@@ -48,23 +36,26 @@
for(;;) {
DWORD read;
- BYTE buffer[1024];
+ BYTE buffer[BUFSIZE];
if (!ReadFile(hPipe, buffer, sizeof(buffer), &read, NULL)) {
DWORD error = GetLastError();
- if (error == ERROR_PIPE_LISTENING)
+ if (error == ERROR_PIPE_LISTENING) {
+ fprintf(stderr,"INVALID_HANDLE_VALUE\n");
Sleep(1000);
- else if (error == ERROR_BROKEN_PIPE) {
+ } else if (error == ERROR_BROKEN_PIPE) {
CloseHandle(hPipe);
hPipe = CreateNamedPipe(path, PIPE_ACCESS_DUPLEX|FILE_FLAG_FIRST_PIPE_INSTANCE,
PIPE_WAIT|PIPE_TYPE_BYTE, 1, 4096, 4096, 30000, NULL);
if (hPipe == INVALID_HANDLE_VALUE) {
+ fprintf(stderr,"INVALID_HANDLE_VALUE\n");
print_error(GetLastError());
return 1;
}
} else {
+ fprintf(stderr,"error %lu\n",error);
print_error(error);
break;
}
@@ -79,3 +70,132 @@
return 0;
}
+
+static int pipeClient(char *path)
+{
+ HANDLE hPipe=INVALID_HANDLE_VALUE;
+ TCHAR chBuf[BUFSIZE];
+ BOOL fSuccess = FALSE;
+ DWORD cbRead;
+ DWORD Err;
+ int res = 0;
+
+ setvbuf(stdout, NULL, _IONBF, 0);
+ while (1) {
+ hPipe = CreateFile(
+ path, // pipe name
+ GENERIC_READ,
+ 0, // no sharing
+ NULL, // default security attributes
+ OPEN_EXISTING, // opens existing pipe
+ 0, // default attributes
+ NULL); // no template file
+
+ // Break if the pipe handle is valid.
+ if (hPipe != INVALID_HANDLE_VALUE)
+ break;
+
+ // Exit if an error other than ERROR_PIPE_BUSY occurs.
+ if (GetLastError() != ERROR_PIPE_BUSY) {
+ fprintf(stderr,"Could not open pipe. Error=%lu\n", GetLastError() );
+ res = -1;
+ break;
+ }
+
+ // All pipe instances are busy, so wait for 20 seconds.
+ if ( ! WaitNamedPipe(path, 20000)) {
+ fprintf(stderr,"Could not open pipe: 20 second wait timed out.");
+ res = -2;
+ break;
+ }
+ }
+
+ if (!res) do {
+ fSuccess = ReadFile(
+ hPipe, // pipe handle
+ chBuf, // buffer to receive reply
+ BUFSIZE, // size of buffer
+ &cbRead, // number of bytes read
+ NULL); // not overlapped
+
+ if ( ! fSuccess ) {
+ Err = GetLastError();
+ if ( Err == ERROR_MORE_DATA ) {
+ fSuccess = TRUE;
+ } else {
+ fprintf(stderr, "ReadFile: Error %lu \n", Err );
+ res = -9;
+ break;
+ }
+ }
+
+ fwrite(chBuf,1,cbRead,stdout);
+ } while ( fSuccess);
+
+ if ( ! fSuccess) {
+ fprintf(stderr, "ReadFile from pipe failed. Error=%lu\n", GetLastError()
);
+ res = -5;
+ }
+
+ if (hPipe != INVALID_HANDLE_VALUE)
+ CloseHandle(hPipe);
+
+ return res;
+
+}
+
+void usage(void)
+{
+ fprintf(stderr, "Usage: piperead [-c] <named pipe>\n");
+ fprintf(stderr, "-c means Client mode\n");
+ fprintf(stderr, "Example: piperead -c \\\\.\\pipe\\kdbg | log2lines -c\n\n");
+}
+
+int main(int argc, char** argv)
+{
+ char path[MAX_PATH];
+ const char* pipe_name;
+ const char* clientMode;
+ int res = 0;
+
+ pipe_name = "com_1";
+ clientMode = NULL;
+ switch (argc) {
+ case 3:
+ clientMode = *++argv;
+ if (strcmp(clientMode,"-c") != 0) {
+ clientMode = NULL;
+ fprintf(stderr,"Invalid option: %s\n", clientMode);
+ res = -6;
+ }
+ //fall through
+ case 2:
+ pipe_name = *++argv;
+ if (strcmp(pipe_name,"-h") == 0) {
+ res = -7;
+ }
+ break;
+ default:
+ res = -8;
+ break;
+ }
+ if (res) {
+ usage();
+ return res;
+ }
+
+ if ( pipe_name[0] == '\\' ) {
+ //assume caller specified full path
+ sprintf(path, "%s", pipe_name);
+ } else {
+ sprintf(path, "\\\\.\\pipe\\%s", pipe_name);
+ }
+
+ if ( clientMode ) {
+ res = pipeClient(path);
+ } else {
+ res = pipeServer(path);
+ }
+
+ return res;
+}
Added: trunk/reactos/tools/pipetools/pipetools.mak
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/tools/pipetools/pipetools.…
==============================================================================
--- trunk/reactos/tools/pipetools/pipetools.mak (added)
+++ trunk/reactos/tools/pipetools/pipetools.mak [iso-8859-1] Wed Jan 27 20:03:52 2010
@@ -1,0 +1,47 @@
+PIPETOOLS_BASE = $(TOOLS_BASE)$(SEP)pipetools
+PIPETOOLS_BASE_ = $(PIPETOOLS_BASE)$(SEP)
+PIPETOOLS_INT = $(INTERMEDIATE_)$(PIPETOOLS_BASE)
+PIPETOOLS_INT_ = $(PIPETOOLS_INT)$(SEP)
+PIPETOOLS_OUT = $(OUTPUT_)$(PIPETOOLS_BASE)
+PIPETOOLS_OUT_ = $(PIPETOOLS_OUT)$(SEP)
+
+$(PIPETOOLS_INT): | $(TOOLS_INT)
+ $(ECHO_MKDIR)
+ ${mkdir} $@
+
+ifneq ($(INTERMEDIATE),$(OUTPUT))
+$(PIPETOOLS_OUT): | $(TOOLS_OUT)
+ $(ECHO_MKDIR)
+ ${mkdir} $@
+endif
+
+
+PIPETOOLS_TARGET = \
+ $(PIPETOOLS_OUT_)piperead$(EXEPOSTFIX)
+
+PIPETOOLS_SOURCES = \
+ $(PIPETOOLS_BASE_)piperead.cpp
+
+PIPETOOLS_OBJECTS = \
+ $(addprefix $(INTERMEDIATE_), $(PIPETOOLS_SOURCES:.cpp=.o))
+
+PIPETOOLS_HOST_CFLAGS = $(TOOLS_CFLAGS)
+
+PIPETOOLS_HOST_LFLAGS = $(TOOLS_LFLAGS)
+
+.PHONY: pipetools
+pipetools: $(PIPETOOLS_TARGET)
+
+$(PIPETOOLS_TARGET): $(PIPETOOLS_OBJECTS) | $(PIPETOOLS_OUT)
+ $(ECHO_HOSTLD)
+ ${host_gcc} $(PIPETOOLS_OBJECTS) $(PIPETOOLS_HOST_LFLAGS) -o $@
+
+$(PIPETOOLS_INT_)piperead.o: $(PIPETOOLS_BASE_)piperead.cpp | $(PIPETOOLS_INT)
+ $(ECHO_HOSTCC)
+ ${host_gcc} $(PIPETOOLS_HOST_CFLAGS) -c $< -o $@
+
+
+.PHONY: pipetools_clean
+pipetools_clean:
+ -@$(rm) $(PIPETOOLS_TARGET) $(PIPETOOLS_OBJECTS) 2>$(NUL)
+clean: pipetools_clean
Propchange: trunk/reactos/tools/pipetools/pipetools.mak
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/tools/rsym/log2lines.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/tools/rsym/log2lines.c?rev…
==============================================================================
--- trunk/reactos/tools/rsym/log2lines.c [iso-8859-1] (original)
+++ trunk/reactos/tools/rsym/log2lines.c [iso-8859-1] Wed Jan 27 20:03:52 2010
@@ -11,7 +11,7 @@
#include "rsym.h"
-#define LOG2LINES_VERSION "1.9"
+#define LOG2LINES_VERSION "1.11"
/* Assume if an offset > ABS_TRESHOLD, then it must be absolute */
#define ABS_TRESHOLD 0x00400000L
@@ -27,6 +27,8 @@
#define CACHEFILE "log2lines.cache"
#define TRKBUILDPREFIX "bootcd-"
#define SVN_PREFIX "/trunk/reactos/"
+#define KDBG_PROMPT "kdbg>"
+#define PIPEREAD_CMD "piperead -c"
#if defined (__DJGPP__) || defined (__WIN32__)
@@ -96,13 +98,13 @@
struct entry_struct *pnext;
};
-typedef struct entry_struct LIST_ENTRY;
+typedef struct entry_struct LIST_MEMBER;
struct list_struct
{
off_t st_size;
- LIST_ENTRY *phead;
- LIST_ENTRY *ptail;
+ LIST_MEMBER *phead;
+ LIST_MEMBER *ptail;
};
struct summ_struct
@@ -149,7 +151,7 @@
static LINEINFO lastLine;
static REVINFO revinfo;
-static char *optchars = "bcd:fFhl:mMrR:sS:tTuUvz:";
+static char *optchars = "bcd:fFhl:mMP:rR:sS:tTuUvz:";
static int opt_buffered = 0; // -b
static int opt_help = 0; // -h
static int opt_force = 0; // -f
@@ -158,6 +160,7 @@
static int opt_console = 0; // -c
static int opt_mark = 0; // -m
static int opt_Mark = 0; // -M
+static char *opt_Pipe = NULL; // -P
static int opt_raw = 0; // -r
static int opt_stats = 0; // -s
static int opt_Source = 0; // -S
<opt_Source>[+<opt_SrcPlus>][,<sources_path>]
@@ -172,6 +175,8 @@
static char opt_7z[MAX_PATH]; // -z <opt_7z>
static char opt_scanned[LINESIZE]; // all scanned options
static FILE *logFile = NULL;
+static FILE *stdIn = NULL;
+static FILE *stdOut = NULL;
static char *cache_name;
static char *tmp_name;
@@ -220,6 +225,7 @@
return res;
}
+#if 0
static FILE *
rfopen(char *path, char *mode)
{
@@ -232,12 +238,13 @@
f = fopen(tmppath, mode);
return f;
}
-
-static LIST_ENTRY *
+#endif
+
+static LIST_MEMBER *
entry_lookup(LIST *list, char *name)
{
- LIST_ENTRY *pprev = NULL;
- LIST_ENTRY *pnext;
+ LIST_MEMBER *pprev = NULL;
+ LIST_MEMBER *pnext;
if (!name || !name[0])
return NULL;
@@ -261,8 +268,8 @@
return NULL;
}
-static LIST_ENTRY *
-entry_delete(LIST_ENTRY *pentry)
+static LIST_MEMBER *
+entry_delete(LIST_MEMBER *pentry)
{
if (!pentry)
return NULL;
@@ -272,8 +279,8 @@
return NULL;
}
-static LIST_ENTRY *
-entry_insert(LIST *list, LIST_ENTRY *pentry)
+static LIST_MEMBER *
+entry_insert(LIST *list, LIST_MEMBER *pentry)
{
if (!pentry)
return NULL;
@@ -286,10 +293,10 @@
}
#if 0
-static LIST_ENTRY *
-entry_remove(LIST *list, LIST_ENTRY *pentry)
-{
- LIST_ENTRY *pprev = NULL, *p = NULL;
+static LIST_MEMBER *
+entry_remove(LIST *list, LIST_MEMBER *pentry)
+{
+ LIST_MEMBER *pprev = NULL, *p = NULL;
if (!pentry)
return NULL;
@@ -320,17 +327,17 @@
}
#endif
-static LIST_ENTRY *
+static LIST_MEMBER *
cache_entry_create(char *Line)
{
- LIST_ENTRY *pentry;
+ LIST_MEMBER *pentry;
char *s = NULL;
int l;
if (!Line)
return NULL;
- pentry = malloc(sizeof(LIST_ENTRY));
+ pentry = malloc(sizeof(LIST_MEMBER));
if (!pentry)
return NULL;
@@ -372,10 +379,10 @@
}
-static LIST_ENTRY *
+static LIST_MEMBER *
sources_entry_create(LIST *list, char *path, char *prefix)
{
- LIST_ENTRY *pentry;
+ LIST_MEMBER *pentry;
char *s = NULL;
int l;
@@ -384,7 +391,7 @@
if (!prefix)
prefix = "";
- pentry = malloc(sizeof(LIST_ENTRY));
+ pentry = malloc(sizeof(LIST_MEMBER));
if (!pentry)
return NULL;
@@ -988,7 +995,7 @@
read_cache(void)
{
FILE *fr;
- LIST_ENTRY *pentry;
+ LIST_MEMBER *pentry;
char *Line = NULL;
int result = 0;
@@ -1117,7 +1124,7 @@
translate_file(const char *cpath, size_t offset, char *toString)
{
size_t base = 0;
- LIST_ENTRY *pentry = NULL;
+ LIST_MEMBER *pentry = NULL;
int res = 0;
char *path, *dpath;
@@ -1552,6 +1559,11 @@
" -m Prefix (mark) each translated line with '* '.\n\n"
" -M Prefix (mark) each NOT translated line with '? '.\n"
" ( Only for lines of the form: <IMAGENAME:ADDRESS> )\n\n"
+" -P <cmd line>\n"
+" Pipeline command line. Spawn <cmd line> and pipeline its output
to\n"
+" log2lines (as stdin). This is for shells lacking support of (one
of):\n"
+" - Input file redirection.\n"
+" - Pipelining byte streams, needed for the -c option.\n\n"
" -r Raw output without translation.\n\n"
" -R <cmd>\n"
" Revision commands interfacing with SVN. <cmd> is one of:\n"
@@ -1632,6 +1644,8 @@
" log2lines -c < \\\\.\\pipe\\kdbg\n\n"
" Use kdbg debugger via console, and append copy to logFile:\n"
" log2lines -c -l dbg.log < \\\\.\\pipe\\kdbg\n\n"
+" Same as above, but for PowerShell:\n"
+" log2lines -c -l dbg.log -P \"piperead -c
\\\\.\\pipe\\kdbg\"\n\n"
" Use kdbg debugger to send output to logfile:\n"
" log2lines < \\\\.\\pipe\\kdbg > dbg.log\n\n"
" Re-translate a debug log:\n"
@@ -1868,6 +1882,8 @@
int i;
char *s;
+ stdIn = stdin;
+ stdOut = stdout;
strcpy(opt_dir, "");
strcpy(sources_path, "");
if ((s = getenv(SOURCES_ENV)))
@@ -1876,9 +1892,20 @@
strcpy(opt_scanned, "");
for (i = 1; i < argc; i++)
{
+ if (strcmp(argv[i],"-P")==0)
+ {
+ //Because its argument can contain spaces we cant use getopt(), a known bug:
+ if (i+1 < argc)
+ {
+ free(opt_Pipe);
+ opt_Pipe = malloc(LINESIZE);
+ strcpy(opt_Pipe, argv[i+1]);
+ }
+ }
strcat(opt_scanned, argv[i]);
strcat(opt_scanned, " ");
}
+ l2l_dbg(4,"opt_scanned=[%s]\n",opt_scanned);
strcpy(opt_logFile, "");
strcpy(opt_7z, CMD_7Z);
@@ -1927,8 +1954,13 @@
case 'r':
opt_raw++;
break;
+ case 'P':
+ optCount++;
+ //just count, see above
+ break;
case 'R':
optCount++;
+ free(opt_Revision);
opt_Revision = malloc(LINESIZE);
sscanf(optarg, "%s", opt_Revision);
break;
@@ -2001,8 +2033,7 @@
return 0;
read_cache();
-
- l2l_dbg(3, "Cache read complete\n");
+ l2l_dbg(4, "Cache read complete\n");
if (*opt_logFile)
{
@@ -2024,6 +2055,22 @@
return 2;
}
}
+ l2l_dbg(4, "opt_logFile processed\n");
+
+ if (opt_Pipe)
+ {
+ l2l_dbg(3, "Command line: \"%s\"\n",opt_Pipe);
+
+ if (!(stdIn = POPEN(opt_Pipe, "r")))
+ {
+ stdIn = stdin; //restore
+ l2l_dbg(0, "Could not popen '%s' (%s)\n", opt_Pipe,
strerror(errno));
+ free(opt_Pipe); opt_Pipe = NULL;
+ }
+
+ free(opt_Pipe); opt_Pipe = NULL;
+ }
+ l2l_dbg(4, "opt_Pipe processed\n");
if (argc > 1)
{ // translate {<exefile> <offset>}
@@ -2043,7 +2090,7 @@
l2l_dbg(2, "translating %s %s\n", exefile, offset);
translate_file(exefile, my_atoi(offset), Line);
printf("%s\n", Line);
- report(stdout);
+ report(stdOut);
}
else
{
@@ -2061,11 +2108,14 @@
}
else
{ // translate logging from stdin
- translate_files(stdin, stdout);
+ translate_files(stdIn, stdOut);
}
if (logFile)
fclose(logFile);
+ if (opt_Pipe)
+ PCLOSE(stdIn);
+
return res;
}
Modified: trunk/reactos/tools/tools.mak
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/tools/tools.mak?rev=45287&…
==============================================================================
--- trunk/reactos/tools/tools.mak [iso-8859-1] (original)
+++ trunk/reactos/tools/tools.mak [iso-8859-1] Wed Jan 27 20:03:52 2010
@@ -44,6 +44,7 @@
include tools/buildno/buildno.mak
include tools/gendib/gendib.mak
include tools/rsym/log2lines.mak
+include tools/pipetools/pipetools.mak
include tools/nci/nci.mak
ifeq ($(ARCH),powerpc)
include tools/ofw_interface/ofw_interface.mak