sbsv2/raptor/util/descramble/descramble.cpp
author Richard Taylor <richard.i.taylor@nokia.com>
Wed, 23 Dec 2009 15:10:51 +0000
branchfix
changeset 52 ae46aeb3faf3
parent 3 e1eecf4d390d
permissions -rw-r--r--
typo: bug 170 was fixed, not 107
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
3
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
     1
/*
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
     2
* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
     3
* All rights reserved.
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
     4
* This component and the accompanying materials are made available
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
     5
* under the terms of the License "Eclipse Public License v1.0"
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
     6
* which accompanies this distribution, and is available
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
     8
*
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
     9
* Initial Contributors:
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    10
* Nokia Corporation - initial contribution.
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    11
*
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    12
* Contributors:
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    13
*
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    14
* Description: 
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    15
*
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    16
*/
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    17
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    18
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    19
/*
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    20
 	descramble.cpp:
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    21
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    22
	Description
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    23
	-----------
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    24
	"descramble" is a program that buffers standard input until end of file
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    25
	and then copies the buffers to the standard output in such a way that
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    26
	if there are many copies of descramble running, each will be given an
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    27
	opportunity to write the complete contents of its buffers while the
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    28
	others wait.
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    29
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    30
	Purpose
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    31
	-------
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    32
	descramble is used to ensure that output from multiple concurrent processes
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    33
	is not interleaved.  It is useful in build systems such as GNU make with
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    34
	the -j switch, although it requires that makefiles are changed before it can
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    35
	work.
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    36
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    37
	Design
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    38
	------
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    39
	This program may be built on Linux or on Windows.  On both platforms the
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    40
	basic behavior is similar:
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    41
		1) Read standard input into buffers.  Allocate these dynamically
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    42
		   so that there is no limit.
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    43
		2) Wait on a named or system-wide semaphore.
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    44
		3) Output all the buffers to stdout.
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    45
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    46
	The name of the semaphore is a parameter and should be chosen so that multiple
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    47
	instances of the build system (or whatever process is running many tasks with
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    48
	descramble) cannot block each other.
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    49
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    50
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    51
	Special Considerations for Linux
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    52
	--------------------------------
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    53
	A named semaphore is a file in the filesystem.  It is not automatically removed
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    54
	when a process exits.  descramble provides a "stop" parameter to be run at the
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    55
	"end" of the build system (or other process) that will clean away this semaphore.
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    56
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    57
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    58
	Special Considerations for Windows
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    59
	----------------------------------
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    60
	The windows implementation is built with the MINGW toolchain.  On windows
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    61
	problems have been noticed that require a fairly complex timeout capability
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    62
	such that descramble will not wait "forever" for output from stdin.
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    63
	This solution currently uses a "kill thread" that will stop descramble if
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    64
	it is blocked in a read on stdio for more than the timeout period.
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    65
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    66
	The "kill thread" attempts to print as much of the input from stdin as has
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    67
	been read so far.  It scans this for XML characters and escapes them, finally
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    68
	printing its own XML-formatted error message with the escaped version of the
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    69
	input between <descramble> tags.
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    70
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    71
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    72
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    73
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    74
*/
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    75
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    76
#include <stdio.h>
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    77
#include <vector>
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    78
#include <ctype.h>
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    79
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    80
// what size chunks to allocate/read
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    81
const int BufferSize = 4096;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    82
unsigned int globalreadcounter = 0;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    83
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    84
// OS specific headers
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    85
#ifdef WIN32
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    86
#include <windows.h>
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    87
#include <tlhelp32.h>
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    88
#include <fcntl.h> /*  _O_BINARY */
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    89
#else
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    90
#include <stdlib.h>
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    91
#include <fcntl.h>
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    92
#include <semaphore.h>
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    93
#include <sys/types.h>
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    94
#include <signal.h>
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    95
#include <string.h>
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    96
#endif
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    97
#include <unistd.h>
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    98
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
    99
#define DEFAULT_TIMEOUT (600000) // 10 minutes
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   100
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   101
#define GOOD_OUTPUT 1
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   102
#define BAD_OUTPUT 0
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   103
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   104
typedef struct
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   105
{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   106
	char *name;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   107
	#ifdef WIN32
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   108
 		HANDLE handle;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   109
	#else
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   110
		sem_t *handle;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   111
	#endif
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   112
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   113
	unsigned int timeout;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   114
} sbs_semaphore;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   115
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   116
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   117
// readstate is a flag to indicate whether descramble is reading
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   118
// it's standard input.
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   119
// This allows the timeout thread on Windows to only cause the
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   120
// process to exit if there is an overdue read operation on the
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   121
// standard input.
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   122
int readstate=1;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   123
int timeoutstate=0;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   124
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   125
// The output semaphore.
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   126
sbs_semaphore sem;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   127
#ifdef WIN32
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   128
	HANDLE bufferMutex;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   129
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   130
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   131
	// Make all output handling binary
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   132
	unsigned int _CRT_fmode = _O_BINARY;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   133
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   134
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   135
	DWORD killPIDTree = 0;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   136
#else
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   137
	pid_t killPIDTree = 0;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   138
#endif
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   139
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   140
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   141
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   142
// Where we store all the standard input.
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   143
std::vector<char*> buffers;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   144
std::vector<int> bytesIn;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   145
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   146
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   147
void error(const char *reason, char *SEM_NAME)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   148
{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   149
	fprintf(stderr, "<descrambler reason='%s' semaphore='%s' />\n", reason, SEM_NAME);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   150
	exit(1);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   151
}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   152
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   153
#ifdef WIN32
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   154
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   155
void killProcess(DWORD pid)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   156
{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   157
	HANDLE proc = OpenProcess(PROCESS_TERMINATE,0,pid);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   158
	if (proc)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   159
	{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   160
		TerminateProcess(proc, 1);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   161
		//fprintf(stdout,"sent terminate to process=%d\n", pid);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   162
		CloseHandle(proc);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   163
	}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   164
	else
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   165
	{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   166
		//fprintf(stderr,"Can't open process=%d\n", pid);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   167
	}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   168
}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   169
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   170
typedef struct {
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   171
	DWORD PID;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   172
	DWORD PPID;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   173
} proc;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   174
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   175
void killProcessTreeRecursively(DWORD PPID, DWORD thisPID, std::vector<proc *> &processtree)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   176
{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   177
	int idx;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   178
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   179
	for (idx=0; idx < processtree.size(); idx++)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   180
	{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   181
		if (processtree[idx]->PID != thisPID &&  processtree[idx]->PPID  == PPID)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   182
		{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   183
			killProcessTreeRecursively(processtree[idx]->PID, thisPID, processtree);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   184
			//fprintf(stderr,"Found descendant =%d\n",processtree[idx]->PID );
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   185
		}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   186
	}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   187
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   188
	killProcess(PPID);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   189
}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   190
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   191
int killProcessTree(DWORD PPID)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   192
{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   193
	HANDLE hSnapShot;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   194
	DWORD thisProcID=0;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   195
	BOOL ok;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   196
	PROCESSENTRY32 pe;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   197
	std::vector<proc *> processtree;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   198
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   199
	thisProcID = GetCurrentProcessId();
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   200
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   201
	hSnapShot=CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   202
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   203
	// Put all this process information into an array;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   204
	ok = Process32First(hSnapShot, &pe);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   205
	while (ok)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   206
	{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   207
		if ( pe.th32ProcessID != thisProcID)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   208
		{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   209
			proc *p = new proc;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   210
			p->PID = pe.th32ProcessID;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   211
			p->PPID = pe.th32ParentProcessID;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   212
			processtree.push_back(p);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   213
			//fprintf(stderr,"Found process =%d\n", pe.th32ProcessID );
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   214
		}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   215
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   216
		ok = Process32Next(hSnapShot, &pe);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   217
	}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   218
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   219
	killProcessTreeRecursively(PPID, thisProcID, processtree);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   220
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   221
	CloseHandle(hSnapShot);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   222
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   223
	//fprintf(stderr,"Ending killproc\n", PPID);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   224
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   225
	return 0;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   226
}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   227
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   228
#endif
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   229
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   230
void createDescrambleSemaphore(sbs_semaphore *s)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   231
{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   232
#ifdef WIN32
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   233
	s->handle = CreateSemaphore(NULL, 1, 1, s->name);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   234
	if (s->handle)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   235
		CloseHandle(s->handle);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   236
	else
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   237
		error("unable to create semaphore", s->name);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   238
#else
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   239
	s->handle = sem_open(s->name, O_CREAT | O_EXCL, 0644, 1);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   240
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   241
  	if (s->handle == SEM_FAILED)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   242
	{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   243
		sem_close(s->handle);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   244
	  	error("unable to create semaphore", s->name);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   245
	}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   246
	sem_close(s->handle);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   247
#endif
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   248
}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   249
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   250
void destroyDescrambleSemaphore(sbs_semaphore *s)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   251
{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   252
	#ifdef WIN32
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   253
		/* can't destroy a windows semaphore... */
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   254
	#else
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   255
  		if (sem_unlink(s->name) != 0)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   256
		  	error("unable to unlink semaphore", s->name);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   257
	#endif
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   258
}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   259
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   260
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   261
int waitForOutput(sbs_semaphore *s)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   262
{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   263
	/* try and open the semaphore now */
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   264
        #ifdef WIN32
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   265
		s->handle = CreateSemaphore(NULL, 1, 1, s->name);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   266
		if (!s->handle)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   267
			error("unable to open semaphore", s->name);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   268
        #else
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   269
		s->handle = sem_open(s->name, 0);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   270
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   271
	  	if (s->handle == SEM_FAILED)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   272
		{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   273
    			sem_close(s->handle);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   274
      			error("unable to open semaphore", s->name);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   275
    		}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   276
	#endif
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   277
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   278
    /* wait for the semaphore to be free [timeout after 60 seconds] */
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   279
 	int timedOutFlag = 0;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   280
	#ifdef WIN32
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   281
 		timedOutFlag = (WaitForSingleObject(s->handle, s->timeout) != WAIT_OBJECT_0);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   282
	#else
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   283
		sem_wait(s->handle);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   284
	#endif
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   285
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   286
	return timedOutFlag;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   287
}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   288
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   289
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   290
void  releaseOutput(sbs_semaphore *s)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   291
{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   292
	/* release the semaphore */
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   293
	#ifdef WIN32
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   294
		ReleaseSemaphore(s->handle, 1, NULL);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   295
	#else
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   296
	   	sem_post(s->handle);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   297
	#endif
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   298
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   299
	   /* clean up */
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   300
	#ifdef WIN32
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   301
		CloseHandle(s->handle);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   302
	#else
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   303
	   	sem_close(s->handle);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   304
	#endif
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   305
}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   306
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   307
void writeBuffers(int goodoutput)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   308
{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   309
	/* write stdin buffers to stdout. If the output comes
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   310
	   from a partially-complete command then make sure that there
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   311
	   is no malformed xml inside by escaping it. */
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   312
	char *escaped_output=NULL;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   313
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   314
	#ifdef WIN32
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   315
		DWORD dwWaitResult = WaitForSingleObject(
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   316
		            bufferMutex,
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   317
		            INFINITE);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   318
	#endif
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   319
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   320
	for (int i = 0; i < buffers.size(); i++)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   321
	{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   322
		int bytes_out;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   323
		char *outbuf;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   324
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   325
		if (goodoutput != GOOD_OUTPUT)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   326
		{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   327
			if (!escaped_output)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   328
				escaped_output = new char[BufferSize*4];
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   329
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   330
			if (!escaped_output)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   331
				error("No memory for escaped outputbuffer.",sem.name);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   332
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   333
			char *buf = buffers[i];
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   334
			bytes_out = 0;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   335
			for (int idx=0; idx < bytesIn[i]; idx++)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   336
			{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   337
				switch (buf[idx])
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   338
				{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   339
					case '&':
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   340
						escaped_output[bytes_out++]='&';
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   341
						escaped_output[bytes_out++]='a';
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   342
						escaped_output[bytes_out++]='m';
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   343
						escaped_output[bytes_out++]='p';
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   344
						escaped_output[bytes_out++]=';';
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   345
						break;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   346
					case '<':
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   347
						escaped_output[bytes_out++]='&';
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   348
						escaped_output[bytes_out++]='l';
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   349
						escaped_output[bytes_out++]='t';
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   350
						escaped_output[bytes_out++]=';';
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   351
						break;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   352
					case '>':
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   353
						escaped_output[bytes_out++]='&';
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   354
						escaped_output[bytes_out++]='g';
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   355
						escaped_output[bytes_out++]='t';
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   356
						escaped_output[bytes_out++]=';';
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   357
						break;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   358
					default:
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   359
						if (!iscntrl(buf[idx]) || buf[idx] == '\n' || buf[idx] == '\r')
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   360
							escaped_output[bytes_out++]=buf[idx];
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   361
						break;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   362
				}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   363
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   364
			}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   365
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   366
			outbuf = escaped_output;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   367
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   368
		} else {
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   369
			outbuf = buffers[i];
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   370
			bytes_out = bytesIn[i];
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   371
		}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   372
		fwrite(outbuf, 1, bytes_out, stdout);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   373
	}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   374
	#ifdef WIN32
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   375
		ReleaseMutex(bufferMutex);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   376
	#endif
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   377
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   378
	if (escaped_output)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   379
		delete escaped_output;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   380
	fflush(stdout);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   381
}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   382
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   383
#ifdef WIN32
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   384
/*
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   385
 A Thread that kills this process if it is "stuck" in a read operation
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   386
 for longer than the timeout period.
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   387
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   388
 There are some race conditions here that don't matter. e.g. globalreadcounter
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   389
 is not protected.  This might result in an "unfair" timeout but we don't care
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   390
 because the timeout should be pretty long and anything that's even nearly
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   391
 a timeout deserves to be timed out.
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   392
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   393
 Additionally, if the timeout is so quick that this function starts before the first
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   394
 ever read has happened then there would be a premature timeout.  This is not likely
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   395
 so we also dont' care - the timeout has a minimum value which is more than long
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   396
 enough (500msec) to deal with that.
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   397
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   398
*/
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   399
DWORD descrambleKillerThread(void * param)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   400
{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   401
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   402
	sbs_semaphore *s;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   403
	unsigned int stored_globalreadcounter;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   404
	s = (sbs_semaphore *)param;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   405
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   406
	fflush(stderr);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   407
	//fprintf(stdout, " timeout=%u sem_name='%s' \n", s->timeout, s->name);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   408
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   409
	do
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   410
	{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   411
		stored_globalreadcounter = globalreadcounter;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   412
		Sleep(s->timeout);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   413
	}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   414
	while (globalreadcounter != stored_globalreadcounter);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   415
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   416
	if (waitForOutput(s) != 0)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   417
	{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   418
		fprintf(stdout, "<descrambler reason='semaphore wait exceeded %ums timeout' semaphore='%s' />\n", s->timeout, s->name);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   419
		ExitProcess(3);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   420
	}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   421
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   422
	if (readstate)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   423
	{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   424
		fprintf(stdout, "<descrambler reason='command output read exceeded %ums timeout' semaphore='%s'>\n", s->timeout, s->name);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   425
		writeBuffers(BAD_OUTPUT);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   426
		fprintf(stdout, "</descrambler>\n");
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   427
		fflush(stdout);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   428
		if (killPIDTree != 0)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   429
			killProcessTree(killPIDTree); // Make sure peers and parents all die. Nasty
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   430
		ExitProcess(2);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   431
	}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   432
	else
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   433
	{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   434
		writeBuffers(GOOD_OUTPUT);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   435
	}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   436
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   437
	// Don't release the semaphore in case the main thread
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   438
	// gets it and tries to write the output.
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   439
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   440
	// Input process finished while we were waiting
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   441
	// for the semaphore so a false alarm.
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   442
	fflush(stdout);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   443
	ExitProcess(0);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   444
}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   445
#endif
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   446
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   447
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   448
int main(int argc, char *argv[])
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   449
{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   450
	char usage[]="usage: %s [-t timeout_millisecs] [ -k kill_PID_tree_on_fail  ] buildID [start | stop]\nwhere timeout_millisecs >= 500\n";
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   451
	int opt_res;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   452
	char options[]="t:k:";
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   453
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   454
	sem.timeout = DEFAULT_TIMEOUT;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   455
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   456
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   457
	opt_res = getopt(argc, argv, options);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   458
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   459
	while (opt_res != -1 )
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   460
	{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   461
		switch (opt_res)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   462
		{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   463
			case 'k':
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   464
				if (!optarg)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   465
				{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   466
					fprintf(stderr, "PID argument required for 'kill PID tree on fail' option\n");
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   467
					fprintf(stderr, usage, argv[0]);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   468
					exit(1);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   469
				}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   470
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   471
				killPIDTree = atol(optarg);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   472
				if (killPIDTree == 0)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   473
				{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   474
					fprintf(stderr, usage, argv[0]);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   475
					fprintf(stderr, "kill PID tree on fail must be > 0: %u\n", killPIDTree);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   476
					exit(1);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   477
				}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   478
				break;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   479
			case 't':
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   480
				if (!optarg)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   481
				{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   482
					fprintf(stderr, "timeout argument required for timeout option\n");
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   483
					fprintf(stderr, usage, argv[0]);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   484
					exit(1);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   485
				}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   486
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   487
				sem.timeout = atoi(optarg);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   488
				if (sem.timeout < 500)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   489
				{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   490
					fprintf(stderr, usage, argv[0]);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   491
					fprintf(stderr, "timeout was too low: %u\n", sem.timeout);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   492
					exit(1);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   493
				}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   494
				break;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   495
			case '?':
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   496
			default:
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   497
				fprintf(stderr, usage, argv[0]);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   498
				fprintf(stderr, "Unknown option. %s\n", opterr);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   499
				exit(1);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   500
				break;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   501
		}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   502
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   503
	opt_res = getopt(argc, argv, options);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   504
	}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   505
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   506
	if (optind >= argc)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   507
	{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   508
		fprintf(stderr, usage, argv[0]);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   509
		fprintf(stderr, "Missing buildID\n");
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   510
		exit(1);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   511
	}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   512
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   513
	sem.name = argv[optind];
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   514
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   515
	if (optind + 1 < argc)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   516
	{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   517
		optind++;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   518
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   519
		if (strncmp(argv[optind], "stop",4) == 0)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   520
			destroyDescrambleSemaphore(&sem);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   521
		else if (strncmp(argv[optind],"start",5) == 0)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   522
			createDescrambleSemaphore(&sem);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   523
		else
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   524
		{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   525
			fprintf(stderr, usage, argv[0]);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   526
			fprintf(stderr, "Unknown argument:: %s\n", argv[optind]);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   527
			exit(1);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   528
		}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   529
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   530
		exit(0);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   531
	}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   532
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   533
	#ifdef WIN32
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   534
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   535
		HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   536
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   537
		bufferMutex = CreateMutex(NULL, FALSE, NULL);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   538
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   539
		/*
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   540
		HANDLE WINAPI CreateThread(
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   541
		  __in_opt   LPSECURITY_ATTRIBUTES lpThreadAttributes,
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   542
		  __in       SIZE_T dwStackSize,
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   543
		  __in       LPTHREAD_START_ROUTINE lpStartAddress,
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   544
		  __in_opt   LPVOID lpParameter,
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   545
		  __in       DWORD dwCreationFlags,
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   546
		  __out_opt  LPDWORD lpThreadId
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   547
		); */
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   548
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   549
		DWORD killerThreadId;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   550
		HANDLE hKillerThread;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   551
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   552
		hKillerThread = CreateThread(NULL, 4096, (LPTHREAD_START_ROUTINE) descrambleKillerThread, (void*)&sem, 0, &killerThreadId);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   553
	#endif
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   554
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   555
	/* read all of my stdin into buffers */
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   556
	int bytesRead = 0;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   557
	int bufferIndex = 0;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   558
	do
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   559
	{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   560
		char *buffer = new char[BufferSize];
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   561
		if (buffer == NULL)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   562
			error("not enough memory for buffer", sem.name);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   563
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   564
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   565
		// Add an empty buffer in advance so that if there is a timeout
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   566
		// the partial command result can be gathered.
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   567
		#ifdef WIN32
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   568
			DWORD dwWaitResult = WaitForSingleObject(
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   569
			            bufferMutex,
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   570
			            INFINITE);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   571
		#endif
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   572
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   573
		buffers.push_back(buffer);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   574
		bytesIn.push_back(0);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   575
		int *counter = &bytesIn[bufferIndex];
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   576
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   577
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   578
		#ifdef WIN32
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   579
			ReleaseMutex(bufferMutex);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   580
		#endif
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   581
		// Empty buffer added.
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   582
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   583
		char c = fgetc(stdin);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   584
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   585
		//fprintf(stderr, "counter %d buffersize %d\n", *counter, BufferSize);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   586
		do
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   587
		{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   588
			if (c == EOF)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   589
				break;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   590
			// escape unprintable characters that might make logs unparsable.
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   591
			if (iscntrl(c) && !isspace(c))
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   592
				c = '_';
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   593
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   594
			buffer[*counter] = c;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   595
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   596
			*counter += 1;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   597
			if (*counter >= BufferSize)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   598
				break;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   599
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   600
			c = fgetc(stdin);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   601
			globalreadcounter = ++globalreadcounter % 65535*4;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   602
		}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   603
		while (c != EOF);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   604
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   605
		//fprintf(stderr, "## %d bytesin %d\n", bufferIndex, *counter);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   606
		bufferIndex++;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   607
	}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   608
	while (!feof(stdin) && !timeoutstate);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   609
	readstate = 0; //  Tell the killerthread that it can back off.
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   610
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   611
	int timedout;
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   612
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   613
	timedout = waitForOutput(&sem);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   614
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   615
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   616
 	if (timedout)
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   617
 		error("timed out waiting for semaphore", sem.name);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   618
 	else
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   619
 	{
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   620
		writeBuffers(1);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   621
	}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   622
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   623
	releaseOutput(&sem);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   624
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   625
 	/* let the OS free the buffer memory */
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   626
	exit(0);
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   627
}
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   628
e1eecf4d390d Team sf branch.
tnmurphy@4GBL06592.nokia.com
parents: 0
diff changeset
   629