Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/aix/native/libnio/fs/AixNativeDispatcher.c
41133 views
1
/*
2
* Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
3
* Copyright (c) 2013, 2019 SAP SE. All rights reserved.
4
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5
*
6
* This code is free software; you can redistribute it and/or modify it
7
* under the terms of the GNU General Public License version 2 only, as
8
* published by the Free Software Foundation. Oracle designates this
9
* particular file as subject to the "Classpath" exception as provided
10
* by Oracle in the LICENSE file that accompanied this code.
11
*
12
* This code is distributed in the hope that it will be useful, but WITHOUT
13
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15
* version 2 for more details (a copy is included in the LICENSE file that
16
* accompanied this code).
17
*
18
* You should have received a copy of the GNU General Public License version
19
* 2 along with this work; if not, write to the Free Software Foundation,
20
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21
*
22
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23
* or visit www.oracle.com if you need additional information or have any
24
* questions.
25
*/
26
27
#include <stdlib.h>
28
#include <string.h>
29
#include <errno.h>
30
#include <sys/types.h>
31
#include <sys/mntctl.h>
32
33
#include "jni.h"
34
#include "jni_util.h"
35
36
#include "sun_nio_fs_AixNativeDispatcher.h"
37
38
static jfieldID entry_name;
39
static jfieldID entry_dir;
40
static jfieldID entry_fstype;
41
static jfieldID entry_options;
42
43
static jclass entry_cls;
44
45
/**
46
* Call this to throw an internal UnixException when a system/library
47
* call fails
48
*/
49
static void throwUnixException(JNIEnv* env, int errnum) {
50
jobject x = JNU_NewObjectByName(env, "sun/nio/fs/UnixException",
51
"(I)V", errnum);
52
if (x != NULL) {
53
(*env)->Throw(env, x);
54
}
55
}
56
57
/**
58
* Initialization
59
*/
60
JNIEXPORT void JNICALL
61
Java_sun_nio_fs_AixNativeDispatcher_init(JNIEnv* env, jclass this)
62
{
63
jclass clazz;
64
65
clazz = (*env)->FindClass(env, "sun/nio/fs/UnixMountEntry");
66
CHECK_NULL(clazz);
67
entry_name = (*env)->GetFieldID(env, clazz, "name", "[B");
68
CHECK_NULL(entry_name);
69
entry_dir = (*env)->GetFieldID(env, clazz, "dir", "[B");
70
CHECK_NULL(entry_dir);
71
entry_fstype = (*env)->GetFieldID(env, clazz, "fstype", "[B");
72
CHECK_NULL(entry_fstype);
73
entry_options = (*env)->GetFieldID(env, clazz, "opts", "[B");
74
CHECK_NULL(entry_options);
75
entry_cls = (*env)->NewGlobalRef(env, clazz);
76
if (entry_cls == NULL) {
77
JNU_ThrowOutOfMemoryError(env, NULL);
78
return;
79
}
80
}
81
82
/**
83
* Special implementation of getextmntent (see SolarisNativeDispatcher.c)
84
* that returns all entries at once.
85
*/
86
JNIEXPORT jobjectArray JNICALL
87
Java_sun_nio_fs_AixNativeDispatcher_getmntctl(JNIEnv* env, jclass this)
88
{
89
int must_free_buf = 0;
90
char stack_buf[1024];
91
char* buffer = stack_buf;
92
size_t buffer_size = 1024;
93
int num_entries;
94
int i;
95
jobjectArray ret;
96
struct vmount * vm;
97
98
for (i = 0; i < 5; i++) {
99
num_entries = mntctl(MCTL_QUERY, buffer_size, buffer);
100
if (num_entries != 0) {
101
break;
102
}
103
if (must_free_buf) {
104
free(buffer);
105
}
106
buffer_size *= 8;
107
buffer = malloc(buffer_size);
108
must_free_buf = 1;
109
}
110
/* Treat zero entries like errors. */
111
if (num_entries <= 0) {
112
if (must_free_buf) {
113
free(buffer);
114
}
115
throwUnixException(env, errno);
116
return NULL;
117
}
118
ret = (*env)->NewObjectArray(env, num_entries, entry_cls, NULL);
119
if (ret == NULL) {
120
if (must_free_buf) {
121
free(buffer);
122
}
123
return NULL;
124
}
125
vm = (struct vmount*)buffer;
126
for (i = 0; i < num_entries; i++) {
127
jsize len;
128
jbyteArray bytes;
129
const char* fstype;
130
/* We set all relevant attributes so there is no need to call constructor. */
131
jobject entry = (*env)->AllocObject(env, entry_cls);
132
if (entry == NULL) {
133
if (must_free_buf) {
134
free(buffer);
135
}
136
return NULL;
137
}
138
(*env)->SetObjectArrayElement(env, ret, i, entry);
139
140
/* vm->vmt_data[...].vmt_size is 32 bit aligned and also includes NULL byte. */
141
/* Since we only need the characters, it is necessary to check string size manually. */
142
len = strlen((char*)vm + vm->vmt_data[VMT_OBJECT].vmt_off);
143
bytes = (*env)->NewByteArray(env, len);
144
if (bytes == NULL) {
145
if (must_free_buf) {
146
free(buffer);
147
}
148
return NULL;
149
}
150
(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)((char *)vm + vm->vmt_data[VMT_OBJECT].vmt_off));
151
(*env)->SetObjectField(env, entry, entry_name, bytes);
152
153
len = strlen((char*)vm + vm->vmt_data[VMT_STUB].vmt_off);
154
bytes = (*env)->NewByteArray(env, len);
155
if (bytes == NULL) {
156
if (must_free_buf) {
157
free(buffer);
158
}
159
return NULL;
160
}
161
(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)((char *)vm + vm->vmt_data[VMT_STUB].vmt_off));
162
(*env)->SetObjectField(env, entry, entry_dir, bytes);
163
164
switch (vm->vmt_gfstype) {
165
case MNT_J2:
166
fstype = "jfs2";
167
break;
168
case MNT_NAMEFS:
169
fstype = "namefs";
170
break;
171
case MNT_NFS:
172
fstype = "nfs";
173
break;
174
case MNT_JFS:
175
fstype = "jfs";
176
break;
177
case MNT_CDROM:
178
fstype = "cdrom";
179
break;
180
case MNT_PROCFS:
181
fstype = "procfs";
182
break;
183
case MNT_NFS3:
184
fstype = "nfs3";
185
break;
186
case MNT_AUTOFS:
187
fstype = "autofs";
188
break;
189
case MNT_UDF:
190
fstype = "udfs";
191
break;
192
case MNT_NFS4:
193
fstype = "nfs4";
194
break;
195
case MNT_CIFS:
196
fstype = "smbfs";
197
break;
198
default:
199
fstype = "unknown";
200
}
201
len = strlen(fstype);
202
bytes = (*env)->NewByteArray(env, len);
203
if (bytes == NULL) {
204
if (must_free_buf) {
205
free(buffer);
206
}
207
return NULL;
208
}
209
(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)fstype);
210
(*env)->SetObjectField(env, entry, entry_fstype, bytes);
211
212
len = strlen((char*)vm + vm->vmt_data[VMT_ARGS].vmt_off);
213
bytes = (*env)->NewByteArray(env, len);
214
if (bytes == NULL) {
215
if (must_free_buf) {
216
free(buffer);
217
}
218
return NULL;
219
}
220
(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)((char *)vm + vm->vmt_data[VMT_ARGS].vmt_off));
221
(*env)->SetObjectField(env, entry, entry_options, bytes);
222
223
/* goto the next vmount structure: */
224
vm = (struct vmount *)((char *)vm + vm->vmt_length);
225
}
226
227
if (must_free_buf) {
228
free(buffer);
229
}
230
return ret;
231
}
232
233