/* Start a new process. PROGRAM is a path to the program to execute. ARGS is a standard NULL-terminated array of arguments, to be passed to the inferior as ``argv''. Returns the new PID on success, -1 on failure. Registers the new process with the process list. */ static int win32_create_inferior (char *program, char **program_args) { #ifndef USE_WIN32API char real_path[PATH_MAX]; char *orig_path, *new_path, *path_ptr; #endif BOOL ret; DWORD flags; char *args; int argslen; int argc; PROCESS_INFORMATION pi; DWORD err; /* win32_wait needs to know we're not attaching. */ attaching = 0; if (!program) error ("No executable specified, specify executable to debug.\n"); flags = DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS; #ifndef USE_WIN32API orig_path = NULL; path_ptr = getenv ("PATH"); if (path_ptr) { int size = cygwin_conv_path_list (CCP_POSIX_TO_WIN_A, path_ptr, NULL, 0); orig_path = alloca (strlen (path_ptr) + 1); new_path = alloca (size); strcpy (orig_path, path_ptr); cygwin_conv_path_list (CCP_POSIX_TO_WIN_A, path_ptr, new_path, size); setenv ("PATH", new_path, 1); } cygwin_conv_path (CCP_POSIX_TO_WIN_A, program, real_path, PATH_MAX); program = real_path; #endif argslen = 1; for (argc = 1; program_args[argc]; argc++) argslen += strlen (program_args[argc]) + 1; args = alloca (argslen); args[0] = '\0'; for (argc = 1; program_args[argc]; argc++) { /* FIXME: Can we do better about quoting? How does Cygwin handle this? */ strcat (args, " "); strcat (args, program_args[argc]); } OUTMSG2 (("Command line is \"%s\"\n", args)); #ifdef CREATE_NEW_PROCESS_GROUP flags |= CREATE_NEW_PROCESS_GROUP; #endif ret = create_process (program, args, flags, &pi); err = GetLastError (); if (!ret && err == ERROR_FILE_NOT_FOUND) { char *exename = alloca (strlen (program) + 5); strcat (strcpy (exename, program), ".exe"); ret = create_process (exename, args, flags, &pi); err = GetLastError (); } #ifndef USE_WIN32API if (orig_path) setenv ("PATH", orig_path, 1); #endif if (!ret) { error ("Error creating process \"%s%s\", (error %d): %s\n", program, args, (int) err, strwinerror (err)); } else { OUTMSG2 (("Process created: %s\n", (char *) args)); } #ifndef _WIN32_WCE /* On Windows CE this handle can't be closed. The OS reuses it in the debug events, while the 9x/NT versions of Windows probably use a DuplicateHandle'd one. */ CloseHandle (pi.hThread); #endif do_initial_child_stuff (pi.hProcess, pi.dwProcessId, 0); return current_process_id; }
static void TclCygwinPutenv( char *str) { char *name, *value; /* * Get the name and value, so that we can change the environment variable * for Windows. */ name = alloca(strlen(str) + 1); strcpy(name, str); for (value=name ; *value!='=' && *value!='\0' ; ++value) { /* Empty body */ } if (*value == '\0') { /* Can't happen. */ return; } *value = '\0'; ++value; if (*value == '\0') { value = NULL; } /* * Set the cygwin environment variable. */ #undef putenv if (value == NULL) { unsetenv(name); } else { putenv(str); } /* * Before changing the environment variable in Windows, if this is PATH, * we need to convert the value back to a Windows style path. * * FIXME: The calling program may know it is running under windows, and * may have set the path to a Windows path, or, worse, appended or * prepended a Windows path to PATH. */ if (strcmp(name, "PATH") != 0) { /* * If this is Path, eliminate any PATH variable, to prevent any * confusion. */ if (strcmp(name, "Path") == 0) { SetEnvironmentVariableA("PATH", NULL); unsetenv("PATH"); } SetEnvironmentVariableA(name, value); } else { char *buf; /* * Eliminate any Path variable, to prevent any confusion. */ SetEnvironmentVariableA("Path", NULL); unsetenv("Path"); if (value == NULL) { buf = NULL; } else { int size; size = cygwin_conv_path_list(0, value, NULL, 0); buf = alloca(size + 1); cygwin_conv_path_list(0, value, buf, size); } SetEnvironmentVariableA(name, buf); } }