Skip to content

Commit f993f90

Browse files
author
Joachim Kern
committed
8360401: [AIX] java/lang/ProcessBuilder/FDLeakTest/FDLeakTest.java fails since JDK-8210549
Reviewed-by: mdoerr, stuefe
1 parent 3036866 commit f993f90

File tree

1 file changed

+27
-13
lines changed

1 file changed

+27
-13
lines changed

src/java.base/unix/native/libjava/childproc.c

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -67,24 +67,39 @@ markCloseOnExec(int fd)
6767
return 0;
6868
}
6969

70+
#if !defined(_AIX)
71+
/* The /proc file system on AIX does not contain open system files
72+
* like /dev/random. Therefore we use a different approach and do
73+
* not need isAsciiDigit() or FD_DIR */
7074
static int
7175
isAsciiDigit(char c)
7276
{
7377
return c >= '0' && c <= '9';
7478
}
7579

76-
#if defined(_AIX)
77-
/* AIX does not understand '/proc/self' - it requires the real process ID */
78-
#define FD_DIR aix_fd_dir
79-
#elif defined(_ALLBSD_SOURCE)
80-
#define FD_DIR "/dev/fd"
81-
#else
82-
#define FD_DIR "/proc/self/fd"
80+
#if defined(_ALLBSD_SOURCE)
81+
#define FD_DIR "/dev/fd"
82+
#else
83+
#define FD_DIR "/proc/self/fd"
84+
#endif
8385
#endif
8486

8587
static int
8688
markDescriptorsCloseOnExec(void)
8789
{
90+
#if defined(_AIX)
91+
/* On AIX, we cannot rely on proc file system iteration to find all open files. Since
92+
* iteration over all possible file descriptors, and subsequently closing them, can
93+
* take a very long time, we use a bulk close via `ioctl` that is available on AIX.
94+
* Since we hard-close, we need to make sure to keep the fail pipe file descriptor
95+
* alive until the exec call. Therefore we mark the fail pipe fd with close on exec
96+
* like the other OSes do, but then proceed to hard-close file descriptors beyond that.
97+
*/
98+
if (fcntl(FAIL_FILENO + 1, F_CLOSEM, 0) == -1 ||
99+
(markCloseOnExec(FAIL_FILENO) == -1 && errno != EBADF)) {
100+
return -1;
101+
}
102+
#else
88103
DIR *dp;
89104
struct dirent *dirp;
90105
/* This function marks all file descriptors beyond stderr as CLOEXEC.
@@ -93,12 +108,6 @@ markDescriptorsCloseOnExec(void)
93108
* execve. */
94109
const int fd_from = STDERR_FILENO + 1;
95110

96-
#if defined(_AIX)
97-
/* AIX does not understand '/proc/self' - it requires the real process ID */
98-
char aix_fd_dir[32]; /* the pid has at most 19 digits */
99-
snprintf(aix_fd_dir, 32, "/proc/%d/fd", getpid());
100-
#endif
101-
102111
if ((dp = opendir(FD_DIR)) == NULL)
103112
return -1;
104113

@@ -114,6 +123,7 @@ markDescriptorsCloseOnExec(void)
114123
}
115124

116125
closedir(dp);
126+
#endif
117127

118128
return 0;
119129
}
@@ -406,6 +416,10 @@ childProcess(void *arg)
406416
/* We moved the fail pipe fd */
407417
fail_pipe_fd = FAIL_FILENO;
408418

419+
/* For AIX: The code in markDescriptorsCloseOnExec() relies on the current
420+
* semantic of this function. When this point here is reached only the
421+
* FDs 0,1,2 and 3 are further used until the exec() or the exit(-1). */
422+
409423
/* close everything */
410424
if (markDescriptorsCloseOnExec() == -1) { /* failed, close the old way */
411425
int max_fd = (int)sysconf(_SC_OPEN_MAX);

0 commit comments

Comments
 (0)