JDK-6966770 : When Runtime.exec() fails, child process remains with grabbing resources in jdk1.4.2_16
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 1.4.2_16
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: solaris_10
  • CPU: sparc
  • Submitted: 2010-07-06
  • Updated: 2011-07-20
  • Resolved: 2010-11-09
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
1.4.2_29 b01Fixed
Description
COBFIGURATION:
 OS: Solaris10
 JDK : 1.4.2_16

PROBLEM:
When non-existing directory is specified for java.lang.Runtime.exec(String, String[], File dir),
IOException occurs and Runtime#exec() fails.

In this case, JVM terminates the parent process and tries to restart the process.
The remaining child process grabs the communication port(ServerSocket) which was
opened by the paraent process.
Then re-satrting the parent process fails and an error occurs.


REQUEST:
- To backport the source code for chdir() failure in jdk5 to jdk1.4.2_XX

According to the UNIXProcess_md.c in JDK5fcs source code archive,

--- j2se/src/solaris/native/java/lang/UNIXProcess_md.c ------
.....
    if (resultPid == 0) {
        /* Child process */

        /* Close the parent sides of the pipe.
           Give the child sides of the pipes the right fileno's.
           Closing pipe fds here is redundant, since closeDescriptors()
           would do it anyways, but a little paranoia is a good thing. */
        /* Note: it is possible for fdin[0] == 0 */
        close(fdin[1]);
        moveDescriptor(fdin[0], STDIN_FILENO);
        close(fdout[0]);
        moveDescriptor(fdout[1], STDOUT_FILENO);
        close(fderr[0]);
        if (redirectErrorStream) {
            close(fderr[1]);
            dup2(STDOUT_FILENO, STDERR_FILENO);
        } else {
            moveDescriptor(fderr[1], STDERR_FILENO);
        }

        /* close everything */
        if (closeDescriptors() == 0) { /* failed,  close the old way */
            int max_fd = (int)sysconf(_SC_OPEN_MAX);
            int i;
            for (i = 3; i < max_fd; i++)
                close(i);
        }

        /* change to the new working directory */
        if (ppath != NULL) {
            if (chdir(ppath) < 0) {
#if 0 /*  __solaris__ */
                /* The well-intentioned code below tried to throw an
                   exception to our caller, but that doesn't work in a
                   child process -- it simply leaked a process.
                   Delete this code once we fix this properly. */

                /* failed to change directory, cleanup */
                char errmsg[128];
                sprintf(errmsg, "errno: %d, error: %s\n", errno, "Failed to change directory");
                JNU_ThrowByNameWithLastError(env, "java/io/IOException", errmsg);
                goto cleanup5;
#else
                /* Should really communicate this back to the parent so that it
                 * can be converted into an exception
                 */
                perror(ppath);
                _exit(-1);
#endif
            }
        }
......
------------------------------------------------

when chdir() fails, _exit(-1) is executed.
This does not cause the case that child process keeps grabbing resources.

This should be backported to 1.4.2_XX.

Comments
SUGGESTED FIX http://jpsesvr.sfbay.sun.com:8080/ctetools/html/ViewDetail.jsp?index=3693
01-09-2010

EVALUATION when chdir() fails, _exit(-1) is executed in child.
27-08-2010