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
10 * -File handles need some special handling. Sometimes children get
11 * open file handles, sometimes not. The docs are confusing
12 * -No check for maximum path/argument/environment size is done
17 DEFAULT_DEBUG_CHANNEL(msvcrt
);
19 /* Process creation flags */
26 void __cdecl
MSVCRT__exit(int);
27 void __cdecl
MSVCRT__searchenv(const char* file
, const char* env
, char *buf
);
29 /* FIXME: Check file extenstions for app to run */
30 static const unsigned int EXE
= 'e' << 16 | 'x' << 8 | 'e';
31 static const unsigned int BAT
= 'b' << 16 | 'a' << 8 | 't';
32 static const unsigned int CMD
= 'c' << 16 | 'm' << 8 | 'd';
33 static const unsigned int COM
= 'c' << 16 | 'o' << 8 | 'm';
35 /* INTERNAL: Spawn a child process */
36 static int __MSVCRT__spawn(int flags
, const char *exe
, char * args
, char *env
)
39 PROCESS_INFORMATION pi
;
41 if (sizeof(HANDLE
) != sizeof(int))
42 WARN("This call is unsuitable for your architecture\n");
44 if ((unsigned)flags
> _P_DETACH
)
46 SET_THREAD_VAR(errno
,MSVCRT_EINVAL
);
50 FIXME(":must dup/kill streams for child process\n");
52 memset(&si
, 0, sizeof(si
));
55 if (!CreateProcessA(exe
, args
, NULL
, NULL
, TRUE
,
56 flags
== _P_DETACH
? DETACHED_PROCESS
: 0,
59 MSVCRT__set_errno(GetLastError());
66 WaitForSingleObject(pi
.hProcess
,-1); /* wait forvever */
67 GetExitCodeProcess(pi
.hProcess
,&pi
.dwProcessId
);
68 CloseHandle(pi
.hProcess
);
69 CloseHandle(pi
.hThread
);
70 return (int)pi
.dwProcessId
;
72 CloseHandle(pi
.hProcess
);
77 CloseHandle(pi
.hThread
);
78 return (int)pi
.hProcess
;
82 return -1; /* can't reach here */
85 /* INTERNAL: Convert argv list to a single 'delim'-seperated string */
86 static char * __MSVCRT__argvtos(const char * *arg
, char delim
)
88 const char **search
= arg
;
98 size
+= strlen(*search
) + 1;
102 if (!(ret
= (char *)MSVCRT_calloc(size
+ 1, 1)))
110 int strsize
= strlen(*search
);
111 memcpy(ret
+size
,*search
,strsize
);
112 ret
[size
+strsize
] = delim
;
119 /*********************************************************************
122 int __cdecl
MSVCRT__cwait(int *status
, int pid
, int action
)
124 HANDLE hPid
= (HANDLE
)pid
;
127 action
= action
; /* Remove warning */
129 if (!WaitForSingleObject(hPid
, -1)) /* wait forever */
134 GetExitCodeProcess(hPid
, &stat
);
139 doserrno
= GetLastError();
141 if (doserrno
== ERROR_INVALID_HANDLE
)
143 SET_THREAD_VAR(errno
, MSVCRT_ECHILD
);
144 SET_THREAD_VAR(doserrno
,doserrno
);
147 MSVCRT__set_errno(doserrno
);
149 return status
? *status
= -1 : -1;
152 /*********************************************************************
153 * _spawnve (MSVCRT.@)
155 int __cdecl
MSVCRT__spawnve(int flags
, const char *name
, const char **argv
,
158 char * args
= __MSVCRT__argvtos(argv
,' ');
159 char * envs
= __MSVCRT__argvtos(envv
,0);
160 const char *fullname
= name
;
163 FIXME(":not translating name %s to locate program\n",fullname
);
164 TRACE(":call (%s), params (%s), env (%s)\n",name
,args
,envs
?"Custom":"Null");
168 ret
= __MSVCRT__spawn(flags
, fullname
, args
, envs
);
177 /*********************************************************************
180 int __cdecl
MSVCRT__spawnv(int flags
, const char *name
, const char **argv
)
182 return MSVCRT__spawnve(flags
, name
, argv
, NULL
);
185 /*********************************************************************
186 * _spawnvpe (MSVCRT.@)
188 int __cdecl
MSVCRT__spawnvpe(int flags
, const char *name
, const char **argv
,
191 char fullname
[MAX_PATH
];
192 MSVCRT__searchenv(name
, "PATH", fullname
);
193 return MSVCRT__spawnve(flags
, fullname
[0] ? fullname
: name
, argv
, envv
);
196 /*********************************************************************
197 * _spawnvp (MSVCRT.@)
199 int __cdecl
MSVCRT__spawnvp(int flags
, const char *name
, const char **argv
)
201 return MSVCRT__spawnvpe(flags
, name
, argv
, NULL
);
204 /*********************************************************************
207 int __cdecl
MSVCRT_system(const char *cmd
)
209 /* FIXME: should probably launch cmd interpreter in COMSPEC */
210 return __MSVCRT__spawn(_P_WAIT
, cmd
, NULL
, NULL
);
213 /*********************************************************************
214 * _loaddll (MSVCRT.@)
216 int __cdecl
MSVCRT__loaddll(const char *dllname
)
218 return LoadLibraryA(dllname
);
221 /*********************************************************************
222 * _unloaddll (MSVCRT.@)
224 int __cdecl
MSVCRT__unloaddll(int dll
)
226 if (FreeLibrary((HANDLE
)dll
))
230 int err
= GetLastError();
231 MSVCRT__set_errno(err
);