8233451: (fs) Files.newInputStream() cannot be used with character special files

Reviewed-by: alanb
This commit is contained in:
Brian Burkhalter 2024-10-23 18:53:30 +00:00
parent 002de86081
commit de92fe3757
8 changed files with 415 additions and 31 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2024, 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
@ -93,6 +93,14 @@ class UnixFileDispatcherImpl extends FileDispatcher {
return size0(fd);
}
int available(FileDescriptor fd) throws IOException {
return available0(fd);
}
boolean isOther(FileDescriptor fd) throws IOException {
return isOther0(fd);
}
int lock(FileDescriptor fd, boolean blocking, long pos, long size,
boolean shared) throws IOException
{
@ -196,6 +204,10 @@ class UnixFileDispatcherImpl extends FileDispatcher {
static native long size0(FileDescriptor fd) throws IOException;
static native int available0(FileDescriptor fd) throws IOException;
static native boolean isOther0(FileDescriptor fd) throws IOException;
static native int lock0(FileDescriptor fd, boolean blocking, long pos,
long size, boolean shared) throws IOException;

View file

@ -23,6 +23,7 @@
* questions.
*/
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/uio.h>
#include <sys/stat.h>
@ -41,8 +42,10 @@
#include "nio.h"
#include "nio_util.h"
#include "sun_nio_ch_UnixFileDispatcherImpl.h"
#include "java_lang_Integer.h"
#include "java_lang_Long.h"
#include <assert.h>
#include "io_util_md.h"
#if defined(_AIX)
#define statvfs statvfs64
@ -178,6 +181,57 @@ Java_sun_nio_ch_UnixFileDispatcherImpl_size0(JNIEnv *env, jobject this, jobject
return fbuf.st_size;
}
JNIEXPORT jint JNICALL
Java_sun_nio_ch_UnixFileDispatcherImpl_available0(JNIEnv *env, jobject this, jobject fdo)
{
jint fd = fdval(env, fdo);
struct stat fbuf;
jlong size = -1;
if (fstat(fd, &fbuf) != -1) {
int mode = fbuf.st_mode;
if (S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) {
int n = ioctl(fd, FIONREAD, &n);
if (n >= 0) {
return n;
}
} else if (S_ISREG(mode)) {
size = fbuf.st_size;
}
}
jlong position;
if ((position = lseek(fd, 0, SEEK_CUR)) == -1) {
return 0;
}
if (size < position) {
if ((size = lseek(fd, 0, SEEK_END)) == -1)
return 0;
else if (lseek(fd, position, SEEK_SET) == -1)
return 0;
}
jlong available = size - position;
return available > java_lang_Integer_MAX_VALUE ?
java_lang_Integer_MAX_VALUE : (jint)available;
}
JNIEXPORT jboolean JNICALL
Java_sun_nio_ch_UnixFileDispatcherImpl_isOther0(JNIEnv *env, jobject this, jobject fdo)
{
jint fd = fdval(env, fdo);
struct stat fbuf;
if (fstat(fd, &fbuf) == -1)
handle(env, -1, "isOther failed");
if (S_ISREG(fbuf.st_mode) || S_ISDIR(fbuf.st_mode) || S_ISLNK(fbuf.st_mode))
return JNI_FALSE;
return JNI_TRUE;
}
JNIEXPORT jint JNICALL
Java_sun_nio_ch_UnixFileDispatcherImpl_lock0(JNIEnv *env, jobject this, jobject fdo,
jboolean block, jlong pos, jlong size,