示例#1
0
/* 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);
    }
}