os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/win/stub16.c
First public contribution.
4 * A helper program used for running 16-bit DOS applications under
7 * Copyright (c) 1996 by Sun Microsystems, Inc.
9 * See the file "license.terms" for information on usage and redistribution
10 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
12 * RCS: @(#) $Id: stub16.c,v 1.4 1999/04/21 21:50:34 rjohnson Exp $
20 static HANDLE CreateTempFile(void);
23 *---------------------------------------------------------------------------
27 * Entry point for the 32-bit console mode app used by Windows 95 to
28 * help run the 16-bit program specified on the command line.
30 * 1. EOF on a pipe that connects a detached 16-bit process and a
31 * 32-bit process is never seen. So, this process runs the 16-bit
32 * process _attached_, and then it is run detached from the calling
35 * 2. If a 16-bit process blocks reading from or writing to a pipe,
36 * it never wakes up, and eventually brings the whole system down
37 * with it if you try to kill the process. This app simulates
38 * pipes. If any of the stdio handles is a pipe, this program
39 * accumulates information into temp files and forwards it to or
40 * from the DOS application as appropriate. This means that this
41 * program must receive EOF from a stdin pipe before it will actually
42 * start the DOS app, and the DOS app must finish generating stdout
43 * or stderr before the data will be sent to the next stage of the
44 * pipe. If the stdio handles are not pipes, no accumulation occurs
45 * and the data is passed straight through to and from the DOS
52 * The child process is created and this process waits for it to
55 *---------------------------------------------------------------------------
61 DWORD dwRead, dwWrite;
63 HANDLE hStdInput, hStdOutput, hStdError;
64 HANDLE hFileInput, hFileOutput, hFileError;
66 PROCESS_INFORMATION pi;
70 hFileInput = INVALID_HANDLE_VALUE;
71 hFileOutput = INVALID_HANDLE_VALUE;
72 hFileError = INVALID_HANDLE_VALUE;
76 * Don't get command line from argc, argv, because the command line
77 * tokenizer will have stripped off all the escape sequences needed
78 * for quotes and backslashes, and then we'd have to put them all
79 * back in again. Get the raw command line and parse off what we
80 * want ourselves. The command line should be of the form:
82 * stub16.exe program arg1 arg2 ...
85 cmdLine = strchr(GetCommandLine(), ' ');
86 if (cmdLine == NULL) {
91 hStdInput = GetStdHandle(STD_INPUT_HANDLE);
92 hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
93 hStdError = GetStdHandle(STD_ERROR_HANDLE);
95 if (GetFileType(hStdInput) == FILE_TYPE_PIPE) {
96 hFileInput = CreateTempFile();
97 if (hFileInput == INVALID_HANDLE_VALUE) {
100 while (ReadFile(hStdInput, buf, sizeof(buf), &dwRead, NULL) != FALSE) {
104 if (WriteFile(hFileInput, buf, dwRead, &dwWrite, NULL) == FALSE) {
108 SetFilePointer(hFileInput, 0, 0, FILE_BEGIN);
109 SetStdHandle(STD_INPUT_HANDLE, hFileInput);
111 if (GetFileType(hStdOutput) == FILE_TYPE_PIPE) {
112 hFileOutput = CreateTempFile();
113 if (hFileOutput == INVALID_HANDLE_VALUE) {
116 SetStdHandle(STD_OUTPUT_HANDLE, hFileOutput);
118 if (GetFileType(hStdError) == FILE_TYPE_PIPE) {
119 hFileError = CreateTempFile();
120 if (hFileError == INVALID_HANDLE_VALUE) {
123 SetStdHandle(STD_ERROR_HANDLE, hFileError);
126 ZeroMemory(&si, sizeof(si));
128 if (CreateProcess(NULL, cmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &si,
133 WaitForInputIdle(pi.hProcess, 5000);
134 WaitForSingleObject(pi.hProcess, INFINITE);
135 GetExitCodeProcess(pi.hProcess, &result);
136 CloseHandle(pi.hProcess);
137 CloseHandle(pi.hThread);
139 if (hFileOutput != INVALID_HANDLE_VALUE) {
140 SetFilePointer(hFileOutput, 0, 0, FILE_BEGIN);
141 while (ReadFile(hFileOutput, buf, sizeof(buf), &dwRead, NULL) != FALSE) {
145 if (WriteFile(hStdOutput, buf, dwRead, &dwWrite, NULL) == FALSE) {
150 if (hFileError != INVALID_HANDLE_VALUE) {
151 SetFilePointer(hFileError, 0, 0, FILE_BEGIN);
152 while (ReadFile(hFileError, buf, sizeof(buf), &dwRead, NULL) != FALSE) {
156 if (WriteFile(hStdError, buf, dwRead, &dwWrite, NULL) == FALSE) {
163 if (hFileInput != INVALID_HANDLE_VALUE) {
164 CloseHandle(hFileInput);
166 if (hFileOutput != INVALID_HANDLE_VALUE) {
167 CloseHandle(hFileOutput);
169 if (hFileError != INVALID_HANDLE_VALUE) {
170 CloseHandle(hFileError);
172 CloseHandle(hStdInput);
173 CloseHandle(hStdOutput);
174 CloseHandle(hStdError);
183 SECURITY_ATTRIBUTES sa;
185 if (GetTempPath(sizeof(name), name) == 0) {
186 return INVALID_HANDLE_VALUE;
188 if (GetTempFileName(name, "tcl", 0, name) == 0) {
189 return INVALID_HANDLE_VALUE;
192 sa.nLength = sizeof(sa);
193 sa.lpSecurityDescriptor = NULL;
194 sa.bInheritHandle = TRUE;
195 return CreateFile(name, GENERIC_READ | GENERIC_WRITE, 0, &sa,
196 CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,