1 /*
2  *  Licensed to the Apache Software Foundation (ASF) under one or more
3  *  contributor license agreements.  See the NOTICE file distributed with
4  *  this work for additional information regarding copyright ownership.
5  *  The ASF licenses this file to You under the Apache License, Version 2.0
6  *  (the "License"); you may not use this file except in compliance with
7  *  the License.  You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  */
17 
18 #include <jni.h>
19 #include "file_descriptor.h"
20 #include "org_apache_hadoop.h"
21 
22 // class of java.io.FileDescriptor
23 static jclass fd_class;
24 // the internal field for the integer fd
25 static jfieldID fd_descriptor;
26 // the no-argument constructor
27 static jmethodID fd_constructor;
28 
29 #ifdef WINDOWS
30 // the internal field for the long handle
31 static jfieldID fd_handle;
32 #endif
33 
fd_init(JNIEnv * env)34 void fd_init(JNIEnv* env)
35 {
36   if (fd_class != NULL) return; // already initted
37 
38   fd_class = (*env)->FindClass(env, "java/io/FileDescriptor");
39   PASS_EXCEPTIONS(env);
40   fd_class = (*env)->NewGlobalRef(env, fd_class);
41 
42   fd_descriptor = (*env)->GetFieldID(env, fd_class, "fd", "I");
43   PASS_EXCEPTIONS(env);
44 
45 #ifdef WINDOWS
46   fd_handle = (*env)->GetFieldID(env, fd_class, "handle", "J");
47   PASS_EXCEPTIONS(env);
48 #endif
49 
50   fd_constructor = (*env)->GetMethodID(env, fd_class, "<init>", "()V");
51 }
52 
fd_deinit(JNIEnv * env)53 void fd_deinit(JNIEnv *env) {
54   if (fd_class != NULL) {
55     (*env)->DeleteGlobalRef(env, fd_class);
56     fd_class = NULL;
57   }
58   fd_descriptor = NULL;
59 #ifdef WINDOWS
60   fd_handle = NULL;
61 #endif
62   fd_constructor = NULL;
63 }
64 
65 #ifdef UNIX
66 /*
67  * Given an instance 'obj' of java.io.FileDescriptor, return the
68  * underlying fd, or throw if unavailable
69  */
fd_get(JNIEnv * env,jobject obj)70 int fd_get(JNIEnv* env, jobject obj) {
71   if (obj == NULL) {
72     THROW(env, "java/lang/NullPointerException",
73           "FileDescriptor object is null");
74     return -1;
75   }
76   return (*env)->GetIntField(env, obj, fd_descriptor);
77 }
78 
79 /*
80  * Create a FileDescriptor object corresponding to the given int fd
81  */
fd_create(JNIEnv * env,int fd)82 jobject fd_create(JNIEnv *env, int fd) {
83   jobject obj = (*env)->NewObject(env, fd_class, fd_constructor);
84   PASS_EXCEPTIONS_RET(env, NULL);
85 
86   (*env)->SetIntField(env, obj, fd_descriptor, fd);
87   return obj;
88 }
89 #endif
90 
91 #ifdef WINDOWS
92 /*
93  * Given an instance 'obj' of java.io.FileDescriptor, return the
94  * underlying fd, or throw if unavailable
95  */
fd_get(JNIEnv * env,jobject obj)96 long fd_get(JNIEnv* env, jobject obj) {
97   if (obj == NULL) {
98     THROW(env, "java/lang/NullPointerException",
99           "FileDescriptor object is null");
100     return -1;
101   }
102   return (long) (*env)->GetLongField(env, obj, fd_handle);
103 }
104 
105 /*
106  * Create a FileDescriptor object corresponding to the given int fd
107  */
fd_create(JNIEnv * env,long fd)108 jobject fd_create(JNIEnv *env, long fd) {
109   jobject obj = (*env)->NewObject(env, fd_class, fd_constructor);
110   PASS_EXCEPTIONS_RET(env, (jobject) NULL);
111 
112   (*env)->SetLongField(env, obj, fd_handle, fd);
113   return obj;
114 }
115 #endif
116