United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6966770 When Runtime.exec() fails, child process remains with grabbing resources in jdk1.4.2_16
JDK-6966770 : When Runtime.exec() fails, child process remains with grabbing resources in jdk1.4.2_16

Details
Type:
Bug
Submit Date:
2010-07-06
Status:
Closed
Updated Date:
2011-07-20
Project Name:
JDK
Resolved Date:
2010-11-09
Component:
core-libs
OS:
solaris_10
Sub-Component:
java.lang
CPU:
sparc
Priority:
P3
Resolution:
Fixed
Affected Versions:
1.4.2_16
Fixed Versions:
1.4.2_29 (b01)

Related Reports

Sub Tasks

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
EVALUATION

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

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



Hardware and Software, Engineered to Work Together