1 /*
2 * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
3 * Copyright 2013 SAP AG. 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 <errno.h>
29 #include <sys/types.h>
30 #include <sys/mntctl.h>
31
32 #include "jni.h"
33 #include "jni_util.h"
34
35 #include "sun_nio_fs_AixNativeDispatcher.h"
36
37 static jfieldID entry_name;
38 static jfieldID entry_dir;
39 static jfieldID entry_fstype;
40 static jfieldID entry_options;
41
42 static jclass entry_cls;
43
44 /**
45 * Call this to throw an internal UnixException when a system/library
46 * call fails
47 */
48 static void throwUnixException(JNIEnv* env, int errnum) {
49 jobject x = JNU_NewObjectByName(env, "sun/nio/fs/UnixException",
50 "(I)V", errnum);
51 if (x != NULL) {
52 (*env)->Throw(env, x);
53 }
54 }
55
56 /**
57 * Initialization
58 */
59 JNIEXPORT void JNICALL
60 Java_sun_nio_fs_AixNativeDispatcher_init(JNIEnv* env, jclass this)
61 {
62 jclass clazz;
63
64 clazz = (*env)->FindClass(env, "sun/nio/fs/UnixMountEntry");
65 CHECK_NULL(clazz);
66 entry_name = (*env)->GetFieldID(env, clazz, "name", "[B");
67 CHECK_NULL(entry_name);
68 entry_dir = (*env)->GetFieldID(env, clazz, "dir", "[B");
69 CHECK_NULL(entry_dir);
70 entry_fstype = (*env)->GetFieldID(env, clazz, "fstype", "[B");
71 CHECK_NULL(entry_fstype);
72 entry_options = (*env)->GetFieldID(env, clazz, "opts", "[B");
73 CHECK_NULL(entry_options);
74 entry_cls = (*env)->NewGlobalRef(env, clazz);
75 if (entry_cls == NULL) {
76 JNU_ThrowOutOfMemoryError(env, NULL);
77 return;
78 }
79 }
80
81 /**
82 * Special implementation of getextmntent (see SolarisNativeDispatcher.c)
83 * that returns all entries at once.
84 */
85 JNIEXPORT jobjectArray JNICALL
86 Java_sun_nio_fs_AixNativeDispatcher_getmntctl(JNIEnv* env, jclass this)
87 {
88 int must_free_buf = 0;
89 char stack_buf[1024];
90 char* buffer = stack_buf;
91 size_t buffer_size = 1024;
92 int num_entries;
93 int i;
94 jobjectArray ret;
95 struct vmount * vm;
96
97 for (i = 0; i < 5; i++) {
98 num_entries = mntctl(MCTL_QUERY, buffer_size, buffer);
210
211 len = strlen((char*)vm + vm->vmt_data[VMT_ARGS].vmt_off);
212 bytes = (*env)->NewByteArray(env, len);
213 if (bytes == NULL) {
214 if (must_free_buf) {
215 free(buffer);
216 }
217 return NULL;
218 }
219 (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)((char *)vm + vm->vmt_data[VMT_ARGS].vmt_off));
220 (*env)->SetObjectField(env, entry, entry_options, bytes);
221
222 /* goto the next vmount structure: */
223 vm = (struct vmount *)((char *)vm + vm->vmt_length);
224 }
225
226 if (must_free_buf) {
227 free(buffer);
228 }
229 return ret;
230 }
|
1 /*
2 * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
3 * Copyright 2013 SAP AG. 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 /*
28 * Portions Copyright (c) 2014 IBM Corporation
29 */
30
31 #include <stdlib.h>
32 #include <errno.h>
33 #include <sys/types.h>
34 #include <sys/mntctl.h>
35
36 #include "jni.h"
37 #include "jni_util.h"
38 #include "jvm.h"
39 #include "jlong.h"
40
41 #include <stdio.h>
42 #include <dlfcn.h>
43 #include <mntent.h>
44 #include <sys/vmount.h>
45 #include "net_util.h"
46
47 #include "sun_nio_fs_AixNativeDispatcher.h"
48
49 static jfieldID entry_name;
50 static jfieldID entry_dir;
51 static jfieldID entry_fstype;
52 static jfieldID entry_options;
53
54 static jclass entry_cls;
55
56 typedef size_t fgetxattr_func_t(int fd, const char* name, void* value, size_t size);
57 typedef int fsetxattr_func_t(int fd, const char* name, void* value, size_t size, int flags);
58 typedef int fremovexattr_func_t(int fd, const char* name);
59 typedef int flistxattr_func_t(int fd, char* list, size_t size);
60
61 fgetxattr_func_t* fgetxattr_func = NULL;
62 fsetxattr_func_t* fsetxattr_func = NULL;
63 fremovexattr_func_t* fremovexattr_func = NULL;
64 flistxattr_func_t* flistxattr_func = NULL;
65
66
67
68 /**
69 * Call this to throw an internal UnixException when a system/library
70 * call fails
71 */
72 static void throwUnixException(JNIEnv* env, int errnum) {
73 jobject x = JNU_NewObjectByName(env, "sun/nio/fs/UnixException",
74 "(I)V", errnum);
75 if (x != NULL) {
76 (*env)->Throw(env, x);
77 }
78 }
79
80 /**
81 * Initialization
82 */
83 JNIEXPORT void JNICALL
84 Java_sun_nio_fs_AixNativeDispatcher_init(JNIEnv* env, jclass this)
85 {
86 jint flags = 0;
87 jclass clazz;
88
89 clazz = (*env)->FindClass(env, "sun/nio/fs/UnixMountEntry");
90 CHECK_NULL(clazz);
91 entry_name = (*env)->GetFieldID(env, clazz, "name", "[B");
92 CHECK_NULL(entry_name);
93 entry_dir = (*env)->GetFieldID(env, clazz, "dir", "[B");
94 CHECK_NULL(entry_dir);
95 entry_fstype = (*env)->GetFieldID(env, clazz, "fstype", "[B");
96 CHECK_NULL(entry_fstype);
97 entry_options = (*env)->GetFieldID(env, clazz, "opts", "[B");
98 CHECK_NULL(entry_options);
99 entry_cls = (*env)->NewGlobalRef(env, clazz);
100 if (entry_cls == NULL) {
101 JNU_ThrowOutOfMemoryError(env, NULL);
102 return;
103 }
104
105 fgetxattr_func = (fgetxattr_func_t*)dlsym(RTLD_DEFAULT, "fgetxattr");
106 fsetxattr_func = (fsetxattr_func_t*)dlsym(RTLD_DEFAULT, "fsetxattr");
107 fremovexattr_func = (fremovexattr_func_t*)dlsym(RTLD_DEFAULT, "fremovexattr");
108 flistxattr_func = (flistxattr_func_t*)dlsym(RTLD_DEFAULT, "flistxattr");
109 }
110
111 /**
112 * Special implementation of getextmntent (see SolarisNativeDispatcher.c)
113 * that returns all entries at once.
114 */
115 JNIEXPORT jobjectArray JNICALL
116 Java_sun_nio_fs_AixNativeDispatcher_getmntctl(JNIEnv* env, jclass this)
117 {
118 int must_free_buf = 0;
119 char stack_buf[1024];
120 char* buffer = stack_buf;
121 size_t buffer_size = 1024;
122 int num_entries;
123 int i;
124 jobjectArray ret;
125 struct vmount * vm;
126
127 for (i = 0; i < 5; i++) {
128 num_entries = mntctl(MCTL_QUERY, buffer_size, buffer);
240
241 len = strlen((char*)vm + vm->vmt_data[VMT_ARGS].vmt_off);
242 bytes = (*env)->NewByteArray(env, len);
243 if (bytes == NULL) {
244 if (must_free_buf) {
245 free(buffer);
246 }
247 return NULL;
248 }
249 (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)((char *)vm + vm->vmt_data[VMT_ARGS].vmt_off));
250 (*env)->SetObjectField(env, entry, entry_options, bytes);
251
252 /* goto the next vmount structure: */
253 vm = (struct vmount *)((char *)vm + vm->vmt_length);
254 }
255
256 if (must_free_buf) {
257 free(buffer);
258 }
259 return ret;
260 }
261
262 JNIEXPORT jint JNICALL
263 Java_sun_nio_fs_AixNativeDispatcher_fgetxattr0(JNIEnv* env, jclass clazz,
264 jint fd, jlong nameAddress, jlong valueAddress, jint valueLen)
265 {
266 size_t res = -1;
267 const char* name = jlong_to_ptr(nameAddress);
268 void* value = jlong_to_ptr(valueAddress);
269
270 if (fgetxattr_func == NULL) {
271 errno = ENOTSUP;
272 } else {
273 /* EINTR not documented */
274 res = (*fgetxattr_func)(fd, name, value, valueLen);
275 }
276 if (res == (size_t)-1) {
277 throwUnixException(env, errno);
278 }
279 return (jint)res;
280 }
281
282 JNIEXPORT void JNICALL
283 Java_sun_nio_fs_AixNativeDispatcher_fsetxattr0(JNIEnv* env, jclass clazz,
284 jint fd, jlong nameAddress, jlong valueAddress, jint valueLen)
285 {
286 int res = -1;
287 const char* name = jlong_to_ptr(nameAddress);
288 void* value = jlong_to_ptr(valueAddress);
289
290 if (fsetxattr_func == NULL) {
291 errno = ENOTSUP;
292 } else {
293 /* EINTR not documented */
294 res = (*fsetxattr_func)(fd, name, value, valueLen, 0);
295 }
296 if (res == -1) {
297 throwUnixException(env, errno);
298 }
299 }
300
301 JNIEXPORT void JNICALL
302 Java_sun_nio_fs_AixNativeDispatcher_fremovexattr0(JNIEnv* env, jclass clazz,
303 jint fd, jlong nameAddress)
304 {
305 int res = -1;
306 const char* name = jlong_to_ptr(nameAddress);
307
308 if (fremovexattr_func == NULL) {
309 errno = ENOTSUP;
310 } else {
311 /* EINTR not documented */
312 res = (*fremovexattr_func)(fd, name);
313 }
314 if (res == -1) {
315 throwUnixException(env, errno);
316 }
317 }
318
319 JNIEXPORT jint JNICALL
320 Java_sun_nio_fs_AixNativeDispatcher_flistxattr(JNIEnv* env, jclass clazz,
321 jint fd, jlong listAddress, jint size)
322 {
323 size_t res = -1;
324 char* list = jlong_to_ptr(listAddress);
325
326 if (flistxattr_func == NULL) {
327 errno = ENOTSUP;
328 } else {
329 /* EINTR not documented */
330 res = (*flistxattr_func)(fd, list, (size_t)size);
331 }
332 if (res == (size_t)-1) {
333 throwUnixException(env, errno);
334 }
335 return (jint)res;
336 }
337
338 JNIEXPORT jint JNICALL
339 Java_sun_nio_fs_AixNativeDispatcher_queryMountEntrySize(JNIEnv* env, jclass this)
340 {
341 int size;
342
343 if (mntctl(MCTL_QUERY, sizeof(size), (char *)&size) != 0) {
344 return 0;
345 }
346 return size;
347 }
348
349 JNIEXPORT void JNICALL
350 Java_sun_nio_fs_AixNativeDispatcher_getAixMountEntries(JNIEnv* env, jclass this, jobject entries, jlong bufferAddress, jint size)
351 {
352 jmethodID addMethod, constructor;
353 jclass arrayListClass, unixMountEntryClass;
354 int entryNum;
355 char *buffer = NULL;
356 char *ptr = NULL;
357 char *name = NULL;
358 char *type = NULL;
359 char *path = NULL;
360 char *opts = NULL;
361 int len, count;
362 jboolean readOnly = JNI_FALSE;
363 jobject mountEntry;
364 jbyteArray bytes;
365 struct vmount * vmountPtr = NULL;
366 jfieldID entry_name;
367 jfieldID entry_dir;
368 jfieldID entry_fstype;
369 jfieldID entry_options;
370
371 arrayListClass = (*env)->FindClass(env, "java/util/ArrayList");
372 if ((*env)->ExceptionOccurred(env)) {
373 return;
374 }
375
376 addMethod = (*env)->GetMethodID(env, arrayListClass, "add", "(Ljava/lang/Object;)Z");
377 if ((*env)->ExceptionOccurred(env)) {
378 return;
379 }
380
381 unixMountEntryClass = (*env)->FindClass(env, "sun/nio/fs/UnixMountEntry");
382 if ((*env)->ExceptionOccurred(env)) {
383 return;
384 }
385
386 constructor = (*env)->GetMethodID(env, unixMountEntryClass, "<init>", "()V");
387 if ((*env)->ExceptionOccurred(env)) {
388 return;
389 }
390
391 buffer = (char *)jlong_to_ptr(bufferAddress);
392
393 entryNum = mntctl(MCTL_QUERY, size, buffer);
394
395 if (entryNum <= 0) {
396 return;
397 }
398
399 entry_name = (*env)->GetFieldID(env, unixMountEntryClass, "name", "[B");
400 entry_dir = (*env)->GetFieldID(env, unixMountEntryClass, "dir", "[B");
401 entry_fstype = (*env)->GetFieldID(env, unixMountEntryClass, "fstype", "[B");
402 entry_options = (*env)->GetFieldID(env, unixMountEntryClass, "opts", "[B");
403
404 ptr = buffer;
405 for (count = 0; count < entryNum; count++, ptr += vmountPtr->vmt_length) {
406 vmountPtr = (struct vmount *)ptr;
407 switch (vmountPtr->vmt_gfstype) {
408 case MNT_JFS:
409 type = "jfs";
410 break;
411 case MNT_J2:
412 type = "jfs2";
413 break;
414 case MNT_NFS:
415 type = "nfs";
416 break;
417 case MNT_CDROM:
418 type = "cdrom";
419 break;
420 case MNT_PROCFS:
421 type = "procfs";
422 break;
423 default:
424 type = "unknown";
425 }
426 if (vmountPtr->vmt_flags & MNT_READONLY) {
427 readOnly = JNI_TRUE;
428 } else {
429 readOnly = JNI_FALSE;
430 }
431
432 name = (char *)(ptr + vmountPtr->vmt_data[VMT_OBJECT].vmt_off);
433 path = (char *)(ptr + vmountPtr->vmt_data[VMT_STUB].vmt_off);
434
435 mountEntry = (*env)->NewObject(env, unixMountEntryClass, constructor);
436
437 // name
438 len = strlen(name);
439 bytes = (*env)->NewByteArray(env, len);
440 if (bytes == NULL) {
441 break;
442 }
443 (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)name);
444 (*env)->SetObjectField(env, mountEntry, entry_name, bytes);
445
446 // dir
447 len = strlen(path);
448 bytes = (*env)->NewByteArray(env, len);
449 if (bytes == NULL) {
450 break;
451 }
452 (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)path);
453 (*env)->SetObjectField(env, mountEntry, entry_dir, bytes);
454
455 // filetype
456 len = strlen(type);
457 bytes = (*env)->NewByteArray(env, len);
458 if (bytes == NULL) {
459 break;
460 }
461 (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)type);
462 (*env)->SetObjectField(env, mountEntry, entry_fstype, bytes);
463
464 // opts
465 if (readOnly) {
466 opts = "ro";
467 } else {
468 opts = "";
469 }
470 len = strlen(opts);
471 bytes = (*env)->NewByteArray(env, len);
472 if (bytes == NULL) {
473 break;
474 }
475 (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)opts);
476 (*env)->SetObjectField(env, mountEntry, entry_options, bytes);
477
478 if ((*env)->ExceptionOccurred(env)) {
479 (*env)->ExceptionDescribe(env);
480 goto error;
481 }
482 (*env)->CallBooleanMethod(env, entries, addMethod, mountEntry);
483 if ((*env)->ExceptionOccurred(env)) {
484 (*env)->ExceptionDescribe(env);
485 goto error;
486 }
487 }
488
489 error:
490 return;
491 }
|