Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/native/sun/nio/fs/LinuxNativeDispatcher.c
32288 views
1
/*
2
* Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
#include "jni.h"
27
#include "jni_util.h"
28
#include "jvm.h"
29
#include "jlong.h"
30
31
#include <stdio.h>
32
#include <string.h>
33
#include <dlfcn.h>
34
#include <errno.h>
35
#include <mntent.h>
36
37
#include "sun_nio_fs_LinuxNativeDispatcher.h"
38
39
typedef size_t fgetxattr_func(int fd, const char* name, void* value, size_t size);
40
typedef int fsetxattr_func(int fd, const char* name, void* value, size_t size, int flags);
41
typedef int fremovexattr_func(int fd, const char* name);
42
typedef int flistxattr_func(int fd, char* list, size_t size);
43
44
fgetxattr_func* my_fgetxattr_func = NULL;
45
fsetxattr_func* my_fsetxattr_func = NULL;
46
fremovexattr_func* my_fremovexattr_func = NULL;
47
flistxattr_func* my_flistxattr_func = NULL;
48
49
static jfieldID entry_name;
50
static jfieldID entry_dir;
51
static jfieldID entry_fstype;
52
static jfieldID entry_options;
53
54
static void throwUnixException(JNIEnv* env, int errnum) {
55
jobject x = JNU_NewObjectByName(env, "sun/nio/fs/UnixException",
56
"(I)V", errnum);
57
if (x != NULL) {
58
(*env)->Throw(env, x);
59
}
60
}
61
62
JNIEXPORT void JNICALL
63
Java_sun_nio_fs_LinuxNativeDispatcher_init(JNIEnv *env, jclass clazz)
64
{
65
my_fgetxattr_func = (fgetxattr_func*)dlsym(RTLD_DEFAULT, "fgetxattr");
66
my_fsetxattr_func = (fsetxattr_func*)dlsym(RTLD_DEFAULT, "fsetxattr");
67
my_fremovexattr_func = (fremovexattr_func*)dlsym(RTLD_DEFAULT, "fremovexattr");
68
my_flistxattr_func = (flistxattr_func*)dlsym(RTLD_DEFAULT, "flistxattr");
69
70
clazz = (*env)->FindClass(env, "sun/nio/fs/UnixMountEntry");
71
CHECK_NULL(clazz);
72
entry_name = (*env)->GetFieldID(env, clazz, "name", "[B");
73
CHECK_NULL(entry_name);
74
entry_dir = (*env)->GetFieldID(env, clazz, "dir", "[B");
75
CHECK_NULL(entry_dir);
76
entry_fstype = (*env)->GetFieldID(env, clazz, "fstype", "[B");
77
CHECK_NULL(entry_fstype);
78
entry_options = (*env)->GetFieldID(env, clazz, "opts", "[B");
79
CHECK_NULL(entry_options);
80
}
81
82
JNIEXPORT jint JNICALL
83
Java_sun_nio_fs_LinuxNativeDispatcher_fgetxattr0(JNIEnv* env, jclass clazz,
84
jint fd, jlong nameAddress, jlong valueAddress, jint valueLen)
85
{
86
size_t res = -1;
87
const char* name = jlong_to_ptr(nameAddress);
88
void* value = jlong_to_ptr(valueAddress);
89
90
if (my_fgetxattr_func == NULL) {
91
errno = ENOTSUP;
92
} else {
93
/* EINTR not documented */
94
res = (*my_fgetxattr_func)(fd, name, value, valueLen);
95
}
96
if (res == (size_t)-1)
97
throwUnixException(env, errno);
98
return (jint)res;
99
}
100
101
JNIEXPORT void JNICALL
102
Java_sun_nio_fs_LinuxNativeDispatcher_fsetxattr0(JNIEnv* env, jclass clazz,
103
jint fd, jlong nameAddress, jlong valueAddress, jint valueLen)
104
{
105
int res = -1;
106
const char* name = jlong_to_ptr(nameAddress);
107
void* value = jlong_to_ptr(valueAddress);
108
109
if (my_fsetxattr_func == NULL) {
110
errno = ENOTSUP;
111
} else {
112
/* EINTR not documented */
113
res = (*my_fsetxattr_func)(fd, name, value, valueLen, 0);
114
}
115
if (res == -1)
116
throwUnixException(env, errno);
117
}
118
119
JNIEXPORT void JNICALL
120
Java_sun_nio_fs_LinuxNativeDispatcher_fremovexattr0(JNIEnv* env, jclass clazz,
121
jint fd, jlong nameAddress)
122
{
123
int res = -1;
124
const char* name = jlong_to_ptr(nameAddress);
125
126
if (my_fremovexattr_func == NULL) {
127
errno = ENOTSUP;
128
} else {
129
/* EINTR not documented */
130
res = (*my_fremovexattr_func)(fd, name);
131
}
132
if (res == -1)
133
throwUnixException(env, errno);
134
}
135
136
JNIEXPORT jint JNICALL
137
Java_sun_nio_fs_LinuxNativeDispatcher_flistxattr(JNIEnv* env, jclass clazz,
138
jint fd, jlong listAddress, jint size)
139
{
140
size_t res = -1;
141
char* list = jlong_to_ptr(listAddress);
142
143
if (my_flistxattr_func == NULL) {
144
errno = ENOTSUP;
145
} else {
146
/* EINTR not documented */
147
res = (*my_flistxattr_func)(fd, list, (size_t)size);
148
}
149
if (res == (size_t)-1)
150
throwUnixException(env, errno);
151
return (jint)res;
152
}
153
154
JNIEXPORT jlong JNICALL
155
Java_sun_nio_fs_LinuxNativeDispatcher_setmntent0(JNIEnv* env, jclass this, jlong pathAddress,
156
jlong modeAddress)
157
{
158
FILE* fp = NULL;
159
const char* path = (const char*)jlong_to_ptr(pathAddress);
160
const char* mode = (const char*)jlong_to_ptr(modeAddress);
161
162
do {
163
fp = setmntent(path, mode);
164
} while (fp == NULL && errno == EINTR);
165
if (fp == NULL) {
166
throwUnixException(env, errno);
167
}
168
return ptr_to_jlong(fp);
169
}
170
171
JNIEXPORT jint JNICALL
172
Java_sun_nio_fs_LinuxNativeDispatcher_getmntent0(JNIEnv* env, jclass this,
173
jlong value, jobject entry, jlong buffer, jint bufLen)
174
{
175
struct mntent ent;
176
char * buf = (char*)jlong_to_ptr(buffer);
177
struct mntent* m;
178
FILE* fp = jlong_to_ptr(value);
179
jsize len;
180
jbyteArray bytes;
181
char* name;
182
char* dir;
183
char* fstype;
184
char* options;
185
186
m = getmntent_r(fp, &ent, buf, (int)bufLen);
187
if (m == NULL)
188
return -1;
189
name = m->mnt_fsname;
190
dir = m->mnt_dir;
191
fstype = m->mnt_type;
192
options = m->mnt_opts;
193
194
len = strlen(name);
195
bytes = (*env)->NewByteArray(env, len);
196
if (bytes == NULL)
197
return -1;
198
(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)name);
199
(*env)->SetObjectField(env, entry, entry_name, bytes);
200
201
len = strlen(dir);
202
bytes = (*env)->NewByteArray(env, len);
203
if (bytes == NULL)
204
return -1;
205
(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)dir);
206
(*env)->SetObjectField(env, entry, entry_dir, bytes);
207
208
len = strlen(fstype);
209
bytes = (*env)->NewByteArray(env, len);
210
if (bytes == NULL)
211
return -1;
212
(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)fstype);
213
(*env)->SetObjectField(env, entry, entry_fstype, bytes);
214
215
len = strlen(options);
216
bytes = (*env)->NewByteArray(env, len);
217
if (bytes == NULL)
218
return -1;
219
(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)options);
220
(*env)->SetObjectField(env, entry, entry_options, bytes);
221
222
return 0;
223
}
224
225
JNIEXPORT void JNICALL
226
Java_sun_nio_fs_LinuxNativeDispatcher_endmntent(JNIEnv* env, jclass this, jlong stream)
227
{
228
FILE* fp = jlong_to_ptr(stream);
229
/* FIXME - man page doesn't explain how errors are returned */
230
endmntent(fp);
231
}
232
233
/**
234
* This function returns line length without NUL terminator or -1 on EOF.
235
* Since getline is missing on Solaris10 this function was moved from
236
* UnixNativeDispatcher to LinuxNativeDispatcher as part of backport form jdk11.
237
*/
238
JNIEXPORT jint JNICALL
239
Java_sun_nio_fs_LinuxNativeDispatcher_getlinelen(JNIEnv* env, jclass this, jlong stream)
240
{
241
FILE* fp = jlong_to_ptr(stream);
242
size_t lineSize = 0;
243
char * lineBuffer = NULL;
244
int saved_errno;
245
246
ssize_t res = getline(&lineBuffer, &lineSize, fp);
247
saved_errno = errno;
248
249
/* Should free lineBuffer no matter result, according to man page */
250
if (lineBuffer != NULL)
251
free(lineBuffer);
252
253
if (feof(fp))
254
return -1;
255
256
/* On successfull return res >= 0, otherwise res is -1 */
257
if (res == -1)
258
throwUnixException(env, saved_errno);
259
260
if (res > INT_MAX)
261
throwUnixException(env, EOVERFLOW);
262
263
return (jint)res;
264
}
265
266
267