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