os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/win/stub16.c
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/* 
sl@0
     2
 * stub16.c 
sl@0
     3
 *
sl@0
     4
 *	A helper program used for running 16-bit DOS applications under
sl@0
     5
 *	Windows 95.
sl@0
     6
 *
sl@0
     7
 * Copyright (c) 1996 by Sun Microsystems, Inc.
sl@0
     8
 *
sl@0
     9
 * See the file "license.terms" for information on usage and redistribution
sl@0
    10
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
sl@0
    11
 *
sl@0
    12
 * RCS: @(#) $Id: stub16.c,v 1.4 1999/04/21 21:50:34 rjohnson Exp $
sl@0
    13
 */
sl@0
    14
sl@0
    15
#define STRICT
sl@0
    16
sl@0
    17
#include <windows.h>
sl@0
    18
#include <stdio.h>
sl@0
    19
sl@0
    20
static HANDLE		CreateTempFile(void);
sl@0
    21
sl@0
    22
/*
sl@0
    23
 *---------------------------------------------------------------------------
sl@0
    24
 *
sl@0
    25
 * main
sl@0
    26
 *
sl@0
    27
 *	Entry point for the 32-bit console mode app used by Windows 95 to
sl@0
    28
 *	help run the 16-bit program specified on the command line.
sl@0
    29
 *
sl@0
    30
 *	1. EOF on a pipe that connects a detached 16-bit process and a
sl@0
    31
 *	32-bit process is never seen.  So, this process runs the 16-bit
sl@0
    32
 *	process _attached_, and then it is run detached from the calling
sl@0
    33
 *	32-bit process.  
sl@0
    34
 * 
sl@0
    35
 *	2. If a 16-bit process blocks reading from or writing to a pipe,
sl@0
    36
 *	it never wakes up, and eventually brings the whole system down
sl@0
    37
 *	with it if you try to kill the process.  This app simulates
sl@0
    38
 *	pipes.  If any of the stdio handles is a pipe, this program
sl@0
    39
 *	accumulates information into temp files and forwards it to or
sl@0
    40
 *	from the DOS application as appropriate.  This means that this
sl@0
    41
 *	program must receive EOF from a stdin pipe before it will actually
sl@0
    42
 *	start the DOS app, and the DOS app must finish generating stdout
sl@0
    43
 *	or stderr before the data will be sent to the next stage of the
sl@0
    44
 *	pipe.  If the stdio handles are not pipes, no accumulation occurs
sl@0
    45
 *	and the data is passed straight through to and from the DOS
sl@0
    46
 *	application.
sl@0
    47
 *
sl@0
    48
 * Results:
sl@0
    49
 *	None.
sl@0
    50
 *
sl@0
    51
 * Side effects:
sl@0
    52
 *	The child process is created and this process waits for it to
sl@0
    53
 *	complete.
sl@0
    54
 *
sl@0
    55
 *---------------------------------------------------------------------------
sl@0
    56
 */
sl@0
    57
sl@0
    58
int
sl@0
    59
main()
sl@0
    60
{
sl@0
    61
    DWORD dwRead, dwWrite;
sl@0
    62
    char *cmdLine;
sl@0
    63
    HANDLE hStdInput, hStdOutput, hStdError;
sl@0
    64
    HANDLE hFileInput, hFileOutput, hFileError;
sl@0
    65
    STARTUPINFO si;
sl@0
    66
    PROCESS_INFORMATION pi;
sl@0
    67
    char buf[8192];
sl@0
    68
    DWORD result;
sl@0
    69
sl@0
    70
    hFileInput = INVALID_HANDLE_VALUE;
sl@0
    71
    hFileOutput = INVALID_HANDLE_VALUE;
sl@0
    72
    hFileError = INVALID_HANDLE_VALUE;
sl@0
    73
    result = 1;
sl@0
    74
sl@0
    75
    /*
sl@0
    76
     * Don't get command line from argc, argv, because the command line
sl@0
    77
     * tokenizer will have stripped off all the escape sequences needed
sl@0
    78
     * for quotes and backslashes, and then we'd have to put them all
sl@0
    79
     * back in again.  Get the raw command line and parse off what we
sl@0
    80
     * want ourselves.  The command line should be of the form:
sl@0
    81
     *
sl@0
    82
     * stub16.exe program arg1 arg2 ...
sl@0
    83
     */
sl@0
    84
sl@0
    85
    cmdLine = strchr(GetCommandLine(), ' ');
sl@0
    86
    if (cmdLine == NULL) {
sl@0
    87
	return 1;
sl@0
    88
    }
sl@0
    89
    cmdLine++;
sl@0
    90
sl@0
    91
    hStdInput = GetStdHandle(STD_INPUT_HANDLE);
sl@0
    92
    hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
sl@0
    93
    hStdError = GetStdHandle(STD_ERROR_HANDLE);
sl@0
    94
sl@0
    95
    if (GetFileType(hStdInput) == FILE_TYPE_PIPE) {
sl@0
    96
	hFileInput = CreateTempFile();
sl@0
    97
	if (hFileInput == INVALID_HANDLE_VALUE) {
sl@0
    98
	    goto cleanup;
sl@0
    99
	}
sl@0
   100
	while (ReadFile(hStdInput, buf, sizeof(buf), &dwRead, NULL) != FALSE) {
sl@0
   101
	    if (dwRead == 0) {
sl@0
   102
		break;
sl@0
   103
	    }
sl@0
   104
	    if (WriteFile(hFileInput, buf, dwRead, &dwWrite, NULL) == FALSE) {
sl@0
   105
		goto cleanup;
sl@0
   106
	    }
sl@0
   107
	}
sl@0
   108
	SetFilePointer(hFileInput, 0, 0, FILE_BEGIN);
sl@0
   109
	SetStdHandle(STD_INPUT_HANDLE, hFileInput);
sl@0
   110
    }
sl@0
   111
    if (GetFileType(hStdOutput) == FILE_TYPE_PIPE) {
sl@0
   112
	hFileOutput = CreateTempFile();
sl@0
   113
	if (hFileOutput == INVALID_HANDLE_VALUE) {
sl@0
   114
	    goto cleanup;
sl@0
   115
	}
sl@0
   116
	SetStdHandle(STD_OUTPUT_HANDLE, hFileOutput);
sl@0
   117
    }
sl@0
   118
    if (GetFileType(hStdError) == FILE_TYPE_PIPE) {
sl@0
   119
	hFileError = CreateTempFile();
sl@0
   120
	if (hFileError == INVALID_HANDLE_VALUE) {
sl@0
   121
	    goto cleanup;
sl@0
   122
	}
sl@0
   123
	SetStdHandle(STD_ERROR_HANDLE, hFileError);
sl@0
   124
    }
sl@0
   125
sl@0
   126
    ZeroMemory(&si, sizeof(si));
sl@0
   127
    si.cb = sizeof(si);
sl@0
   128
    if (CreateProcess(NULL, cmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, 
sl@0
   129
	    &pi) == FALSE) {
sl@0
   130
	goto cleanup;
sl@0
   131
    }
sl@0
   132
sl@0
   133
    WaitForInputIdle(pi.hProcess, 5000);
sl@0
   134
    WaitForSingleObject(pi.hProcess, INFINITE);
sl@0
   135
    GetExitCodeProcess(pi.hProcess, &result);
sl@0
   136
    CloseHandle(pi.hProcess);
sl@0
   137
    CloseHandle(pi.hThread);
sl@0
   138
sl@0
   139
    if (hFileOutput != INVALID_HANDLE_VALUE) {
sl@0
   140
	SetFilePointer(hFileOutput, 0, 0, FILE_BEGIN);
sl@0
   141
	while (ReadFile(hFileOutput, buf, sizeof(buf), &dwRead, NULL) != FALSE) {
sl@0
   142
	    if (dwRead == 0) {
sl@0
   143
		break;
sl@0
   144
	    }
sl@0
   145
	    if (WriteFile(hStdOutput, buf, dwRead, &dwWrite, NULL) == FALSE) {
sl@0
   146
		break;
sl@0
   147
	    }
sl@0
   148
	}
sl@0
   149
    }
sl@0
   150
    if (hFileError != INVALID_HANDLE_VALUE) {
sl@0
   151
	SetFilePointer(hFileError, 0, 0, FILE_BEGIN);
sl@0
   152
	while (ReadFile(hFileError, buf, sizeof(buf), &dwRead, NULL) != FALSE) {
sl@0
   153
	    if (dwRead == 0) {
sl@0
   154
		break;
sl@0
   155
	    }
sl@0
   156
	    if (WriteFile(hStdError, buf, dwRead, &dwWrite, NULL) == FALSE) {
sl@0
   157
		break;
sl@0
   158
	    }
sl@0
   159
	}
sl@0
   160
    }
sl@0
   161
sl@0
   162
cleanup:
sl@0
   163
    if (hFileInput != INVALID_HANDLE_VALUE) {
sl@0
   164
	CloseHandle(hFileInput);
sl@0
   165
    }
sl@0
   166
    if (hFileOutput != INVALID_HANDLE_VALUE) {
sl@0
   167
	CloseHandle(hFileOutput);
sl@0
   168
    }
sl@0
   169
    if (hFileError != INVALID_HANDLE_VALUE) {
sl@0
   170
	CloseHandle(hFileError);
sl@0
   171
    }
sl@0
   172
    CloseHandle(hStdInput);
sl@0
   173
    CloseHandle(hStdOutput);
sl@0
   174
    CloseHandle(hStdError);
sl@0
   175
    ExitProcess(result);
sl@0
   176
    return 1;
sl@0
   177
}
sl@0
   178
sl@0
   179
static HANDLE
sl@0
   180
CreateTempFile()
sl@0
   181
{
sl@0
   182
    char name[MAX_PATH];
sl@0
   183
    SECURITY_ATTRIBUTES sa;
sl@0
   184
sl@0
   185
    if (GetTempPath(sizeof(name), name) == 0) {
sl@0
   186
	return INVALID_HANDLE_VALUE;
sl@0
   187
    }
sl@0
   188
    if (GetTempFileName(name, "tcl", 0, name) == 0) {
sl@0
   189
	return INVALID_HANDLE_VALUE;
sl@0
   190
    }
sl@0
   191
sl@0
   192
    sa.nLength = sizeof(sa);
sl@0
   193
    sa.lpSecurityDescriptor = NULL;
sl@0
   194
    sa.bInheritHandle = TRUE;
sl@0
   195
    return CreateFile(name, GENERIC_READ | GENERIC_WRITE, 0, &sa, 
sl@0
   196
	    CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
sl@0
   197
	    NULL);
sl@0
   198
}