| OLD | NEW |
| 1 /* |
| 2 * Copyright 2016 The Netty Project |
| 3 * |
| 4 * The Netty Project licenses this file to you under the Apache License, |
| 5 * version 2.0 (the "License"); you may not use this file except in compliance |
| 6 * with the License. You may obtain a copy of the License at: |
| 7 * |
| 8 * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 * |
| 10 * Unless required by applicable law or agreed to in writing, software |
| 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| 13 * License for the specific language governing permissions and limitations |
| 14 * under the License. |
| 15 */ |
| 1 /* Licensed to the Apache Software Foundation (ASF) under one or more | 16 /* Licensed to the Apache Software Foundation (ASF) under one or more |
| 2 * contributor license agreements. See the NOTICE file distributed with | 17 * contributor license agreements. See the NOTICE file distributed with |
| 3 * this work for additional information regarding copyright ownership. | 18 * this work for additional information regarding copyright ownership. |
| 4 * The ASF licenses this file to You under the Apache License, Version 2.0 | 19 * The ASF licenses this file to You under the Apache License, Version 2.0 |
| 5 * (the "License"); you may not use this file except in compliance with | 20 * (the "License"); you may not use this file except in compliance with |
| 6 * the License. You may obtain a copy of the License at | 21 * the License. You may obtain a copy of the License at |
| 7 * | 22 * |
| 8 * http://www.apache.org/licenses/LICENSE-2.0 | 23 * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 * | 24 * |
| 10 * Unless required by applicable law or agreed to in writing, software | 25 * Unless required by applicable law or agreed to in writing, software |
| 11 * distributed under the License is distributed on an "AS IS" BASIS, | 26 * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 27 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 * See the License for the specific language governing permissions and | 28 * See the License for the specific language governing permissions and |
| 14 * limitations under the License. | 29 * limitations under the License. |
| 15 */ | 30 */ |
| 16 | 31 |
| 17 /* | 32 #include "tcn.h" |
| 18 * | 33 #include "apr_strings.h" |
| 19 * @author Mladen Turk | |
| 20 * @version $Id: error.c 1442587 2013-02-05 13:49:48Z rjung $ | |
| 21 */ | |
| 22 | 34 |
| 23 #include "tcn.h" | |
| 24 | |
| 25 static const char *tcn_errors[] = { | |
| 26 "Unknown user error", | |
| 27 /* TCN_TIMEUP */ "Operation timed out", | |
| 28 /* TCN_EAGAIN */ "There is no data ready", | |
| 29 /* TCN_EINTR */ "Interrupted system call", | |
| 30 /* TCN_EINPROGRESS */ "Operation in progress", | |
| 31 /* TCN_ETIMEDOUT */ "Connection timed out", | |
| 32 NULL | |
| 33 }; | |
| 34 | |
| 35 /* Merge IS_ETIMEDOUT with APR_TIMEUP | |
| 36 */ | |
| 37 #define TCN_STATUS_IS_ETIMEDOUT(x) (APR_STATUS_IS_ETIMEDOUT((x)) || ((x) == APR_
TIMEUP)) | |
| 38 /* | 35 /* |
| 39 * Convenience function to help throw an java.lang.Exception. | 36 * Convenience function to help throw an java.lang.Exception. |
| 40 */ | 37 */ |
| 41 void tcn_ThrowException(JNIEnv *env, const char *msg) | 38 void tcn_ThrowException(JNIEnv *env, const char *msg) |
| 42 { | 39 { |
| 43 jclass javaExceptionClass; | 40 jclass javaExceptionClass; |
| 44 | 41 |
| 45 javaExceptionClass = (*env)->FindClass(env, "java/lang/Exception"); | 42 javaExceptionClass = (*env)->FindClass(env, "java/lang/Exception"); |
| 46 if (javaExceptionClass == NULL) { | 43 if (javaExceptionClass == NULL) { |
| 47 fprintf(stderr, "Cannot find java/lang/Exception class\n"); | 44 fprintf(stderr, "Cannot find java/lang/Exception class\n"); |
| 48 return; | 45 return; |
| 49 } | 46 } |
| 50 (*env)->ThrowNew(env, javaExceptionClass, msg); | 47 (*env)->ThrowNew(env, javaExceptionClass, msg); |
| 51 (*env)->DeleteLocalRef(env, javaExceptionClass); | 48 (*env)->DeleteLocalRef(env, javaExceptionClass); |
| 52 | 49 |
| 53 } | 50 } |
| 54 | 51 |
| 55 void tcn_ThrowMemoryException(JNIEnv *env, const char *file, int line, const cha
r *msg) | |
| 56 { | |
| 57 jclass javaExceptionClass; | |
| 58 javaExceptionClass = (*env)->FindClass(env, "java/lang/OutOfMemoryError"); | |
| 59 if (javaExceptionClass == NULL) { | |
| 60 fprintf(stderr, "Cannot find java/lang/OutOfMemoryError\n"); | |
| 61 return; | |
| 62 } | |
| 63 | |
| 64 if (file) { | |
| 65 char fmt[TCN_BUFFER_SZ]; | |
| 66 char *f = (char *)(file + strlen(file) - 1); | |
| 67 while (f != file && '\\' != *f && '/' != *f) { | |
| 68 f--; | |
| 69 } | |
| 70 if (f != file) { | |
| 71 f++; | |
| 72 } | |
| 73 sprintf(fmt, "%s for [%04d@%s]", msg, line, f); | |
| 74 (*env)->ThrowNew(env, javaExceptionClass, &fmt[0]); | |
| 75 } | |
| 76 else | |
| 77 (*env)->ThrowNew(env, javaExceptionClass, msg); | |
| 78 (*env)->DeleteLocalRef(env, javaExceptionClass); | |
| 79 | |
| 80 } | |
| 81 | |
| 82 | |
| 83 void tcn_Throw(JNIEnv *env, const char *fmt, ...) | 52 void tcn_Throw(JNIEnv *env, const char *fmt, ...) |
| 84 { | 53 { |
| 85 char msg[TCN_BUFFER_SZ] = {'\0'}; | 54 char msg[TCN_BUFFER_SZ] = {'\0'}; |
| 86 va_list ap; | 55 va_list ap; |
| 87 | 56 |
| 88 va_start(ap, fmt); | 57 va_start(ap, fmt); |
| 89 apr_vsnprintf(msg, TCN_BUFFER_SZ, fmt, ap); | 58 apr_vsnprintf(msg, TCN_BUFFER_SZ, fmt, ap); |
| 90 tcn_ThrowException(env, msg); | 59 tcn_ThrowException(env, msg); |
| 91 va_end(ap); | 60 va_end(ap); |
| 92 } | 61 } |
| 93 | 62 |
| 94 /* | |
| 95 * Convenience function to help throw an APR Exception | |
| 96 * from native error code. | |
| 97 */ | |
| 98 void tcn_ThrowAPRException(JNIEnv *e, apr_status_t err) | 63 void tcn_ThrowAPRException(JNIEnv *e, apr_status_t err) |
| 99 { | 64 { |
| 100 jclass aprErrorClass; | |
| 101 jmethodID constructorID = 0; | |
| 102 jobject throwObj; | |
| 103 jstring jdescription; | |
| 104 char serr[512] = {0}; | 65 char serr[512] = {0}; |
| 105 | 66 |
| 106 aprErrorClass = (*e)->FindClass(e, TCN_ERROR_CLASS); | |
| 107 if (aprErrorClass == NULL) { | |
| 108 fprintf(stderr, "Cannot find " TCN_ERROR_CLASS " class\n"); | |
| 109 return; | |
| 110 } | |
| 111 | |
| 112 /* Find the constructor ID */ | |
| 113 constructorID = (*e)->GetMethodID(e, aprErrorClass, | |
| 114 "<init>", | |
| 115 "(ILjava/lang/String;)V"); | |
| 116 if (constructorID == NULL) { | |
| 117 fprintf(stderr, | |
| 118 "Cannot find constructor for " TCN_ERROR_CLASS " class\n"); | |
| 119 goto cleanup; | |
| 120 } | |
| 121 | |
| 122 apr_strerror(err, serr, 512); | 67 apr_strerror(err, serr, 512); |
| 123 /* Obtain the string objects */ | 68 tcn_ThrowException(e, serr); |
| 124 jdescription = AJP_TO_JSTRING(serr); | |
| 125 if (jdescription == NULL) { | |
| 126 fprintf(stderr, | |
| 127 "Cannot allocate description for " TCN_ERROR_CLASS " class\n"); | |
| 128 goto cleanup; | |
| 129 } | |
| 130 /* Create the APR Error object */ | |
| 131 throwObj = (*e)->NewObject(e, aprErrorClass, constructorID, | |
| 132 (jint)err, jdescription); | |
| 133 if (throwObj == NULL) { | |
| 134 fprintf(stderr, | |
| 135 "Cannot allocate new " TCN_ERROR_CLASS " object\n"); | |
| 136 goto cleanup; | |
| 137 } | |
| 138 | |
| 139 (*e)->Throw(e, throwObj); | |
| 140 cleanup: | |
| 141 (*e)->DeleteLocalRef(e, aprErrorClass); | |
| 142 } | 69 } |
| 143 | |
| 144 | |
| 145 TCN_IMPLEMENT_CALL(jint, Error, osError)(TCN_STDARGS) | |
| 146 { | |
| 147 UNREFERENCED_STDARGS; | |
| 148 return (jint)apr_get_os_error(); | |
| 149 } | |
| 150 | |
| 151 TCN_IMPLEMENT_CALL(jint, Error, netosError)(TCN_STDARGS) | |
| 152 { | |
| 153 UNREFERENCED_STDARGS; | |
| 154 return (jint)apr_get_netos_error(); | |
| 155 } | |
| 156 | |
| 157 TCN_IMPLEMENT_CALL(jstring, Error, strerror)(TCN_STDARGS, jint err) | |
| 158 { | |
| 159 char serr[512] = {0}; | |
| 160 jstring jerr; | |
| 161 | |
| 162 UNREFERENCED(o); | |
| 163 if (err >= TCN_TIMEUP && err <= TCN_ETIMEDOUT) { | |
| 164 err -= TCN_TIMEUP; | |
| 165 jerr = AJP_TO_JSTRING(tcn_errors[err + 1]); | |
| 166 } | |
| 167 else { | |
| 168 apr_strerror(err, serr, 512); | |
| 169 jerr = AJP_TO_JSTRING(serr); | |
| 170 } | |
| 171 return jerr; | |
| 172 } | |
| 173 | |
| 174 TCN_IMPLEMENT_CALL(jboolean, Status, is)(TCN_STDARGS, jint err, jint idx) | |
| 175 { | |
| 176 #define APR_IS(I, E) case I: if (E(err)) return JNI_TRUE; break | |
| 177 #define APR_ISX(I, E, T) case I: if (E(err) || (err == T)) return JNI_TRUE; brea
k | |
| 178 | |
| 179 UNREFERENCED_STDARGS; | |
| 180 switch (idx) { | |
| 181 APR_IS(1, APR_STATUS_IS_ENOSTAT); | |
| 182 APR_IS(2, APR_STATUS_IS_ENOPOOL); | |
| 183 /* empty slot: +3 */ | |
| 184 APR_IS(4, APR_STATUS_IS_EBADDATE); | |
| 185 APR_IS(5, APR_STATUS_IS_EINVALSOCK); | |
| 186 APR_IS(6, APR_STATUS_IS_ENOPROC); | |
| 187 APR_IS(7, APR_STATUS_IS_ENOTIME); | |
| 188 APR_IS(8, APR_STATUS_IS_ENODIR); | |
| 189 APR_IS(9, APR_STATUS_IS_ENOLOCK); | |
| 190 APR_IS(10, APR_STATUS_IS_ENOPOLL); | |
| 191 APR_IS(11, APR_STATUS_IS_ENOSOCKET); | |
| 192 APR_IS(12, APR_STATUS_IS_ENOTHREAD); | |
| 193 APR_IS(13, APR_STATUS_IS_ENOTHDKEY); | |
| 194 APR_IS(14, APR_STATUS_IS_EGENERAL); | |
| 195 APR_IS(15, APR_STATUS_IS_ENOSHMAVAIL); | |
| 196 APR_IS(16, APR_STATUS_IS_EBADIP); | |
| 197 APR_IS(17, APR_STATUS_IS_EBADMASK); | |
| 198 /* empty slot: +18 */ | |
| 199 APR_IS(19, APR_STATUS_IS_EDSOOPEN); | |
| 200 APR_IS(20, APR_STATUS_IS_EABSOLUTE); | |
| 201 APR_IS(21, APR_STATUS_IS_ERELATIVE); | |
| 202 APR_IS(22, APR_STATUS_IS_EINCOMPLETE); | |
| 203 APR_IS(23, APR_STATUS_IS_EABOVEROOT); | |
| 204 APR_IS(24, APR_STATUS_IS_EBADPATH); | |
| 205 APR_IS(25, APR_STATUS_IS_EPATHWILD); | |
| 206 APR_IS(26, APR_STATUS_IS_ESYMNOTFOUND); | |
| 207 APR_IS(27, APR_STATUS_IS_EPROC_UNKNOWN); | |
| 208 APR_IS(28, APR_STATUS_IS_ENOTENOUGHENTROPY); | |
| 209 | |
| 210 | |
| 211 /* APR_Error */ | |
| 212 APR_IS(51, APR_STATUS_IS_INCHILD); | |
| 213 APR_IS(52, APR_STATUS_IS_INPARENT); | |
| 214 APR_IS(53, APR_STATUS_IS_DETACH); | |
| 215 APR_IS(54, APR_STATUS_IS_NOTDETACH); | |
| 216 APR_IS(55, APR_STATUS_IS_CHILD_DONE); | |
| 217 APR_IS(56, APR_STATUS_IS_CHILD_NOTDONE); | |
| 218 APR_ISX(57, APR_STATUS_IS_TIMEUP, TCN_TIMEUP); | |
| 219 APR_IS(58, APR_STATUS_IS_INCOMPLETE); | |
| 220 /* empty slot: +9 */ | |
| 221 /* empty slot: +10 */ | |
| 222 /* empty slot: +11 */ | |
| 223 APR_IS(62, APR_STATUS_IS_BADCH); | |
| 224 APR_IS(63, APR_STATUS_IS_BADARG); | |
| 225 APR_IS(64, APR_STATUS_IS_EOF); | |
| 226 APR_IS(65, APR_STATUS_IS_NOTFOUND); | |
| 227 /* empty slot: +16 */ | |
| 228 /* empty slot: +17 */ | |
| 229 /* empty slot: +18 */ | |
| 230 APR_IS(69, APR_STATUS_IS_ANONYMOUS); | |
| 231 APR_IS(70, APR_STATUS_IS_FILEBASED); | |
| 232 APR_IS(71, APR_STATUS_IS_KEYBASED); | |
| 233 APR_IS(72, APR_STATUS_IS_EINIT); | |
| 234 APR_IS(73, APR_STATUS_IS_ENOTIMPL); | |
| 235 APR_IS(74, APR_STATUS_IS_EMISMATCH); | |
| 236 APR_IS(75, APR_STATUS_IS_EBUSY); | |
| 237 /* Socket errors */ | |
| 238 APR_ISX(90, APR_STATUS_IS_EAGAIN, TCN_EAGAIN); | |
| 239 APR_ISX(91, TCN_STATUS_IS_ETIMEDOUT, TCN_ETIMEDOUT); | |
| 240 APR_IS(92, APR_STATUS_IS_ECONNABORTED); | |
| 241 APR_IS(93, APR_STATUS_IS_ECONNRESET); | |
| 242 APR_ISX(94, APR_STATUS_IS_EINPROGRESS, TCN_EINPROGRESS); | |
| 243 APR_ISX(95, APR_STATUS_IS_EINTR, TCN_EINTR); | |
| 244 APR_IS(96, APR_STATUS_IS_ENOTSOCK); | |
| 245 APR_IS(97, APR_STATUS_IS_EINVAL); | |
| 246 } | |
| 247 return JNI_FALSE; | |
| 248 } | |
| OLD | NEW |