diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index 54e307cc8444f64aa04baf3217b7cdc275d30db5..2c55540b355abdf41017048acfa554e71101a025 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -1,3 +1,37 @@
+2004-08-12  David Daney  <ddaney@avtrex.com>
+
+	* testsuite/libjava.lang/Process_1.java: New test.
+	* testsuite/libjava.lang/Process_2.java: New test.
+	* testsuite/libjava.lang/Process_3.java: New test.
+	* testsuite/libjava.lang/Process_4.java: New test.
+	* testsuite/libjava.lang/Process_5.java: New test.
+	* testsuite/libjava.lang/Process_6.java: New test.
+	* testsuite/libjava.lang/Process_1.out: Expected result.
+	* testsuite/libjava.lang/Process_2.out: Expected result.
+	* testsuite/libjava.lang/Process_3.out: Expected result.
+	* testsuite/libjava.lang/Process_4.out: Expected result.
+	* testsuite/libjava.lang/Process_5.out: Expected result.
+	* testsuite/libjava.lang/Process_6.out: Expected result.
+
+2004-08-12  David Daney  <ddaney@avtrex.com>
+
+	PR libgcj/11801
+	* java/lang/PosixProcess.java: Rewrote.
+	* java/lang/natPosixProcess.cc: Rewrote.
+	* java/lang/Runtime.java (execInternal): Declare throws IOException.
+	* gcj/javaprims.h (ConcreteProcess$ProcessManager): Declare.
+	* posix-threads.cc (block_sigchld) New function.
+	(_Jv_ThreadRegister) Use it.
+	(_Jv_ThreadStart) Use it.
+	* configure.in (PLATFORM_INNER_NAT_HDRS): New AC_SUBST() used in...
+	* Makefile.am: ... to specify extra native headers.
+	* configure: Regenerated.
+	* include/config.h: Regenerated.
+	* Makefile.in: Regenerated.
+	* gcj/Makefile.in: Regenerated.
+	* include/Makefile.in: Regenerated.
+	* testsuite/Makefile.in: Regenerated.
+
 2004-08-12  Diego Novillo  <dnovillo@redhat.com>
 
 	PR tree-optimization/16867
diff --git a/libjava/testsuite/libjava.lang/Process_1.java b/libjava/testsuite/libjava.lang/Process_1.java
new file mode 100644
index 0000000000000000000000000000000000000000..adc6354660d1c0a25844a1591ef0c244d24c07cc
--- /dev/null
+++ b/libjava/testsuite/libjava.lang/Process_1.java
@@ -0,0 +1,41 @@
+// Create a process and read from its standard output.
+//
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+
+public class Process_1
+{
+  public static void main(String[] args)
+  {
+    try
+      {
+	Runtime r = Runtime.getRuntime();
+	String s = "Hello World";
+	String[] a = { "echo", s };
+	Process p = r.exec(a);
+	InputStream is = p.getInputStream();
+	InputStreamReader isr = new InputStreamReader(is);
+	BufferedReader br = new BufferedReader(isr);
+	String result = br.readLine();
+	if (! s.equals(result))
+	  {
+	    System.out.println("bad 1");
+	    return;
+	  }
+	result = br.readLine();
+	if (result != null)
+	  {
+	    System.out.println("bad 2");
+	    return;
+	  }
+	int c = p.waitFor();
+	System.out.println(c == 0 ? "ok" : "bad 3");
+      }
+    catch (Exception ex)
+      {
+	System.out.println(ex.toString());
+      }
+  }
+}
diff --git a/libjava/testsuite/libjava.lang/Process_1.out b/libjava/testsuite/libjava.lang/Process_1.out
new file mode 100644
index 0000000000000000000000000000000000000000..9766475a4185a151dc9d56d614ffb9aaea3bfd42
--- /dev/null
+++ b/libjava/testsuite/libjava.lang/Process_1.out
@@ -0,0 +1 @@
+ok
diff --git a/libjava/testsuite/libjava.lang/Process_2.java b/libjava/testsuite/libjava.lang/Process_2.java
new file mode 100644
index 0000000000000000000000000000000000000000..d90e653a40ed0df8a6195f7ad2c5a77e8df33ac7
--- /dev/null
+++ b/libjava/testsuite/libjava.lang/Process_2.java
@@ -0,0 +1,40 @@
+// Create a process and read from its standard error.
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+
+public class Process_2
+{
+  public static void main(String[] args)
+  {
+    try
+      {
+	Runtime r = Runtime.getRuntime();
+	String s = "Hello World";
+	String[] a = { "sh", "-c", "echo " + s + " >&2" };
+	Process p = r.exec(a);
+	InputStream is = p.getErrorStream();
+	InputStreamReader isr = new InputStreamReader(is);
+	BufferedReader br = new BufferedReader(isr);
+	String result = br.readLine();
+	if (! s.equals(result))
+	  {
+	    System.out.println("bad 1");
+	    return;
+	  }
+	result = br.readLine();
+	if (result != null)
+	  {
+	    System.out.println("bad 2");
+	    return;
+	  }
+	int c = p.waitFor();
+	System.out.println(c == 0 ? "ok" : "bad 3");
+      }
+    catch (Exception ex)
+      {
+	System.out.println(ex.toString());
+      }
+  }
+}
diff --git a/libjava/testsuite/libjava.lang/Process_2.out b/libjava/testsuite/libjava.lang/Process_2.out
new file mode 100644
index 0000000000000000000000000000000000000000..9766475a4185a151dc9d56d614ffb9aaea3bfd42
--- /dev/null
+++ b/libjava/testsuite/libjava.lang/Process_2.out
@@ -0,0 +1 @@
+ok
diff --git a/libjava/testsuite/libjava.lang/Process_3.java b/libjava/testsuite/libjava.lang/Process_3.java
new file mode 100644
index 0000000000000000000000000000000000000000..669e1dc7e293a2b3c1c9cf5831559997dafee762
--- /dev/null
+++ b/libjava/testsuite/libjava.lang/Process_3.java
@@ -0,0 +1,72 @@
+// Create a process and pipe data through it.  waitFor() the process
+// in a different thread than the one that created it.
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintStream;
+
+
+public class Process_3 implements Runnable
+{
+  Process p;
+
+  public void run()
+  {
+    try
+      {
+	Runtime r = Runtime.getRuntime();
+	String[] a = { "sed", "-e", "s/Hello/Goodbye/" };
+	synchronized (this)
+	  {
+	    p = r.exec(a);
+	    this.notifyAll();
+	  }
+	OutputStream os = p.getOutputStream();
+	PrintStream ps = new PrintStream(os);
+	ps.println("Hello World");
+	ps.close();
+      }
+    catch (Exception ex)
+      {
+	System.out.println(ex.toString());
+      }
+  }
+
+  public static void main(String[] args)
+  {
+    try
+      {
+	Process_3 p3 = new Process_3();
+	Thread t = new Thread(p3);
+	t.start();
+	synchronized (p3)
+	  {
+	    while (p3.p == null)
+	      p3.wait();
+	  }
+
+	InputStream is = p3.p.getInputStream();
+	InputStreamReader isr = new InputStreamReader(is);
+	BufferedReader br = new BufferedReader(isr);
+	String result = br.readLine();
+	if (! "Goodbye World".equals(result))
+	  {
+	    System.out.println("bad 1");
+	    return;
+	  }
+	result = br.readLine();
+	if (result != null)
+	  {
+	    System.out.println("bad 2");
+	    return;
+	  }
+	int c = p3.p.waitFor();
+	System.out.println(c == 0 ? "ok" : "bad 3");
+      }
+    catch (Exception ex)
+      {
+	System.out.println(ex.toString());
+      }
+  }
+}
diff --git a/libjava/testsuite/libjava.lang/Process_3.out b/libjava/testsuite/libjava.lang/Process_3.out
new file mode 100644
index 0000000000000000000000000000000000000000..9766475a4185a151dc9d56d614ffb9aaea3bfd42
--- /dev/null
+++ b/libjava/testsuite/libjava.lang/Process_3.out
@@ -0,0 +1 @@
+ok
diff --git a/libjava/testsuite/libjava.lang/Process_4.java b/libjava/testsuite/libjava.lang/Process_4.java
new file mode 100644
index 0000000000000000000000000000000000000000..241dfde816d40610edabef30a0fc7b72f4074d42
--- /dev/null
+++ b/libjava/testsuite/libjava.lang/Process_4.java
@@ -0,0 +1,19 @@
+// Create a process and verify failure exit code.
+public class Process_4
+{
+  public static void main(String[] args)
+  {
+    try
+      {
+	Runtime r = Runtime.getRuntime();
+	String[] a = { "false" };
+	Process p = r.exec(a);
+	int c = p.waitFor();
+	System.out.println(c == 1 ? "ok" : "bad");
+      }
+    catch (Exception ex)
+      {
+	System.out.println(ex.toString());
+      }
+  }
+}
diff --git a/libjava/testsuite/libjava.lang/Process_4.out b/libjava/testsuite/libjava.lang/Process_4.out
new file mode 100644
index 0000000000000000000000000000000000000000..9766475a4185a151dc9d56d614ffb9aaea3bfd42
--- /dev/null
+++ b/libjava/testsuite/libjava.lang/Process_4.out
@@ -0,0 +1 @@
+ok
diff --git a/libjava/testsuite/libjava.lang/Process_5.java b/libjava/testsuite/libjava.lang/Process_5.java
new file mode 100644
index 0000000000000000000000000000000000000000..61fd5b7409f9049a731bbe124f894c9baf93b301
--- /dev/null
+++ b/libjava/testsuite/libjava.lang/Process_5.java
@@ -0,0 +1,43 @@
+// Create a long running process and verify that the exitValue is not
+// immediately available.  Then destroy() it and verify that it
+// terminates quickly with a non-zero exitValue.
+public class Process_5
+{
+  public static void main(String[] args)
+  {
+    try
+      {
+	int c;
+	long startTime = System.currentTimeMillis();
+	Runtime r = Runtime.getRuntime();
+	String[] a = { "sleep", "120" };
+	Process p = r.exec(a);
+
+	try
+	  {
+	    c = p.exitValue();
+	    System.out.println("bad 1");
+	    return;
+	  }
+	catch (IllegalThreadStateException itse)
+	  {
+	    // Ignore as this is good here.
+	  }
+
+	p.destroy();
+
+	c = p.waitFor();
+
+	long endTime = System.currentTimeMillis();
+
+	if (endTime - startTime > 110000L)
+	  System.out.println("bad 2");
+
+	System.out.println(c != 0 ? "ok" : "bad 3");
+      }
+    catch (Exception ex)
+      {
+	System.out.println(ex.toString());
+      }
+  }
+}
diff --git a/libjava/testsuite/libjava.lang/Process_5.out b/libjava/testsuite/libjava.lang/Process_5.out
new file mode 100644
index 0000000000000000000000000000000000000000..9766475a4185a151dc9d56d614ffb9aaea3bfd42
--- /dev/null
+++ b/libjava/testsuite/libjava.lang/Process_5.out
@@ -0,0 +1 @@
+ok
diff --git a/libjava/testsuite/libjava.lang/Process_6.java b/libjava/testsuite/libjava.lang/Process_6.java
new file mode 100644
index 0000000000000000000000000000000000000000..3bf015f760b3ce9957a2c67e5ce6bbd5f907477c
--- /dev/null
+++ b/libjava/testsuite/libjava.lang/Process_6.java
@@ -0,0 +1,31 @@
+// Create a running process for a non existent executable.
+// Verify that IOException is thrown.
+import java.io.IOException;
+
+
+public class Process_6
+{
+  public static void main(String[] args)
+  {
+    try
+      {
+	int c;
+	Runtime r = Runtime.getRuntime();
+	String[] a = { "blablabla_failure" };
+
+	try
+	  {
+	    Process p = r.exec(a);
+	    System.out.println("bad");
+	  }
+	catch (IOException ioe)
+	  {
+	    System.out.println("ok");
+	  }
+      }
+    catch (Exception ex)
+      {
+	System.out.println(ex.toString());
+      }
+  }
+}
diff --git a/libjava/testsuite/libjava.lang/Process_6.out b/libjava/testsuite/libjava.lang/Process_6.out
new file mode 100644
index 0000000000000000000000000000000000000000..9766475a4185a151dc9d56d614ffb9aaea3bfd42
--- /dev/null
+++ b/libjava/testsuite/libjava.lang/Process_6.out
@@ -0,0 +1 @@
+ok