1 | /* |
2 | * Copyright (c) 1997, 2018, 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 | |
29 | extern jfieldID IO_fd_fdID; |
30 | extern jfieldID IO_handle_fdID; |
31 | extern jfieldID IO_append_fdID; |
32 | |
33 | #ifdef _ALLBSD_SOURCE |
34 | #include <fcntl.h> |
35 | #ifndef O_SYNC |
36 | #define O_SYNC O_FSYNC |
37 | #endif |
38 | #ifndef O_DSYNC |
39 | #define O_DSYNC O_FSYNC |
40 | #endif |
41 | #elif !defined(O_DSYNC) || !defined(O_SYNC) |
42 | #define O_SYNC (0x0800) |
43 | #define O_DSYNC (0x2000) |
44 | #endif |
45 | |
46 | /* |
47 | * IO helper functions |
48 | */ |
49 | |
50 | jint readSingle(JNIEnv *env, jobject this, jfieldID fid); |
51 | jint readBytes(JNIEnv *env, jobject this, jbyteArray bytes, jint off, |
52 | jint len, jfieldID fid); |
53 | void writeSingle(JNIEnv *env, jobject this, jint byte, jboolean append, jfieldID fid); |
54 | void writeBytes(JNIEnv *env, jobject this, jbyteArray bytes, jint off, |
55 | jint len, jboolean append, jfieldID fid); |
56 | void fileOpen(JNIEnv *env, jobject this, jstring path, jfieldID fid, int flags); |
57 | void throwFileNotFoundException(JNIEnv *env, jstring path); |
58 | |
59 | /* |
60 | * Macros for managing platform strings. The typical usage pattern is: |
61 | * |
62 | * WITH_PLATFORM_STRING(env, string, var) { |
63 | * doSomethingWith(var); |
64 | * } END_PLATFORM_STRING(env, var); |
65 | * |
66 | * where env is the prevailing JNIEnv, |
67 | * string is a JNI reference to a java.lang.String object, and |
68 | * var is the char * variable that will point to the string, |
69 | * after being converted into the platform encoding. |
70 | * |
71 | * The related macro WITH_FIELD_PLATFORM_STRING first extracts the string from |
72 | * a given field of a given object: |
73 | * |
74 | * WITH_FIELD_PLATFORM_STRING(env, object, id, var) { |
75 | * doSomethingWith(var); |
76 | * } END_PLATFORM_STRING(env, var); |
77 | * |
78 | * where env is the prevailing JNIEnv, |
79 | * object is a jobject, |
80 | * id is the field ID of the String field to be extracted, and |
81 | * var is the char * variable that will point to the string. |
82 | * |
83 | * Uses of these macros may be nested as long as each WITH_.._STRING macro |
84 | * declares a unique variable. |
85 | */ |
86 | |
87 | #define WITH_PLATFORM_STRING(env, strexp, var) \ |
88 | if (1) { \ |
89 | const char *var; \ |
90 | jstring _##var##str = (strexp); \ |
91 | if (_##var##str == NULL) { \ |
92 | JNU_ThrowNullPointerException((env), NULL); \ |
93 | goto _##var##end; \ |
94 | } \ |
95 | var = JNU_GetStringPlatformChars((env), _##var##str, NULL); \ |
96 | if (var == NULL) goto _##var##end; |
97 | |
98 | #define WITH_FIELD_PLATFORM_STRING(env, object, id, var) \ |
99 | WITH_PLATFORM_STRING(env, \ |
100 | ((object == NULL) \ |
101 | ? NULL \ |
102 | : (*(env))->GetObjectField((env), (object), (id))), \ |
103 | var) |
104 | |
105 | #define END_PLATFORM_STRING(env, var) \ |
106 | JNU_ReleaseStringPlatformChars(env, _##var##str, var); \ |
107 | _##var##end: ; \ |
108 | } else ((void)NULL) |
109 | |
110 | |
111 | /* Macros for transforming Java Strings into native Unicode strings. |
112 | * Works analogously to WITH_PLATFORM_STRING. |
113 | */ |
114 | |
115 | #define WITH_UNICODE_STRING(env, strexp, var) \ |
116 | if (1) { \ |
117 | const jchar *var; \ |
118 | jstring _##var##str = (strexp); \ |
119 | if (_##var##str == NULL) { \ |
120 | JNU_ThrowNullPointerException((env), NULL); \ |
121 | goto _##var##end; \ |
122 | } \ |
123 | var = (*(env))->GetStringChars((env), _##var##str, NULL); \ |
124 | if (var == NULL) goto _##var##end; |
125 | |
126 | #define END_UNICODE_STRING(env, var) \ |
127 | (*(env))->ReleaseStringChars(env, _##var##str, var); \ |
128 | _##var##end: ; \ |
129 | } else ((void)NULL) |
130 | |