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
--- 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);
+ }
+ }
+}