Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/tcl8.5.2/win/stub16.c @ 25

Last change on this file since 25 was 25, checked in by landauf, 16 years ago

added tcl to libs

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