+++ /dev/null
-/* $Id: spawnve.c,v 1.5 2002/09/08 10:22:53 chorns Exp $ */
-/* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
-/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
-/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
-
-#include <windows.h>
-
-#include <msvcrt/stdio.h>
-#include <msvcrt/stdlib.h>
-#include <msvcrt/string.h>
-#include <msvcrt/errno.h>
-//#include <msvcrt/limits.h>
-#include <msvcrt/process.h>
-#include <msvcrt/ctype.h>
-#include <msvcrt/io.h>
-#include <msvcrt/fcntl.h>
-
-#define NDEBUG
-#include <msvcrt/msvcrtdbg.h>
-
-
-#ifndef F_OK
- #define F_OK 0x01
-#endif
-#ifndef R_OK
- #define R_OK 0x02
-#endif
-#ifndef W_OK
- #define W_OK 0x04
-#endif
-#ifndef X_OK
- #define X_OK 0x08
-#endif
-#ifndef D_OK
- #define D_OK 0x10
-#endif
-
-// information about crtdll file handles is not passed to child
-int _fileinfo_dll = 0;
-
-extern int maxfno;
-
-static int
-direct_exec_tail(int mode, const char *program,
- const char *args, const char * envp)
-{
-
- STARTUPINFO StartupInfo;
- PROCESS_INFORMATION ProcessInformation;
- char* fmode;
- HANDLE* hFile;
- int i, last;
- BOOL bResult;
-
- DPRINT("direct_exec_tail()\n");
-
- memset (&StartupInfo, 0, sizeof(STARTUPINFO));
- StartupInfo.cb = sizeof(STARTUPINFO);
-
- for (last = i = 0; i < maxfno; i++)
- {
- if ((void*)-1 != _get_osfhandle(i))
- {
- last = i + 1;
- }
- }
-
- if (last)
- {
- StartupInfo.cbReserved2 = sizeof(ULONG) + last * (sizeof(char) + sizeof(HANDLE));
- StartupInfo.lpReserved2 = malloc(StartupInfo.cbReserved2);
- if (StartupInfo.lpReserved2 == NULL)
- {
- return -1;
- }
-
- *(DWORD*)StartupInfo.lpReserved2 = last;
- fmode = (char*)(StartupInfo.lpReserved2 + sizeof(ULONG));
- hFile = (HANDLE*)(StartupInfo.lpReserved2 + sizeof(ULONG) + last * sizeof(char));
- for (i = 0; i < last; i++)
- {
- int mode = __fileno_getmode(i);
- HANDLE h = _get_osfhandle(i);
- /* FIXME: The test of console handles (((ULONG)Handle) & 0x10000003) == 0x3)
- * is possible wrong
- */
- if ((((ULONG)h) & 0x10000003) == 0x3 || mode & _O_NOINHERIT)
- {
- *hFile = INVALID_HANDLE_VALUE;
- }
- else
- {
- *hFile = h;
- *fmode = (_O_ACCMODE & mode) | (((_O_TEXT | _O_BINARY) & mode) >> 8);
- }
- fmode++;
- hFile++;
- }
- }
-
- bResult = CreateProcessA((char *)program,
- (char *)args,
- NULL,
- NULL,
- TRUE,
- mode == _P_DETACH ? DETACHED_PROCESS : 0,
- (LPVOID)envp,
- NULL,
- &StartupInfo,
- &ProcessInformation);
- Sleep(100);
- if (StartupInfo.lpReserved2)
- {
- free(StartupInfo.lpReserved2);
- }
-
- if (!bResult)
- {
- DPRINT("%x\n", GetLastError());
- __set_errno( GetLastError() );
- return -1;
- }
- CloseHandle(ProcessInformation.hThread);
- return (int)ProcessInformation.hProcess;
-}
-
-static int vdm_exec(int mode, const char *program, char **argv, char *envp)
-{
- static char args[1024];
- int i = 0;
- args[0] = 0;
-
- strcpy(args,"vdm.exe ");
- while(argv[i] != NULL ) {
- strcat(args,argv[i]);
- strcat(args," ");
- i++;
- }
-
- return direct_exec_tail(mode,program,args,envp);
-}
-
-static int go32_exec(int mode, const char *program, char **argv, char **envp)
-{
- char * penvblock, * ptr;
- char * args;
- int i, len, result;
-
- for (i = 0, len = 0; envp[i]; i++) {
- len += strlen(envp[i]) + 1;
- }
- penvblock = ptr = (char*)malloc(len + 1);
- if (penvblock == NULL)
- return -1;
-
- for(i = 0, *ptr = 0; envp[i]; i++) {
- strcpy(ptr, envp[i]);
- ptr += strlen(envp[i]) + 1;
- }
- *ptr = 0;
-
- for(i = 0, len = 0; argv[i]; i++) {
- len += strlen(argv[i]) + 1;
- }
-
- args = (char*) malloc(len + 1);
- if (args == NULL)
- {
- free(penvblock);
- return -1;
- }
-
- for(i = 0, *args = 0; argv[i]; i++) {
- strcat(args,argv[i]);
- if (argv[i+1] != NULL) {
- strcat(args," ");
- }
- }
-
- DPRINT("'%s'\n", args);
- result = direct_exec_tail(mode, program,args,(const char*)penvblock);
- free(args);
- free(penvblock);
- return result;
-}
-
-int
-command_exec(int mode, const char *program, char **argv, char *envp)
-{
- static char args[1024];
- int i = 0;
-
-
-
- args[0] = 0;
-
- strcpy(args,"cmd.exe /c ");
- while(argv[i] != NULL ) {
- strcat(args,argv[i]);
- strcat(args," ");
- i++;
- }
-
- return direct_exec_tail(mode,program,args,envp);
-
-}
-
-static int script_exec(int mode, const char *program, char **argv, char **envp)
-{
- return 0;
-}
-
-
-/* Note: the following list is not supposed to mention *every*
- possible extension of an executable file. It only mentions
- those extensions that can be *omitted* when you invoke the
- executable from one of the shells used on MSDOS. */
-static struct {
- const char *extension;
- int (*interp)(int , const char*, char **, char **);
-} interpreters[] = {
- { ".com", vdm_exec },
- { ".exe", go32_exec },
- { ".dll", go32_exec },
- { ".cmd", command_exec },
- { ".bat", command_exec },
- { ".btm", command_exec },
- { ".sh", script_exec }, /* for compatibility with ms_sh */
- { ".ksh", script_exec },
- { ".pl", script_exec }, /* Perl */
- { ".sed", script_exec },
- { "", go32_exec },
- { 0, script_exec }, /* every extension not mentioned above calls it */
- { 0, 0 },
-};
-
-/* This is the index into the above array of the interpreter
- which is called when the program filename has no extension. */
-#define INTERP_NO_EXT (sizeof(interpreters)/sizeof(interpreters[0]) - 3)
-
-/*-------------------------------------------------*/
-
-
-
-
-int _spawnve(int mode, const char *path, char *const argv[], char *const envp[])
-{
- /* This is the one that does the work! */
- union { char *const *x; char **p; } u;
- int i = -1;
- char **argvp;
- char **envpp;
- char rpath[FILENAME_MAX], *rp, *rd=0;
- int e = errno;
- int is_dir = 0;
- int found = 0;
- DWORD ExitCode;
-
- DPRINT("_spawnve(mode %x, '%s')\n", mode, path);
-
- if (path == 0 || argv[0] == 0)
- {
- errno = EINVAL;
- DPRINT("??\n");
- return -1;
- }
- if (strlen(path) > FILENAME_MAX - 1)
- {
- errno = ENAMETOOLONG;
- DPRINT("??\n");
- return -1;
- }
-
- u.x = argv; argvp = u.p;
- u.x = envp; envpp = u.p;
-
- fflush(stdout); /* just in case */
- for (rp=rpath; *path; *rp++ = *path++)
- {
- if (*path == '.')
- rd = rp;
- if (*path == '\\' || *path == '/')
- rd = 0;
- }
- *rp = 0;
-
- /* If LFN is supported on the volume where rpath resides, we
- might have something like foo.bar.exe or even foo.exe.com.
- If so, look for RPATH.ext before even trying RPATH itself. */
- if (!rd)
- {
- for (i=0; interpreters[i].extension; i++)
- {
- strcpy(rp, interpreters[i].extension);
- if (_access(rpath, F_OK) == 0 && !(is_dir = (_access(rpath, D_OK) == 0)))
- {
- found = 1;
- break;
- }
- }
- }
-
- if (!found)
- {
- const char *rpath_ext;
-
- if (rd)
- {
- i = 0;
- rpath_ext = rd;
- }
- else
- {
- i = INTERP_NO_EXT;
- rpath_ext = "";
- }
- for ( ; interpreters[i].extension; i++)
- if (_stricmp(rpath_ext, interpreters[i].extension) == 0
- && _access(rpath, F_OK) == 0
- && !(is_dir = (_access(rpath, D_OK) == 0)))
- {
- found = 1;
- break;
- }
- }
- if (!found)
- {
- DPRINT("??\n");
- errno = is_dir ? EISDIR : ENOENT;
- return -1;
- }
- errno = e;
- i = interpreters[i].interp(mode, rpath, argvp, envpp);
- if (i < 0)
- {
- return -1;
- }
- if (mode == P_OVERLAY)
- {
- CloseHandle((HANDLE)i);
- exit(i);
- }
- if (mode == P_WAIT)
- {
- WaitForSingleObject((HANDLE)i, INFINITE);
- GetExitCodeProcess((HANDLE)i, &ExitCode);
- CloseHandle((HANDLE)i);
- i = (int)ExitCode;
- }
- return i;
-}
-
-
-
-
-const char * find_exec(char * path,char *rpath)
-{
- char *rp, *rd=0;
- int i;
- int is_dir = 0;
- int found = 0;
- if (path == 0 )
- return 0;
- if (strlen(path) > FILENAME_MAX - 1)
- return path;
-
- /* copy path in rpath */
- for (rd=path,rp=rpath; *rd; *rp++ = *rd++)
- ;
- *rp = 0;
- /* try first with the name as is */
- for (i=0; interpreters[i].extension; i++)
- {
- strcpy(rp, interpreters[i].extension);
- if (_access(rpath, F_OK) == 0 && !(is_dir = (_access(rpath, D_OK) == 0)))
- {
- found = 1;
- break;
- }
- }
-
- if (!found)
- {
- /* search in the PATH */
- char winpath[MAX_PATH];
- if( GetEnvironmentVariableA("PATH",winpath,MAX_PATH))
- {
- char *ep=winpath;
- while( *ep)
- {
- if(*ep == ';') ep++;
- rp=rpath;
- for ( ; *ep && (*ep != ';') ; *rp++ = *ep++)
- ;
- *rp++='/';
- for (rd=path ; *rd ; *rp++ = *rd++)
- ;
-
- for (i=0; interpreters[i].extension; i++)
- {
- strcpy(rp, interpreters[i].extension);
- if (_access(rpath, F_OK) == 0 && !(is_dir = (_access(rpath, D_OK) == 0)))
- {
- found = 1;
- break;
- }
- }
- if (found) break;
- }
- }
- }
- if (!found)
- return path;
-
- return rpath;
-}
-
-int _spawnvpe(int nMode, const char* szPath, char* const* szaArgv, char* const* szaEnv)
-{
- char rpath[FILENAME_MAX];
-
- return _spawnve(nMode, find_exec((char*)szPath,rpath), szaArgv, szaEnv);
-
-}