annotate lib-src/i.c @ 2227:8e7b4a0c1a81

[xemacs-hg @ 2004-08-21 17:05:49 by michaels] 2004-08-15 Jan Rychter <jwr@xemacs.org> * window-xemacs.el (really-set-window-configuration): deal gracefully with the case when the buffer previously saved in the configuration (and that we want to switch to) has been killed. Switch to the next buffer on the buffer-list in that case.
author michaels
date Sat, 21 Aug 2004 17:05:51 +0000
parents 01c57eb70ae9
children bb3f73fbbda8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
1 /* I-connector utility
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
2 Copyright (C) 2000 Kirill M. Katsnelson
1346
01c57eb70ae9 [xemacs-hg @ 2003-03-09 02:27:27 by ben]
ben
parents: 826
diff changeset
3 Copyright (C) 2002, 2003 Ben Wing.
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
4
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
5 This file is part of XEmacs.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
6
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
7 XEmacs is free software; you can redistribute it and/or modify it
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
8 under the terms of the GNU General Public License as published by the
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
9 Free Software Foundation; either version 2, or (at your option) any
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
10 later version.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
11
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
15 for more details.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
16
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
17 You should have received a copy of the GNU General Public License
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
18 along with XEmacs; see the file COPYING. If not, write to
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
20 Boston, MA 02111-1307, USA. */
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
21
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
22 /* When run with an argument, i treats it as a command line, and pipes
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
23 command stdin, stdout and stderr to its own respective streams. How
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
24 silly it should sound, but windowed program in Win32 cannot do output
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
25 to the console from which it has been started, and should be run using
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
26 this utility.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
27
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
28 This utility is for running [tx]emacs as part of make process so that
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
29 its output goes to the same console as the rest of the make output
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
30 does. It can be used also when xemacs should be run as a batch
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
31 command ina script, especially when its standart output should be
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
32 obtained programmatically. */
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
33
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
34 #include <windows.h>
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
35 #include <stdio.h>
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
36 #include <string.h>
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
37 #include <tchar.h>
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
38
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
39 typedef struct
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
40 {
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
41 HANDLE source;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
42 HANDLE drain;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
43 } I_connector;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
44
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
45 /*
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
46 * Make new handle as that pointed to by PH but
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
47 * inheritable, substitute PH with it, and close the
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
48 * original one
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
49 */
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
50 static void
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
51 make_inheritable (HANDLE* ph)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
52 {
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
53 HANDLE htmp;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
54 DuplicateHandle (GetCurrentProcess(), *ph, GetCurrentProcess(), &htmp,
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
55 0, TRUE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS);
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
56 *ph = htmp;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
57 }
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
58
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
59 /*
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
60 * Worker thread proc. Reads source, pumps into drain,
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
61 * till either clogs.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
62 */
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
63 static DWORD CALLBACK
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
64 pump (LPVOID pv_i)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
65 {
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
66 I_connector* pi = (I_connector*) pv_i;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
67 BYTE buffer [256];
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
68 DWORD really_read, unused;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
69
1346
01c57eb70ae9 [xemacs-hg @ 2003-03-09 02:27:27 by ben]
ben
parents: 826
diff changeset
70 /* The docs for ReadFile claim:
01c57eb70ae9 [xemacs-hg @ 2003-03-09 02:27:27 by ben]
ben
parents: 826
diff changeset
71
01c57eb70ae9 [xemacs-hg @ 2003-03-09 02:27:27 by ben]
ben
parents: 826
diff changeset
72 The ReadFile function returns when one of the following is true: a write
01c57eb70ae9 [xemacs-hg @ 2003-03-09 02:27:27 by ben]
ben
parents: 826
diff changeset
73 operation completes on the write end of the pipe, the number of bytes
01c57eb70ae9 [xemacs-hg @ 2003-03-09 02:27:27 by ben]
ben
parents: 826
diff changeset
74 requested has been read, or an error occurs.
01c57eb70ae9 [xemacs-hg @ 2003-03-09 02:27:27 by ben]
ben
parents: 826
diff changeset
75
01c57eb70ae9 [xemacs-hg @ 2003-03-09 02:27:27 by ben]
ben
parents: 826
diff changeset
76 But this is just not true. ReadFile never seems to block, and unless we
01c57eb70ae9 [xemacs-hg @ 2003-03-09 02:27:27 by ben]
ben
parents: 826
diff changeset
77 Sleep(), we will chew up all the CPU time. --ben
01c57eb70ae9 [xemacs-hg @ 2003-03-09 02:27:27 by ben]
ben
parents: 826
diff changeset
78 */
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
79 while (ReadFile (pi->source, buffer, sizeof (buffer), &really_read, NULL) &&
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
80 WriteFile (pi->drain, buffer, really_read, &unused, NULL))
1346
01c57eb70ae9 [xemacs-hg @ 2003-03-09 02:27:27 by ben]
ben
parents: 826
diff changeset
81 Sleep (100);
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
82
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
83 return 0;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
84 }
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
85
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
86 /*
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
87 * Launch a pump for the given I-connector
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
88 */
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
89 static void
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
90 start_pump (I_connector* pi)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
91 {
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
92 DWORD unused;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
93 HANDLE h_thread = CreateThread (NULL, 0, pump, (void*)pi, 0, &unused);
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
94 CloseHandle (h_thread);
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
95 }
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
96
826
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
97 static HANDLE external_event;
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
98
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
99 static BOOL
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
100 ctrl_c_handler (unsigned long type)
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
101 {
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
102 SetEvent (external_event);
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
103 return FALSE;
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
104 }
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
105
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
106 /* Skip over the executable name in the given command line. Correctly
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
107 handles quotes in the name. Return NULL upon error. If
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
108 REQUIRE_FOLLOWING is non-zero, it's an error if no argument follows the
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
109 executable name. */
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
110
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
111 static LPTSTR
826
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
112 skip_executable_name (LPTSTR cl, int require_following)
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
113 {
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
114 int ix;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
115
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
116 while (1)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
117 {
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
118 ix = _tcscspn (cl, _T(" \t\""));
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
119 if (cl[ix] == '\"')
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
120 {
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
121 cl = _tcschr (cl + ix + 1, '\"');
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
122 if (cl == NULL)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
123 return NULL; /* Unmatched quote */
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
124 cl++;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
125 }
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
126 else
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
127 {
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
128 cl += ix;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
129 cl += _tcsspn (cl, _T(" \t"));
826
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
130 if (!require_following)
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
131 return cl;
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
132 return *cl ? cl : NULL;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
133 }
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
134 }
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
135 }
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
136
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
137 /*
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
138 * Brew coffee and bring snickers
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
139 */
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
140 void
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
141 usage (void)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
142 {
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
143 fprintf (stderr,
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
144 "\n"
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
145 "usage: i command\n"
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
146 "i executes the command and reroutes its standard handles to the calling\n"
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
147 "console. Good for seeing output of GUI programs that use standard output."
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
148 "\n");
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
149 }
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
150
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
151 int
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
152 main (void)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
153 {
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
154 STARTUPINFO si;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
155 PROCESS_INFORMATION pi;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
156 I_connector I_in, I_out, I_err;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
157 DWORD exit_code;
826
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
158 LPTSTR command = skip_executable_name (GetCommandLine (), 1);
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
159
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
160 if (command == NULL)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
161 {
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
162 usage ();
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
163 return 1;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
164 }
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
165
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
166 ZeroMemory (&si, sizeof (si));
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
167 si.dwFlags = STARTF_USESTDHANDLES;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
168
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
169 I_in.source = GetStdHandle (STD_INPUT_HANDLE);
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
170 CreatePipe (&si.hStdInput, &I_in.drain, NULL, 0);
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
171 make_inheritable (&si.hStdInput);
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
172
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
173 I_out.drain = GetStdHandle (STD_OUTPUT_HANDLE);
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
174 CreatePipe (&I_out.source, &si.hStdOutput, NULL, 0);
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
175 make_inheritable (&si.hStdOutput);
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
176
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
177 I_err.drain = GetStdHandle (STD_ERROR_HANDLE);
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
178 CreatePipe (&I_err.source, &si.hStdError, NULL, 0);
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
179 make_inheritable (&si.hStdError);
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
180
826
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
181 {
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
182 SECURITY_ATTRIBUTES sa;
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
183 LPTSTR new_command =
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
184 (LPTSTR) malloc (666 + sizeof (TCHAR) * _tcslen (command));
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
185 LPTSTR past_exe;
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
186
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
187 if (!new_command)
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
188 {
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
189 _ftprintf (stderr, _T ("Out of memory when launching `%s'\n"),
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
190 command);
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
191 return 2;
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
192 }
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
193
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
194 past_exe = skip_executable_name (command, 0);
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
195 if (!past_exe)
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
196 {
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
197 usage ();
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
198 return 1;
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
199 }
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
200
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
201 /* Since XEmacs isn't a console application, it can't easily be
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
202 terminated using ^C. Therefore, we set up a communication path with
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
203 it so that when a ^C is sent to us (using GenerateConsoleCtrlEvent),
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
204 we in turn signals it to commit suicide. (This is cleaner than using
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
205 TerminateProcess()). This makes (e.g.) the "Stop Build" command
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
206 from VC++ correctly terminate XEmacs.
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
207
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
208 #### This will cause problems if i.exe is used for commands other
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
209 than XEmacs. We need to make behavior this a command-line
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
210 option. */
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
211
826
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
212 /* Create the event as inheritable so that we can use it to communicate
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
213 with the child process */
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
214 sa.nLength = sizeof (sa);
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
215 sa.bInheritHandle = TRUE;
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
216 sa.lpSecurityDescriptor = NULL;
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
217 external_event = CreateEvent (&sa, FALSE, FALSE, NULL);
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
218 if (!external_event)
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
219 {
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
220 _ftprintf (stderr, _T ("Error %d creating signal event for `%s'\n"),
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
221 GetLastError (), command);
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
222 return 2;
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
223 }
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
224
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
225 SetConsoleCtrlHandler ((PHANDLER_ROUTINE) ctrl_c_handler, TRUE);
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
226 _tcsncpy (new_command, command, past_exe - command);
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
227 _stprintf (new_command + (past_exe - command),
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
228 /* start with space in case no args past command name */
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
229 " -mswindows-termination-handle %d ", (long) external_event);
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
230 _tcscat (new_command, past_exe);
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
231
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
232 if (CreateProcess (NULL, new_command, NULL, NULL, TRUE, 0,
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
233 NULL, NULL, &si, &pi) == 0)
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
234 {
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
235 _ftprintf (stderr, _T("Error %d launching `%s'\n"),
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
236 GetLastError (), command);
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
237 return 2;
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
238 }
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
239
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
240 CloseHandle (pi.hThread);
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
241 }
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 442
diff changeset
242
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
243
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
244 /* Start pump in each I-connector */
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
245 start_pump (&I_in);
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
246 start_pump (&I_out);
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
247 start_pump (&I_err);
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
248
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
249 /* Wait for the process to complete */
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
250 WaitForSingleObject (pi.hProcess, INFINITE);
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
251 GetExitCodeProcess (pi.hProcess, &exit_code);
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
252 CloseHandle (pi.hProcess);
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
253
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
254 /* Make pump threads eventually die out. Looks rude, I agree */
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
255 CloseHandle (GetStdHandle (STD_INPUT_HANDLE));
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
256 CloseHandle (GetStdHandle (STD_OUTPUT_HANDLE));
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
257 CloseHandle (GetStdHandle (STD_ERROR_HANDLE));
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
258
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
259 return exit_code;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents:
diff changeset
260 }