Added the DFCS_{HOT,TRANSPARENT} definitions.
[wine/gsoc_dplay.git] / dlls / msvcrt / process.c
blobe9b66fee54674538bcb98eeb164e00eabffc473f
1 /*
2 * msvcrt.dll spawn/exec functions
4 * Copyright 1996,1998 Marcus Meissner
5 * Copyright 1996 Jukka Iivonen
6 * Copyright 1997,2000 Uwe Bonnes
7 * Copyright 2000 Jon Griffiths
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 * FIXME:
24 * -File handles need some special handling. Sometimes children get
25 * open file handles, sometimes not. The docs are confusing
26 * -No check for maximum path/argument/environment size is done
28 #include "msvcrt.h"
29 #include "ms_errno.h"
31 #include "msvcrt/process.h"
32 #include "msvcrt/stdlib.h"
33 #include "msvcrt/string.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
39 /* FIXME: Check file extensions for app to run */
40 static const unsigned int EXE = 'e' << 16 | 'x' << 8 | 'e';
41 static const unsigned int BAT = 'b' << 16 | 'a' << 8 | 't';
42 static const unsigned int CMD = 'c' << 16 | 'm' << 8 | 'd';
43 static const unsigned int COM = 'c' << 16 | 'o' << 8 | 'm';
45 /* INTERNAL: Spawn a child process */
46 static int msvcrt_spawn(int flags, const char* exe, char* cmdline, char* env)
48 STARTUPINFOA si;
49 PROCESS_INFORMATION pi;
51 if (sizeof(HANDLE) != sizeof(int))
52 WARN("This call is unsuitable for your architecture\n");
54 if ((unsigned)flags > _P_DETACH)
56 SET_THREAD_VAR(errno,MSVCRT_EINVAL);
57 return -1;
60 FIXME(":must dup/kill streams for child process\n");
62 memset(&si, 0, sizeof(si));
63 si.cb = sizeof(si);
65 if (!CreateProcessA(exe, cmdline, NULL, NULL, TRUE,
66 flags == _P_DETACH ? DETACHED_PROCESS : 0,
67 env, NULL, &si, &pi))
69 MSVCRT__set_errno(GetLastError());
70 return -1;
73 switch(flags)
75 case _P_WAIT:
76 WaitForSingleObject(pi.hProcess,-1); /* wait forvever */
77 GetExitCodeProcess(pi.hProcess,&pi.dwProcessId);
78 CloseHandle(pi.hProcess);
79 CloseHandle(pi.hThread);
80 return (int)pi.dwProcessId;
81 case _P_DETACH:
82 CloseHandle(pi.hProcess);
83 pi.hProcess = 0;
84 /* fall through */
85 case _P_NOWAIT:
86 case _P_NOWAITO:
87 CloseHandle(pi.hThread);
88 return (int)pi.hProcess;
89 case _P_OVERLAY:
90 MSVCRT__exit(0);
92 return -1; /* can't reach here */
95 /* INTERNAL: Convert argv list to a single 'delim'-separated string, with an
96 * extra '\0' to terminate it
98 static char* msvcrt_argvtos(const char* const* arg, char delim)
100 const char* const* a;
101 long size;
102 char* p;
103 char* ret;
105 if (!arg && !delim)
107 /* Return NULL for an empty environment list */
108 return NULL;
111 /* get length */
112 a = arg;
113 size = 0;
114 while (*a)
116 size += strlen(*a) + 1;
117 a++;
120 ret = (char*)MSVCRT_malloc(size + 1);
121 if (!ret)
122 return NULL;
124 /* fill string */
125 a = arg;
126 p = ret;
127 while (*a)
129 int len = strlen(*a);
130 memcpy(ret+size,*a,len);
131 p += len;
132 *p++ = delim;
133 a++;
135 *p='\0';
136 return ret;
139 /* INTERNAL: Convert va_list to a single 'delim'-separated string, with an
140 * extra '\0' to terminate it
142 static char* msvcrt_valisttos(const char* arg0, va_list alist, char delim)
144 va_list alist2 = alist;
145 long size;
146 const char *arg;
147 char* p;
148 char *ret;
150 if (!arg0 && !delim)
152 /* Return NULL for an empty environment list */
153 return NULL;
156 /* get length */
157 arg = arg0;
158 size = 0;
159 do {
160 size += strlen(arg) + 1;
161 arg = va_arg(alist, char*);
162 } while (arg != NULL);
164 ret = (char*)MSVCRT_malloc(size + 1);
165 if (!ret)
166 return NULL;
168 /* fill string */
169 arg = arg0;
170 p = ret;
171 do {
172 int len = strlen(arg);
173 memcpy(p,arg,len);
174 p += len;
175 *p++ = delim;
176 arg = va_arg(alist2, char*);
177 } while (arg != NULL);
178 *p = '\0';
179 return ret;
182 /*********************************************************************
183 * _cwait (MSVCRT.@)
185 int _cwait(int *status, int pid, int action)
187 HANDLE hPid = (HANDLE)pid;
188 int doserrno;
190 action = action; /* Remove warning */
192 if (!WaitForSingleObject(hPid, -1)) /* wait forever */
194 if (status)
196 DWORD stat;
197 GetExitCodeProcess(hPid, &stat);
198 *status = (int)stat;
200 return (int)pid;
202 doserrno = GetLastError();
204 if (doserrno == ERROR_INVALID_HANDLE)
206 SET_THREAD_VAR(errno, MSVCRT_ECHILD);
207 SET_THREAD_VAR(doserrno,doserrno);
209 else
210 MSVCRT__set_errno(doserrno);
212 return status ? *status = -1 : -1;
215 /*********************************************************************
216 * _execl (MSVCRT.@)
218 * Like on Windows, this function does not handle arguments with spaces
219 * or double-quotes.
221 int _execl(const char* name, const char* arg0, ...)
223 va_list ap;
224 char * args;
225 int ret;
227 va_start(ap, arg0);
228 args = msvcrt_valisttos(arg0, ap, ' ');
229 va_end(ap);
231 ret = msvcrt_spawn(_P_OVERLAY, name, args, NULL);
232 MSVCRT_free(args);
234 return ret;
237 /*********************************************************************
238 * _execlp (MSVCRT.@)
240 * Like on Windows, this function does not handle arguments with spaces
241 * or double-quotes.
243 int _execlp(const char* name, const char* arg0, ...)
245 va_list ap;
246 char * args;
247 int ret;
248 char fullname[MAX_PATH];
250 _searchenv(name, "PATH", fullname);
252 va_start(ap, arg0);
253 args = msvcrt_valisttos(arg0, ap, ' ');
254 va_end(ap);
256 ret = msvcrt_spawn(_P_OVERLAY, fullname[0] ? fullname : name, args, NULL);
257 MSVCRT_free(args);
259 return ret;
262 /*********************************************************************
263 * _execv (MSVCRT.@)
265 * Like on Windows, this function does not handle arguments with spaces
266 * or double-quotes.
268 int _execv(const char* name, char* const* argv)
270 return _spawnve(_P_OVERLAY, name, (const char* const*) argv, NULL);
273 /*********************************************************************
274 * _execve (MSVCRT.@)
276 * Like on Windows, this function does not handle arguments with spaces
277 * or double-quotes.
279 int _execve(const char* name, char* const* argv, const char* const* envv)
281 return _spawnve(_P_OVERLAY, name, (const char* const*) argv, envv);
284 /*********************************************************************
285 * _execvpe (MSVCRT.@)
287 * Like on Windows, this function does not handle arguments with spaces
288 * or double-quotes.
290 int _execvpe(const char* name, char* const* argv, const char* const* envv)
292 char fullname[MAX_PATH];
294 _searchenv(name, "PATH", fullname);
295 return _spawnve(_P_OVERLAY, fullname[0] ? fullname : name,
296 (const char* const*) argv, envv);
299 /*********************************************************************
300 * _execvp (MSVCRT.@)
302 * Like on Windows, this function does not handle arguments with spaces
303 * or double-quotes.
305 int _execvp(const char* name, char* const* argv)
307 return _execvpe(name, argv, NULL);
310 /*********************************************************************
311 * _spawnl (MSVCRT.@)
313 * Like on Windows, this function does not handle arguments with spaces
314 * or double-quotes.
316 int _spawnl(int flags, const char* name, const char* arg0, ...)
318 va_list ap;
319 char * args;
320 int ret;
322 va_start(ap, arg0);
323 args = msvcrt_valisttos(arg0, ap, ' ');
324 va_end(ap);
326 ret = msvcrt_spawn(flags, name, args, NULL);
327 MSVCRT_free(args);
329 return ret;
332 /*********************************************************************
333 * _spawnlp (MSVCRT.@)
335 * Like on Windows, this function does not handle arguments with spaces
336 * or double-quotes.
338 int _spawnlp(int flags, const char* name, const char* arg0, ...)
340 va_list ap;
341 char * args;
342 int ret;
343 char fullname[MAX_PATH];
345 _searchenv(name, "PATH", fullname);
347 va_start(ap, arg0);
348 args = msvcrt_valisttos(arg0, ap, ' ');
349 va_end(ap);
351 ret = msvcrt_spawn(flags, fullname[0] ? fullname : name, args, NULL);
352 MSVCRT_free(args);
354 return ret;
357 /*********************************************************************
358 * _spawnve (MSVCRT.@)
360 * Like on Windows, this function does not handle arguments with spaces
361 * or double-quotes.
363 int _spawnve(int flags, const char* name, const char* const* argv,
364 const char* const* envv)
366 char * args = msvcrt_argvtos(argv,' ');
367 char * envs = msvcrt_argvtos(envv,0);
368 const char *fullname = name;
369 int ret = -1;
371 FIXME(":not translating name %s to locate program\n",fullname);
372 TRACE(":call (%s), params (%s), env (%s)\n",name,args,envs?"Custom":"Null");
374 if (args)
376 ret = msvcrt_spawn(flags, fullname, args, envs);
377 MSVCRT_free(args);
379 if (envs)
380 MSVCRT_free(envs);
382 return ret;
385 /*********************************************************************
386 * _spawnv (MSVCRT.@)
388 * Like on Windows, this function does not handle arguments with spaces
389 * or double-quotes.
391 int _spawnv(int flags, const char* name, const char* const* argv)
393 return _spawnve(flags, name, argv, NULL);
396 /*********************************************************************
397 * _spawnvpe (MSVCRT.@)
399 * Like on Windows, this function does not handle arguments with spaces
400 * or double-quotes.
402 int _spawnvpe(int flags, const char* name, const char* const* argv,
403 const char* const* envv)
405 char fullname[MAX_PATH];
406 _searchenv(name, "PATH", fullname);
407 return _spawnve(flags, fullname[0] ? fullname : name, argv, envv);
410 /*********************************************************************
411 * _spawnvp (MSVCRT.@)
413 * Like on Windows, this function does not handle arguments with spaces
414 * or double-quotes.
416 int _spawnvp(int flags, const char* name, const char* const* argv)
418 return _spawnvpe(flags, name, argv, NULL);
421 /*********************************************************************
422 * system (MSVCRT.@)
424 int MSVCRT_system(const char* cmd)
426 char* cmdcopy;
427 int res;
429 /* Make a writable copy for CreateProcess */
430 cmdcopy=_strdup(cmd);
431 /* FIXME: should probably launch cmd interpreter in COMSPEC */
432 res=msvcrt_spawn(_P_WAIT, NULL, cmdcopy, NULL);
433 MSVCRT_free(cmdcopy);
434 return res;
437 /*********************************************************************
438 * _loaddll (MSVCRT.@)
440 int _loaddll(const char* dllname)
442 return LoadLibraryA(dllname);
445 /*********************************************************************
446 * _unloaddll (MSVCRT.@)
448 int _unloaddll(int dll)
450 if (FreeLibrary((HANDLE)dll))
451 return 0;
452 else
454 int err = GetLastError();
455 MSVCRT__set_errno(err);
456 return err;