We now properly forward the errno value from the child when execvp()
fails, which the parent then uses to for the errno message as well as
including the failed command's name in the message.
The first bug affected POSIX systems: if the app never called
Process.waitFor, we'd never call waitpid on the child and thus leak a
zombie process. This patch ensures that we always call waitpid by
spawning a thread to handle it.
The second bug affected Windows systems: we weren't closing the
child's ends of the stdin, stdout, and stderr pipes after process
creation, which lead to us blocking forever while reading from the
child's stdout or stderr.
Due to a silly cut-and-paste error, we were incorrectly passing the
stdout and stderr file descriptors back from native code to Java,
which prevented reading the output of the child process.
Whereas the GNU Classpath port used the strategy of patching Classpath
with core classes from Avian so as to minimize changes to the VM, this
port uses the opposite strategy: abstract and isolate
classpath-specific features in the VM similar to how we abstract away
platform-specific features in system.h. This allows us to use an
unmodified copy of OpenJDK's class library, including its core classes
and augmented by a few VM-specific classes in the "avian" package.
The latter is cheaper (avoids a state transition and possible memory
allocation) when we just want to know if an exception is thrown
without needing a handle to that exception.
I had thought about using other means, ie using sysctl or utsname for
osx/linux....but this solution is more universal between OS's as well as
provided by the compiler, not via system operations
Floats and doubles can now be read from strings, using the C standard library
functions for this purpose (strtof and strtod). The code also relies on
standard library functions to implement isNaN() and isInfinite()