8139133: Changing the modification time on a unix domain socket file fails
authorbpb
Thu, 10 Dec 2015 15:57:27 -0800
changeset 34537 ca5ca0e04c96
parent 34536 d424563a8ab8
child 34538 b0705127fbba
8139133: Changing the modification time on a unix domain socket file fails Summary: If a file descriptor cannot be obtained, use utimes() instead of futimes(). Reviewed-by: alanb
jdk/make/mapfiles/libnio/mapfile-linux
jdk/make/mapfiles/libnio/mapfile-macosx
jdk/make/mapfiles/libnio/mapfile-solaris
jdk/make/src/native/genconstants/fs/genUnixConstants.c
jdk/src/java.base/linux/classes/sun/nio/fs/LinuxDosFileAttributeView.java
jdk/src/java.base/linux/classes/sun/nio/fs/LinuxFileStore.java
jdk/src/java.base/linux/classes/sun/nio/fs/LinuxUserDefinedFileAttributeView.java
jdk/src/java.base/solaris/classes/sun/nio/fs/SolarisAclFileAttributeView.java
jdk/src/java.base/solaris/classes/sun/nio/fs/SolarisUserDefinedFileAttributeView.java
jdk/src/java.base/unix/classes/sun/nio/fs/UnixException.java
jdk/src/java.base/unix/classes/sun/nio/fs/UnixFileAttributeViews.java
jdk/src/java.base/unix/classes/sun/nio/fs/UnixNativeDispatcher.java
jdk/src/java.base/unix/classes/sun/nio/fs/UnixPath.java
jdk/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c
jdk/test/java/nio/file/attribute/BasicFileAttributeView/UnixSocketFile.java
--- a/jdk/make/mapfiles/libnio/mapfile-linux	Thu Dec 10 09:23:49 2015 -0800
+++ b/jdk/make/mapfiles/libnio/mapfile-linux	Thu Dec 10 15:57:27 2015 -0800
@@ -173,7 +173,7 @@
 		Java_sun_nio_fs_UnixNativeDispatcher_futimes;
 		Java_sun_nio_fs_UnixNativeDispatcher_open0;
 		Java_sun_nio_fs_UnixNativeDispatcher_openat0;
-		Java_sun_nio_fs_UnixNativeDispatcher_close;
+		Java_sun_nio_fs_UnixNativeDispatcher_close0;
 		Java_sun_nio_fs_UnixNativeDispatcher_read;
 		Java_sun_nio_fs_UnixNativeDispatcher_write;
 		Java_sun_nio_fs_UnixNativeDispatcher_fopen0;
--- a/jdk/make/mapfiles/libnio/mapfile-macosx	Thu Dec 10 09:23:49 2015 -0800
+++ b/jdk/make/mapfiles/libnio/mapfile-macosx	Thu Dec 10 15:57:27 2015 -0800
@@ -150,7 +150,7 @@
 		Java_sun_nio_fs_UnixNativeDispatcher_futimes;
 		Java_sun_nio_fs_UnixNativeDispatcher_open0;
 		Java_sun_nio_fs_UnixNativeDispatcher_openat0;
-		Java_sun_nio_fs_UnixNativeDispatcher_close;
+		Java_sun_nio_fs_UnixNativeDispatcher_close0;
 		Java_sun_nio_fs_UnixNativeDispatcher_read;
 		Java_sun_nio_fs_UnixNativeDispatcher_write;
 		Java_sun_nio_fs_UnixNativeDispatcher_fopen0;
--- a/jdk/make/mapfiles/libnio/mapfile-solaris	Thu Dec 10 09:23:49 2015 -0800
+++ b/jdk/make/mapfiles/libnio/mapfile-solaris	Thu Dec 10 15:57:27 2015 -0800
@@ -150,7 +150,7 @@
 		Java_sun_nio_fs_UnixNativeDispatcher_futimes;
 		Java_sun_nio_fs_UnixNativeDispatcher_open0;
 		Java_sun_nio_fs_UnixNativeDispatcher_openat0;
-		Java_sun_nio_fs_UnixNativeDispatcher_close;
+		Java_sun_nio_fs_UnixNativeDispatcher_close0;
 		Java_sun_nio_fs_UnixNativeDispatcher_read;
 		Java_sun_nio_fs_UnixNativeDispatcher_write;
 		Java_sun_nio_fs_UnixNativeDispatcher_fopen0;
--- a/jdk/make/src/native/genconstants/fs/genUnixConstants.c	Thu Dec 10 09:23:49 2015 -0800
+++ b/jdk/make/src/native/genconstants/fs/genUnixConstants.c	Thu Dec 10 15:57:27 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -104,6 +104,7 @@
 
     // errors
     DEF(ENOENT);
+    DEF(ENXIO);
     DEF(EACCES);
     DEF(EEXIST);
     DEF(ENOTDIR);
--- a/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxDosFileAttributeView.java	Thu Dec 10 09:23:49 2015 -0800
+++ b/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxDosFileAttributeView.java	Thu Dec 10 15:57:27 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -117,8 +117,9 @@
     public DosFileAttributes readAttributes() throws IOException {
         file.checkRead();
 
-        int fd = file.openForAttributeAccess(followLinks);
+        int fd = -1;
         try {
+             fd = file.openForAttributeAccess(followLinks);
              final UnixFileAttributes attrs = UnixFileAttributes.get(fd);
              final int dosAttribute = getDosAttribute(fd);
 
@@ -253,8 +254,9 @@
     private void updateDosAttribute(int flag, boolean enable) throws IOException {
         file.checkWrite();
 
-        int fd = file.openForAttributeAccess(followLinks);
+        int fd = -1;
         try {
+            fd = file.openForAttributeAccess(followLinks);
             int oldValue = getDosAttribute(fd);
             int newValue = oldValue;
             if (enable) {
--- a/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxFileStore.java	Thu Dec 10 09:23:49 2015 -0800
+++ b/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxFileStore.java	Thu Dec 10 15:57:27 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -94,22 +94,20 @@
     // returns true if extended attributes enabled on file system where given
     // file resides, returns false if disabled or unable to determine.
     private boolean isExtendedAttributesEnabled(UnixPath path) {
+        int fd = -1;
         try {
-            int fd = path.openForAttributeAccess(false);
-            try {
-                // fgetxattr returns size if called with size==0
-                byte[] name = Util.toBytes("user.java");
-                LinuxNativeDispatcher.fgetxattr(fd, name, 0L, 0);
+            fd = path.openForAttributeAccess(false);
+
+            // fgetxattr returns size if called with size==0
+            byte[] name = Util.toBytes("user.java");
+            LinuxNativeDispatcher.fgetxattr(fd, name, 0L, 0);
+            return true;
+        } catch (UnixException e) {
+            // attribute does not exist
+            if (e.errno() == UnixConstants.ENODATA)
                 return true;
-            } catch (UnixException e) {
-                // attribute does not exist
-                if (e.errno() == UnixConstants.ENODATA)
-                    return true;
-            } finally {
-                UnixNativeDispatcher.close(fd);
-            }
-        } catch (IOException ignore) {
-            // nothing we can do
+        } finally {
+            UnixNativeDispatcher.close(fd);
         }
         return false;
     }
--- a/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxUserDefinedFileAttributeView.java	Thu Dec 10 09:23:49 2015 -0800
+++ b/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxUserDefinedFileAttributeView.java	Thu Dec 10 15:57:27 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -97,7 +97,12 @@
         if (System.getSecurityManager() != null)
             checkAccess(file.getPathForPermissionCheck(), true, false);
 
-        int fd = file.openForAttributeAccess(followLinks);
+        int fd = -1;
+        try {
+            fd = file.openForAttributeAccess(followLinks);
+        } catch (UnixException x) {
+            x.rethrowAsIOException(file);
+        }
         NativeBuffer buffer = null;
         try {
             int size = 1024;
@@ -133,7 +138,12 @@
         if (System.getSecurityManager() != null)
             checkAccess(file.getPathForPermissionCheck(), true, false);
 
-        int fd = file.openForAttributeAccess(followLinks);
+        int fd = -1;
+        try {
+            fd = file.openForAttributeAccess(followLinks);
+        } catch (UnixException x) {
+            x.rethrowAsIOException(file);
+        }
         try {
             // fgetxattr returns size if called with size==0
             return fgetxattr(fd, nameAsBytes(file,name), 0L, 0);
@@ -169,7 +179,12 @@
             address = nb.address();
         }
 
-        int fd = file.openForAttributeAccess(followLinks);
+        int fd = -1;
+        try {
+            fd = file.openForAttributeAccess(followLinks);
+        } catch (UnixException x) {
+            x.rethrowAsIOException(file);
+        }
         try {
             try {
                 int n = fgetxattr(fd, nameAsBytes(file,name), address, rem);
@@ -236,7 +251,12 @@
             }
         }
 
-        int fd = file.openForAttributeAccess(followLinks);
+        int fd = -1;
+        try {
+            fd = file.openForAttributeAccess(followLinks);
+        } catch (UnixException x) {
+            x.rethrowAsIOException(file);
+        }
         try {
             try {
                 fsetxattr(fd, nameAsBytes(file,name), address, rem);
@@ -260,7 +280,12 @@
         if (System.getSecurityManager() != null)
             checkAccess(file.getPathForPermissionCheck(), false, true);
 
-        int fd = file.openForAttributeAccess(followLinks);
+        int fd = -1;
+        try {
+            fd = file.openForAttributeAccess(followLinks);
+        } catch (UnixException x) {
+            x.rethrowAsIOException(file);
+        }
         try {
             fremovexattr(fd, nameAsBytes(file,name));
         } catch (UnixException x) {
--- a/jdk/src/java.base/solaris/classes/sun/nio/fs/SolarisAclFileAttributeView.java	Thu Dec 10 09:23:49 2015 -0800
+++ b/jdk/src/java.base/solaris/classes/sun/nio/fs/SolarisAclFileAttributeView.java	Thu Dec 10 15:57:27 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -309,7 +309,12 @@
         checkAccess(file, true, false);
 
         // open file (will fail if file is a link and not following links)
-        int fd = file.openForAttributeAccess(followLinks);
+        int fd = -1;
+        try {
+            fd = file.openForAttributeAccess(followLinks);
+        } catch (UnixException x) {
+            x.rethrowAsIOException(file);
+        }
         try {
             long address = unsafe.allocateMemory(SIZEOF_ACE_T * MAX_ACL_ENTRIES);
             try {
@@ -338,7 +343,12 @@
         checkAccess(file, false, true);
 
         // open file (will fail if file is a link and not following links)
-        int fd = file.openForAttributeAccess(followLinks);
+        int fd = -1;
+        try {
+            fd = file.openForAttributeAccess(followLinks);
+        } catch (UnixException x) {
+            x.rethrowAsIOException(file);
+        }
         try {
             // SECURITY: need to copy list as can change during processing
             acl = new ArrayList<AclEntry>(acl);
--- a/jdk/src/java.base/solaris/classes/sun/nio/fs/SolarisUserDefinedFileAttributeView.java	Thu Dec 10 09:23:49 2015 -0800
+++ b/jdk/src/java.base/solaris/classes/sun/nio/fs/SolarisUserDefinedFileAttributeView.java	Thu Dec 10 15:57:27 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -71,9 +71,11 @@
         if (System.getSecurityManager() != null)
             checkAccess(file.getPathForPermissionCheck(), true, false);
 
-        int fd = file.openForAttributeAccess(followLinks);
+        int fd = -1;
         try {
             try {
+                fd = file.openForAttributeAccess(followLinks);
+
                 // open extended attribute directory
                 int dfd = openat(fd, HERE, (O_RDONLY|O_XATTR), 0);
                 long dp;
@@ -112,9 +114,11 @@
         if (System.getSecurityManager() != null)
             checkAccess(file.getPathForPermissionCheck(), true, false);
 
-        int fd = file.openForAttributeAccess(followLinks);
+        int fd = -1;
         try {
             try {
+                fd = file.openForAttributeAccess(followLinks);
+
                 // open attribute file
                 int afd = openat(fd, nameAsBytes(file,name), (O_RDONLY|O_XATTR), 0);
                 try {
@@ -142,9 +146,11 @@
         if (System.getSecurityManager() != null)
             checkAccess(file.getPathForPermissionCheck(), true, false);
 
-        int fd = file.openForAttributeAccess(followLinks);
+        int fd = -1;
         try {
             try {
+                fd = file.openForAttributeAccess(followLinks);
+
                 // open attribute file
                 int afd = openat(fd, nameAsBytes(file,name), (O_RDONLY|O_XATTR), 0);
 
@@ -181,9 +187,11 @@
         if (System.getSecurityManager() != null)
             checkAccess(file.getPathForPermissionCheck(), false, true);
 
-        int fd = file.openForAttributeAccess(followLinks);
+        int fd = -1;
         try {
             try {
+                fd = file.openForAttributeAccess(followLinks);
+
                 // open/create attribute file
                 int afd = openat(fd, nameAsBytes(file,name),
                                  (O_CREAT|O_WRONLY|O_TRUNC|O_XATTR),
@@ -217,8 +225,10 @@
         if (System.getSecurityManager() != null)
             checkAccess(file.getPathForPermissionCheck(), false, true);
 
-        int fd = file.openForAttributeAccess(followLinks);
+        int fd = -1;
         try {
+            fd = file.openForAttributeAccess(followLinks);
+
             int dfd = openat(fd, HERE, (O_RDONLY|O_XATTR), 0);
             try {
                 unlinkat(dfd, nameAsBytes(file,name), 0);
--- a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixException.java	Thu Dec 10 09:23:49 2015 -0800
+++ b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixException.java	Thu Dec 10 15:57:27 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -86,6 +86,9 @@
             return new NoSuchFileException(file, other, null);
         if (errno() == UnixConstants.EEXIST)
             return new FileAlreadyExistsException(file, other, null);
+        if (errno() == UnixConstants.ELOOP)
+            return new FileSystemException(file, other, errorString()
+                + " or unable to access attributes of symbolic link");
 
         // fallback to the more general exception
         return new FileSystemException(file, other, errorString());
--- a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixFileAttributeViews.java	Thu Dec 10 09:23:49 2015 -0800
+++ b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixFileAttributeViews.java	Thu Dec 10 15:57:27 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -71,14 +71,30 @@
             // permission check
             file.checkWrite();
 
-            int fd = file.openForAttributeAccess(followLinks);
+            boolean haveFd = false;
+            boolean useFutimes = false;
+            int fd = -1;
+            try {
+                fd = file.openForAttributeAccess(followLinks);
+                if (fd != -1) {
+                    haveFd = true;
+                    useFutimes = futimesSupported();
+                }
+            } catch (UnixException x) {
+                if (x.errno() != UnixConstants.ENXIO) {
+                    x.rethrowAsIOException(file);
+                }
+            }
+
             try {
                 // assert followLinks || !UnixFileAttributes.get(fd).isSymbolicLink();
 
                 // if not changing both attributes then need existing attributes
                 if (lastModifiedTime == null || lastAccessTime == null) {
                     try {
-                        UnixFileAttributes attrs = UnixFileAttributes.get(fd);
+                        UnixFileAttributes attrs = haveFd ?
+                            UnixFileAttributes.get(fd) :
+                            UnixFileAttributes.get(file, followLinks);
                         if (lastModifiedTime == null)
                             lastModifiedTime = attrs.lastModifiedTime();
                         if (lastAccessTime == null)
@@ -94,7 +110,7 @@
 
                 boolean retry = false;
                 try {
-                    if (futimesSupported()) {
+                    if (useFutimes) {
                         futimes(fd, accessValue, modValue);
                     } else {
                         utimes(file, accessValue, modValue);
@@ -113,7 +129,7 @@
                     if (modValue < 0L) modValue = 0L;
                     if (accessValue < 0L) accessValue= 0L;
                     try {
-                        if (futimesSupported()) {
+                        if (useFutimes) {
                             futimes(fd, accessValue, modValue);
                         } else {
                             utimes(file, accessValue, modValue);
--- a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixNativeDispatcher.java	Thu Dec 10 09:23:49 2015 -0800
+++ b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixNativeDispatcher.java	Thu Dec 10 15:57:27 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -91,9 +91,14 @@
         throws UnixException;
 
     /**
-     * close(int filedes)
+     * close(int filedes). If fd is -1 this is a no-op.
      */
-    static native void close(int fd);
+    static void close(int fd) {
+        if (fd != -1) {
+            close0(fd);
+        }
+    }
+    private static native void close0(int fd);
 
     /**
      * FILE* fopen(const char *filename, const char* mode);
--- a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixPath.java	Thu Dec 10 09:23:49 2015 -0800
+++ b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixPath.java	Thu Dec 10 15:57:27 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -764,11 +764,12 @@
     // -- file operations --
 
     // package-private
-    int openForAttributeAccess(boolean followLinks) throws IOException {
+    int openForAttributeAccess(boolean followLinks) throws UnixException {
         int flags = O_RDONLY;
         if (!followLinks) {
             if (O_NOFOLLOW == 0)
-                throw new IOException("NOFOLLOW_LINKS is not supported on this platform");
+                throw new UnixException
+                    ("NOFOLLOW_LINKS is not supported on this platform");
             flags |= O_NOFOLLOW;
         }
         try {
@@ -778,12 +779,7 @@
             if (getFileSystem().isSolaris() && x.errno() == EINVAL)
                 x.setError(ELOOP);
 
-            if (x.errno() == ELOOP)
-                throw new FileSystemException(getPathForExceptionMessage(), null,
-                    x.getMessage() + " or unable to access attributes of symbolic link");
-
-            x.rethrowAsIOException(this);
-            return -1; // keep compile happy
+            throw x;
         }
     }
 
--- a/jdk/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c	Thu Dec 10 09:23:49 2015 -0800
+++ b/jdk/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c	Thu Dec 10 15:57:27 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -408,7 +408,7 @@
 }
 
 JNIEXPORT void JNICALL
-Java_sun_nio_fs_UnixNativeDispatcher_close(JNIEnv* env, jclass this, jint fd) {
+Java_sun_nio_fs_UnixNativeDispatcher_close0(JNIEnv* env, jclass this, jint fd) {
     int err;
     /* TDB - need to decide if EIO and other errors should cause exception */
     RESTARTABLE(close((int)fd), err);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/attribute/BasicFileAttributeView/UnixSocketFile.java	Thu Dec 10 15:57:27 2015 -0800
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 8139133
+ * @summary Verify ability to set time attributes of socket files with no device
+ * @requires os.family == "linux"
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardWatchEventKinds;
+import java.nio.file.WatchKey;
+import java.nio.file.WatchService;
+import java.nio.file.attribute.BasicFileAttributeView;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.nio.file.attribute.FileTime;
+
+public class UnixSocketFile {
+    private static final String TEST_SUB_DIR = "UnixSocketFile";
+    private static final String SOCKET_FILE_NAME = "mysocket";
+    private static final String CMD_BASE = "nc -lU";
+
+    public static void main(String[] args)
+        throws InterruptedException, IOException {
+
+        // Create a new sub-directory of the nominal test directory in which
+        // 'nc' will create the socket file.
+        String testSubDir = System.getProperty("test.dir", ".")
+            + File.separator + TEST_SUB_DIR;
+        Path socketTestDir = Paths.get(testSubDir);
+        Files.createDirectory(socketTestDir);
+
+        // Set the path of the socket file.
+        String socketFilePath = testSubDir + File.separator
+            + SOCKET_FILE_NAME;
+
+        // Create a process which executes the nc (netcat) utility to create
+        // a socket file at the indicated location.
+        Process proc;
+        FileSystem fs = FileSystems.getDefault();
+        try (WatchService ws = fs.newWatchService()) {
+            // Watch the test sub-directory to receive notification when an
+            // entry, i.e., the socket file, is added to the sub-directory.
+            WatchKey wk = socketTestDir.register(ws,
+                    StandardWatchEventKinds.ENTRY_CREATE);
+
+            // Execute the 'nc' command.
+            proc = Runtime.getRuntime().exec(CMD_BASE + " " + socketFilePath);
+
+            // Wait until the socket file is created.
+            WatchKey key = ws.take();
+            if (key != wk) {
+                throw new RuntimeException("Unknown entry created - expected: "
+                    + wk.watchable() + ", actual: " + key.watchable());
+            }
+            wk.cancel();
+        }
+
+        // Verify that the socket file in fact exists.
+        Path socketPath = fs.getPath(socketFilePath);
+        if (!Files.exists(socketPath)) {
+            throw new RuntimeException("Socket file " + socketFilePath
+                + " was not created by \"nc\" command.");
+        }
+
+        // Retrieve the most recent access and modification times of the
+        // socket file; print the values.
+        BasicFileAttributeView attributeView = Files.getFileAttributeView(
+                socketPath, BasicFileAttributeView.class);
+        BasicFileAttributes oldAttributes = attributeView.readAttributes();
+        FileTime oldAccessTime = oldAttributes.lastAccessTime();
+        FileTime oldModifiedTime = oldAttributes.lastModifiedTime();
+        System.out.println("Old times: " + oldAccessTime
+            + " " + oldModifiedTime);
+
+        // Calculate the time to which the access and modification times of the
+        // socket file will be changed.
+        FileTime newFileTime =
+            FileTime.fromMillis(oldAccessTime.toMillis() + 1066);
+
+        try {
+            // Set the access and modification times of the socket file.
+            attributeView.setTimes(newFileTime, newFileTime, null);
+
+            // Retrieve the updated access and modification times of the
+            // socket file; print the values.
+            FileTime newAccessTime = null;
+            FileTime newModifiedTime = null;
+            BasicFileAttributes newAttributes = attributeView.readAttributes();
+            newAccessTime = newAttributes.lastAccessTime();
+            newModifiedTime = newAttributes.lastModifiedTime();
+            System.out.println("New times: " + newAccessTime + " "
+                + newModifiedTime);
+
+            // Verify that the updated times have the expected values.
+            if ((newAccessTime != null && !newAccessTime.equals(newFileTime))
+                || (newModifiedTime != null
+                    && !newModifiedTime.equals(newFileTime))) {
+                throw new RuntimeException("Failed to set correct times.");
+            }
+        } finally {
+            // Destry the process running netcat and delete the socket file.
+            proc.destroy();
+            Files.delete(socketPath);
+        }
+    }
+}