bug-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug when redirecting mingw32-make output (w32/sub_proc/sub_proc.c)


From: Roland Puntaier
Subject: bug when redirecting mingw32-make output (w32/sub_proc/sub_proc.c)
Date: Fri, 2 Jun 2006 17:36:00 +0200


"process_easy: DuplicateHandle(In) failed" is issued, when redirecting the mingw32-make output from a parent process.

GetStdHandle returns 0, which is not an error, but also no handle to be duplicated.

Example parent process code leading to error (in C#):

        static StringBuilder myOutput=null;

        private static void MyOutputDataHandler(object sendingProcess,
            DataReceivedEventArgs line)
        {
            if (!String.IsNullOrEmpty(line.Data))
            {
                myOutput.Append(Environment.NewLine + "out:   " + line.Data);
            }
        }

        private static void MyErrorDataHandler(object sendingProcess,
            DataReceivedEventArgs line)
        {
            if (!String.IsNullOrEmpty(line.Data))
            {
                myOutput.Append(Environment.NewLine + "err:   " + line.Data);
            }
        }


        private void button1_Click(object sender, EventArgs e)
        {
            Process myprocess = new Process();
            myprocess.StartInfo.FileName = "mingw32-make.exe";
            myprocess.StartInfo.Arguments = "-f C:/test/main.mak";

            myprocess.StartInfo.UseShellExecute = false;

            myprocess.StartInfo.RedirectStandardOutput = true;
            myprocess.OutputDataReceived += new DataReceivedEventHandler(MyOutputDataHandler);
            myprocess.StartInfo.RedirectStandardError = true;
            myprocess.ErrorDataReceived += new DataReceivedEventHandler(MyErrorDataHandler);

            myOutput = new StringBuilder();
            myprocess.Start();

            myprocess.BeginOutputReadLine();
            myprocess.BeginErrorReadLine();

            myprocess.WaitForExit();

            if (myOutput.Length > 0)
            {
                System.Windows.Forms.MessageBox.Show(myOutput.ToString(), "Hello");
            }

            myprocess.Close();
        }



Patch that helped:
HANDLE
process_easy(
        char **argv,
        char **envp)
{
  HANDLE hIn=0;
  HANDLE hOut=0;
  HANDLE hErr=0;
  HANDLE hProcess;

  HANDLE processPseudo;
  HANDLE tmpIn,tmpOut,tmpErr;

  processPseudo=GetCurrentProcess();
  tmpIn=GetStdHandle(STD_INPUT_HANDLE);
  tmpOut=GetStdHandle(STD_OUTPUT_HANDLE);
  tmpErr=GetStdHandle(STD_ERROR_HANDLE);
  fprintf(stdout, "Handles: %d,%d,%d\n",tmpIn,tmpOut,tmpErr);

  if (tmpIn && DuplicateHandle(processPseudo,
                      tmpIn,
                      processPseudo,
                      &hIn,
                      0,
                      TRUE,
                      DUPLICATE_SAME_ACCESS) == FALSE) {
    fprintf(stderr,
            "process_easy: DuplicateHandle(In) failed (e=%d)\n",
            GetLastError());
    return INVALID_HANDLE_VALUE;
  }
  if (tmpOut && DuplicateHandle(processPseudo,
                      tmpOut,
                      processPseudo,
                      &hOut,
                      0,
                      TRUE,
                      DUPLICATE_SAME_ACCESS) == FALSE) {
    fprintf(stderr,
           "process_easy: DuplicateHandle(Out) failed (e=%d)\n",
           GetLastError());
    return INVALID_HANDLE_VALUE;
  }
  if (tmpErr && DuplicateHandle(processPseudo,
                      tmpErr,
                      processPseudo,
                      &hErr,
                      0,
                      TRUE,
                      DUPLICATE_SAME_ACCESS) == FALSE) {
    fprintf(stderr,
            "process_easy: DuplicateHandle(Err) failed (e=%d)\n",
            GetLastError());
    return INVALID_HANDLE_VALUE;
  }

  hProcess = process_init_fd(hIn, hOut, hErr);

  if (process_begin(hProcess, argv, envp, argv[0], NULL)) {
    fake_exits_pending++;
    ((sub_process*) hProcess)->exit_code = process_last_err(hProcess);

    /* close up unused handles */
    CloseHandle(hIn);
    CloseHandle(hOut);
    CloseHandle(hErr);
  }

  process_register(hProcess);

  return hProcess;
}


reply via email to

[Prev in Thread] Current Thread [Next in Thread]