1 /* $Id: spawn.c,v 1.3 2000/11/16 14:21:31 amura Exp $ */
2 /*
3 * Spawn CLI for Win32.
4 *
5 * I make this file from MS-DOS spawn.c.
6 */
7
8 /*
9 * $Log: spawn.c,v $
10 * Revision 1.3 2000/11/16 14:21:31 amura
11 * merge Ng for win32 0.5
12 *
13 * Revision 1.2 2000/10/23 13:19:52 amura
14 * now impliment call_process() and spawncli()
15 *
16 * Revision 1.1.1.1 2000/06/27 01:48:00 amura
17 * import to CVS
18 *
19 */
20 /* 90.02.11 Modified for Ng 1.0 MS-DOS ver. by S.Yoshida */
21
22 #include "config.h" /* 90.12.20 by S.Yoshida */
23 #include <windows.h>
24 #include "def.h"
25 #include "tools.h"
26
27 int
spawncli(int f,int n)28 spawncli( int f, int n)
29 {
30 STARTUPINFO si;
31 PROCESS_INFORMATION pi;
32 BOOL bSuccess;
33 char *shell;
34
35 ewprintf("[Starting new shell]");
36 if ((shell=getenv("COMSPEC")) == NULL) {
37 ewprintf("Can't find shell");
38 return FALSE;
39 }
40 memset(&si, 0, sizeof(si));
41 si.cb = sizeof(si);
42 si.lpTitle = "MicroEmacs Subprocess";
43 #ifdef EXTD_DIR
44 ensurecwd();
45 #endif
46 bSuccess = CreateProcess(NULL, shell, NULL, NULL,
47 FALSE, CREATE_NEW_CONSOLE, NULL,
48 NULL, &si, &pi);
49 return (bSuccess) ? TRUE : FALSE;
50 }
51
52 int
tticon(int f,int n)53 tticon( int f, int n )
54 {
55 extern HWND g_hwndMain;
56 #ifdef _WIN32_WCE
57 #if 0
58 HWND next;
59
60 next = GetWindow(g_hwndMain, GW_HWNDNEXT);
61 if (next) {
62 #ifdef CTRLMAP
63 extern DWORD g_ctrlmap;
64 if (g_ctrlmap) {
65 /* send ctrl key `up' event in order to prevent
66 ctrl key to be kept in a state of `depressed' */
67 keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);
68 }
69 #endif
70 SetForegroundWindow(next);
71 }
72 else {
73 SetWindowPos(g_hwndMain, HWND_BOTTOM, 0, 0, 0, 0,
74 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE
75 #ifdef SWP_NOSENDCHANGING
76 | SWP_NOSENDCHANGING);
77 #endif
78 }
79 #else /* Always activate */
80 SetWindowPos(g_hwndMain, HWND_BOTTOM, 0, 0, 0, 0,
81 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE
82 #ifdef SWP_NOSENDCHANGING
83 | SWP_NOSENDCHANGING);
84 #endif
85 #endif /* 1 */
86 #else /* not _WIN32_WCE */
87 CloseWindow(g_hwndMain);
88 #endif /* _WIN32_WCE */
89 return TRUE;
90 }
91
92 #ifndef NO_SHELL /* 91.01.10 by K.Maeda / Modified by sahf and amura */
93
94 char tempfile[NFILEN];
95
96 /*
97 * Call process in subshell.
98 * Execute COMMAND binding standard input to file INPUT.
99 * NULL as INPUT means standard input should be bound to
100 * /dev/null or whatever equivalent in your OS.
101 * All output during the execution (including standard error output)
102 * should go into a scratch file, whose name call_process() returns.
103 * Return value NULL means error in some stage of the execution.
104 * In that case, scratch file should be deleted.
105 */
106 char *
call_process(command,input)107 call_process(command, input)
108 char *command;
109 char *input;
110 {
111 extern char *mktemp();
112 int cmdlen;
113 char *sbuf, *tmp, *temp_path, *shell;
114 LPTSTR buf;
115 BOOL bSuccess;
116 HANDLE hRead, hWrite;
117 SECURITY_ATTRIBUTES sa;
118 STARTUPINFO si;
119 PROCESS_INFORMATION pi;
120
121 if ((shell=getenv("COMSPEC")) != NULL) {
122 int shlen;
123 cmdlen = strlen(command) + strlen(shell) + 5;
124 if ((sbuf=malloc(cmdlen)) == NULL)
125 return NULL;
126 strcpy(sbuf, shell);
127 strcat(sbuf, " /c ");
128 #ifdef KANJI
129 shlen = strlen(sbuf);
130 strcat(sbuf, command);
131 bufetos(sbuf+shlen, cmdlen-shlen);
132 #else
133 strcat(sbuf, command);
134 #endif
135 }
136 else {
137 cmdlen = strlen(command)+1;
138 if ((sbuf=malloc(cmdlen)) == NULL)
139 return NULL;
140 strcpy(sbuf, command);
141 #ifdef KANJI
142 bufetos(sbuf, cmdlen);
143 #endif
144 }
145 cmdlen = sjis2unicode((LPBYTE)sbuf, NULL, 0);
146 if ((buf=malloc(cmdlen)) == NULL) {
147 free(sbuf);
148 return NULL;
149 }
150 sjis2unicode(sbuf, buf, cmdlen);
151 free(sbuf);
152
153 temp_path = getenv("TMP");
154 if (temp_path == NULL)
155 temp_path = getenv("tmp");
156 if (temp_path == NULL)
157 temp_path = getenv("TEMP");
158 if (temp_path == NULL)
159 temp_path = getenv("temp");
160
161 tmp = tempfile;
162 if (temp_path && *temp_path) {
163 while (*tmp = *temp_path++) {
164 tmp++;
165 }
166 if (tmp[-1] != '/' && tmp[-1] != '\\') {
167 *tmp++ = '/';
168 }
169 }
170 strcpy(tmp, "ngXXXXXX");
171 if ((tmp = mktemp(tempfile)) == NULL) {
172 return NULL;
173 }
174 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
175 sa.lpSecurityDescriptor = NULL;
176 sa.bInheritHandle = TRUE;
177 hRead = CreateFile(input ? input : "NUL", GENERIC_READ, 0, &sa,
178 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
179 hWrite = CreateFile(tmp, GENERIC_READ | GENERIC_WRITE, 0, &sa,
180 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
181
182 /* For OS panic during spawn child process */
183 if (GetFileType(tmp) == FILE_TYPE_UNKNOWN)
184 MoveFileEx(tmp, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
185
186 memset(&si, 0, sizeof(si));
187 si.cb = sizeof(si);
188 si.hStdInput = hRead;
189 si.hStdOutput = hWrite;
190 si.hStdError = hWrite;
191 si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
192 si.wShowWindow = SW_MINIMIZE; /* or SW_HIDE */
193 #ifdef EXTD_DIR
194 ensurecwd();
195 #endif
196 bSuccess = CreateProcess(NULL, buf, NULL, NULL,
197 TRUE, 0, NULL, NULL, &si, &pi);
198 WaitForSingleObject(pi.hProcess, INFINITE);
199 CloseHandle(pi.hThread); CloseHandle(pi.hProcess);
200 CloseHandle(hRead); CloseHandle(hWrite);
201 free(buf);
202 if (!bSuccess) {
203 unlink(tmp);
204 return NULL;
205 }
206 return tmp;
207 }
208 #endif /* NO_SHELL */
209