8356493: make createFile accept LinkOption

This commit is contained in:
Brian Burkhalter 2025-09-08 12:48:28 -07:00
parent b59c3f6c6f
commit 77df14373a
6 changed files with 22 additions and 14 deletions

View File

@ -220,7 +220,11 @@ public interface SecureDirectoryStream<T>
* path then it locates the target file (the {@code targetdir} parameter is
* ignored). If the {@code existing} parameter is a relative path it is
* located relative to the open directory identified by the {@code
* targetdir} parameter.
* targetdir} parameter, unless {@code targetdir} is {@code null}, in which
* case it is located relative to the current working directory. By default,
* symbolic links are followed. If the option
* {@linkplain LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} is present then
* symbolic links are not followed.
*
* @param link
* the link (directory entry) to create
@ -228,6 +232,8 @@ public interface SecureDirectoryStream<T>
* the destination directory
* @param existing
* a path to an existing file
* @param options
* options indicating how symbolic links are handled
*
* @return the path to the link (directory entry)
*
@ -247,7 +253,8 @@ public interface SecureDirectoryStream<T>
*
* @since 26
*/
T createLink(T link, SecureDirectoryStream<T> targetdir, T existing)
T createLink(T link, SecureDirectoryStream<T> targetdir, T existing,
LinkOption... options)
throws IOException;
/**

View File

@ -143,11 +143,13 @@ class UnixConstants {
// flags used with openat/unlinkat/etc.
#if defined(AT_FDCWD) && defined(AT_SYMLINK_NOFOLLOW) && defined(AT_REMOVEDIR)
static final int PREFIX_AT_FDCWD = AT_FDCWD;
static final int PREFIX_AT_SYMLINK_FOLLOW = AT_SYMLINK_FOLLOW;
static final int PREFIX_AT_SYMLINK_NOFOLLOW = AT_SYMLINK_NOFOLLOW;
static final int PREFIX_AT_REMOVEDIR = AT_REMOVEDIR;
#else
// not supported (dummy values will not be used at runtime).
static final int PREFIX_AT_FDCWD = 00;
static final int PREFIX_AT_SYMLINK_FOLLOW = 00;
static final int PREFIX_AT_SYMLINK_NOFOLLOW = 00;
static final int PREFIX_AT_REMOVEDIR = 00;
#endif

View File

@ -136,16 +136,17 @@ class UnixNativeDispatcher {
/**
* linkat(int fd1, const char *name1, int fd2, const char *name2, int flag)
*/
static void linkat(int dfd1, UnixPath path1, int dfd2, UnixPath path2)
static void linkat(int dfd1, UnixPath path1, int dfd2, UnixPath path2,
int flag)
throws UnixException
{
try (NativeBuffer buffer1 = copyToNativeBuffer(path1);
NativeBuffer buffer2 = copyToNativeBuffer(path2)) {
linkat0(dfd1, buffer1.address(), dfd2, buffer2.address());
linkat0(dfd1, buffer1.address(), dfd2, buffer2.address(), flag);
}
}
private static native void linkat0(int dfd1, long addr1,
int dfd2, long addr2)
int dfd2, long addr2, int flag)
throws UnixException;
/**

View File

@ -217,7 +217,7 @@ class UnixSecureDirectoryStream
@Override
public Path createLink(Path link, SecureDirectoryStream<Path> dir,
Path target)
Path target, LinkOption... options)
throws IOException
{
UnixPath linkpath = UnixPath.toUnixPath(link);
@ -229,7 +229,9 @@ class UnixSecureDirectoryStream
throw new ClosedDirectoryStreamException();
try {
UnixSecureDirectoryStream that = (UnixSecureDirectoryStream)dir;
linkat(that.dfd, targetpath, this.dfd, linkpath);
int targetfd = that != null ? that.dfd : AT_FDCWD;
int flag = Util.followLinks(options) ? AT_SYMLINK_FOLLOW : 0;
linkat(targetfd, targetpath, this.dfd, linkpath, flag);
} catch (UnixException x) {
x.rethrowAsIOException(linkpath, targetpath);
return null; // keep compiler happy

View File

@ -1029,14 +1029,14 @@ Java_sun_nio_fs_UnixNativeDispatcher_link0(JNIEnv* env, jclass this,
JNIEXPORT void JNICALL
Java_sun_nio_fs_UnixNativeDispatcher_linkat0(JNIEnv* env, jclass this,
int dfd1, long addr1,
int dfd2, long addr2)
jint dfd1, jlong addr1,
jint dfd2, jlong addr2, jint flag)
{
int err;
const char* name1 = (const char*)jlong_to_ptr(addr1);
const char* name2 = (const char*)jlong_to_ptr(addr2);
RESTARTABLE(linkat(dfd1, name1, dfd2, name2, AT_SYMLINK_FOLLOW), err);
RESTARTABLE(linkat(dfd1, name1, dfd2, name2, flag), err);
if (err == -1) {
throwUnixException(env, errno);
}

View File

@ -497,10 +497,6 @@ public class SecureDS {
stream.createLink(null, stream, file);
shouldNotGetHere();
} catch (NullPointerException x) { }
try {
stream.createLink(link, null, file);
shouldNotGetHere();
} catch (NullPointerException x) { }
try {
stream.createLink(link, stream, null);
shouldNotGetHere();