void-packages/srcpkgs/openjdk8/patches/002_8043780-pr3368.patch

114 lines
3.7 KiB
Diff

# HG changeset patch
# User martin
# Date 1494116427 -3600
# Sun May 07 01:20:27 2017 +0100
# Node ID 0bd3170be8c729dfaa88e7aa97449b2f36c650a9
# Parent baf64c88538f477d7f5a0cf90b670108ac312375
8043780, PR3368: Use open(O_CLOEXEC) instead of fcntl(FD_CLOEXEC)
Summary: Use open(O_CLOEXEC) where available; fall back to FD_CLOEXEC when necessary
Reviewed-by: rasbold, dholmes
diff --git a/src/os/linux/vm/os_linux.cpp b/src/os/linux/vm/os_linux.cpp
--- openjdk/hotspot/src/os/linux/vm/os_linux.cpp
+++ openjdk/hotspot/src/os/linux/vm/os_linux.cpp
@@ -5282,38 +5282,16 @@
errno = ENAMETOOLONG;
return -1;
}
- int fd;
int o_delete = (oflag & O_DELETE);
oflag = oflag & ~O_DELETE;
- fd = ::open64(path, oflag, mode);
- if (fd == -1) return -1;
-
- //If the open succeeded, the file might still be a directory
- {
- struct stat64 buf64;
- int ret = ::fstat64(fd, &buf64);
- int st_mode = buf64.st_mode;
-
- if (ret != -1) {
- if ((st_mode & S_IFMT) == S_IFDIR) {
- errno = EISDIR;
- ::close(fd);
- return -1;
- }
- } else {
- ::close(fd);
- return -1;
- }
- }
-
- /*
- * All file descriptors that are opened in the JVM and not
- * specifically destined for a subprocess should have the
- * close-on-exec flag set. If we don't set it, then careless 3rd
- * party native code might fork and exec without closing all
- * appropriate file descriptors (e.g. as we do in closeDescriptors in
- * UNIXProcess.c), and this in turn might:
+
+ /* All file descriptors that are opened in the Java process and not
+ * specifically destined for a subprocess should have the close-on-exec
+ * flag set. If we don't set it, then careless 3rd party native code
+ * might fork and exec without closing all appropriate file descriptors
+ * (e.g. as we do in closeDescriptors in UNIXProcess.c), and this in
+ * turn might:
*
* - cause end-of-file to fail to be detected on some file
* descriptors, resulting in mysterious hangs, or
@@ -5329,12 +5307,49 @@
* 4843136: (process) pipe file descriptor from Runtime.exec not being closed
* 6339493: (process) Runtime.exec does not close all file descriptors on Solaris 9
*/
+ // Modern Linux kernels (after 2.6.23 2007) support O_CLOEXEC with open().
+ // O_CLOEXEC is preferable to using FD_CLOEXEC on an open file descriptor
+ // because it saves a system call and removes a small window where the flag
+ // is unset. On ancient Linux kernels the O_CLOEXEC flag will be ignored
+ // and we fall back to using FD_CLOEXEC (see below).
+#ifdef O_CLOEXEC
+ oflag |= O_CLOEXEC;
+#endif
+
+ int fd = ::open64(path, oflag, mode);
+ if (fd == -1) return -1;
+
+ //If the open succeeded, the file might still be a directory
+ {
+ struct stat64 buf64;
+ int ret = ::fstat64(fd, &buf64);
+ int st_mode = buf64.st_mode;
+
+ if (ret != -1) {
+ if ((st_mode & S_IFMT) == S_IFDIR) {
+ errno = EISDIR;
+ ::close(fd);
+ return -1;
+ }
+ } else {
+ ::close(fd);
+ return -1;
+ }
+ }
+
#ifdef FD_CLOEXEC
- {
- int flags = ::fcntl(fd, F_GETFD);
- if (flags != -1)
- ::fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
+ // Validate that the use of the O_CLOEXEC flag on open above worked.
+ // With recent kernels, we will perform this check exactly once.
+ static sig_atomic_t O_CLOEXEC_is_known_to_work = 0;
+ if (!O_CLOEXEC_is_known_to_work) {
+ int flags = ::fcntl(fd, F_GETFD);
+ if (flags != -1) {
+ if ((flags & FD_CLOEXEC) != 0)
+ O_CLOEXEC_is_known_to_work = 1;
+ else
+ ::fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
}
+ }
#endif
if (o_delete != 0) {