---
generator/java.ml | 80 ++++++++++++++++------
generator/main.ml | 1 +
java/Makefile.am | 3 +-
.../et/libguestfs/LibGuestFSOutOfMemory.java | 37 ++++++++++
java/examples/guestfs-java.pod | 3 +
5 files changed, 102 insertions(+), 22 deletions(-)
create mode 100644 java/com/redhat/et/libguestfs/LibGuestFSOutOfMemory.java
diff --git a/generator/java.ml b/generator/java.ml
index 08e3a5f..7bcd329 100644
--- a/generator/java.ml
+++ b/generator/java.ml
@@ -576,7 +576,7 @@ struct callback_data {
jmethodID method; // callback.event method
};
-static struct callback_data **get_all_event_callbacks (guestfs_h *g, size_t *len_rtn);
+static struct callback_data **get_all_event_callbacks (JNIEnv *env, guestfs_h *g, size_t
*len_rtn);
/* Note that this function returns. The exception is not thrown
* until after the wrapper function returns.
@@ -590,6 +590,18 @@ throw_exception (JNIEnv *env, const char *msg)
(*env)->ThrowNew (env, cl, msg);
}
+/* Note that this function returns. The exception is not thrown
+ * until after the wrapper function returns.
+ */
+static void
+throw_out_of_memory (JNIEnv *env, const char *msg)
+{
+ jclass cl;
+ cl = (*env)->FindClass (env,
+ \"com/redhat/et/libguestfs/LibGuestFSOutOfMemory\");
+ (*env)->ThrowNew (env, cl, msg);
+}
+
JNIEXPORT jlong JNICALL
Java_com_redhat_et_libguestfs_GuestFS__1create (JNIEnv *env,
jobject obj_unused, jint flags)
@@ -617,7 +629,7 @@ Java_com_redhat_et_libguestfs_GuestFS__1close
* user deletes events in one of the callbacks that we are
* about to invoke, resulting in a double-free. XXX
*/
- data = get_all_event_callbacks (g, &len);
+ data = get_all_event_callbacks (env, g, &len);
guestfs_close (g);
@@ -717,7 +729,11 @@ Java_com_redhat_et_libguestfs_GuestFS__1set_1event_1callback
return -1;
}
- data = guestfs_int_safe_malloc (g, sizeof *data);
+ data = malloc (sizeof *data);
+ if (data == NULL) {
+ throw_out_of_memory (env, \"malloc\");
+ return -1;
+ }
(*env)->GetJavaVM (env, &data->jvm);
data->method = method;
@@ -779,7 +795,7 @@ Java_com_redhat_et_libguestfs_GuestFS__1event_1to_1string
}
static struct callback_data **
-get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
+get_all_event_callbacks (JNIEnv *env, guestfs_h *g, size_t *len_rtn)
{
struct callback_data **r;
size_t i;
@@ -796,7 +812,11 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
}
/* Copy them into the return array. */
- r = guestfs_int_safe_malloc (g, sizeof (struct callback_data *) * (*len_rtn));
+ r = malloc (sizeof (struct callback_data *) * (*len_rtn));
+ if (r == NULL) {
+ throw_out_of_memory (env, \"malloc\");
+ return NULL;
+ }
i = 0;
data = guestfs_first_private (g, &key);
@@ -961,6 +981,7 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
pr "\n";
(* Get the parameters. *)
+ let add_ret_error_label = ref false in
List.iter (
function
| Pathname n
@@ -981,7 +1002,12 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
pr " %s_size = (*env)->GetArrayLength (env, j%s);\n" n n
| StringList n | DeviceList n | FilenameList n ->
pr " %s_len = (*env)->GetArrayLength (env, j%s);\n" n n;
- pr " %s = guestfs_int_safe_malloc (g, sizeof (char *) *
(%s_len+1));\n" n n;
+ pr " %s = malloc (sizeof (char *) * (%s_len+1));\n" n n;
+ pr " if (%s == NULL) {\n" n;
+ pr " throw_out_of_memory (env, \"malloc\");\n";
+ pr " goto ret_error;\n";
+ add_ret_error_label := true;
+ pr " }\n";
pr " for (i = 0; i < %s_len; ++i) {\n" n;
pr " jobject o = (*env)->GetObjectArrayElement (env, j%s,
i);\n"
n;
@@ -1007,7 +1033,12 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
n n
| OStringList n ->
pr " %s_len = (*env)->GetArrayLength (env, j%s);\n" n n;
- pr " %s = guestfs_int_safe_malloc (g, sizeof (char *) *
(%s_len+1));\n" n n;
+ pr " %s = malloc (sizeof (char *) * (%s_len+1));\n" n n;
+ pr " if (%s == NULL) {\n" n;
+ pr " throw_out_of_memory (env, \"malloc\");\n";
+ pr " goto ret_error;\n";
+ add_ret_error_label := true;
+ pr " }\n";
pr " for (i = 0; i < %s_len; ++i) {\n" n;
pr " jobject o = (*env)->GetObjectArrayElement (env, j%s,
i);\n"
n;
@@ -1084,25 +1115,14 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
pr " if (r == NULL) {\n";
);
pr " throw_exception (env, guestfs_last_error (g));\n";
- (match ret with
- | RErr ->
- pr " return;\n"
- | RInt _
- | RInt64 _
- | RBool _ ->
- pr " return -1;\n"
- | RConstString _ | RConstOptString _ | RString _
- | RBufferOut _
- | RStruct _ | RHashtable _
- | RStringList _ | RStructList _ ->
- pr " return NULL;\n"
- );
+ pr " goto ret_error;\n";
+ add_ret_error_label := true;
pr " }\n"
);
(* Return value. *)
(match ret with
- | RErr -> ()
+ | RErr -> pr " return;\n";
| RInt _ -> pr " return (jint) r;\n"
| RBool _ -> pr " return (jboolean) r;\n"
| RInt64 _ -> pr " return (jlong) r;\n"
@@ -1140,6 +1160,24 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
pr " return jr;\n"
);
+ if !add_ret_error_label then (
+ pr "\n";
+ pr " ret_error:\n";
+ (match ret with
+ | RErr ->
+ pr " return;\n"
+ | RInt _
+ | RInt64 _
+ | RBool _ ->
+ pr " return -1;\n"
+ | RConstString _ | RConstOptString _ | RString _
+ | RBufferOut _
+ | RStruct _ | RHashtable _
+ | RStringList _ | RStructList _ ->
+ pr " return NULL;\n"
+ );
+ );
+
pr "}\n";
pr "\n"
) external_functions_sorted
diff --git a/generator/main.ml b/generator/main.ml
index 0230a2f..b209511 100644
--- a/generator/main.ml
+++ b/generator/main.ml
@@ -145,6 +145,7 @@ Run it from the top source directory using the command
) external_structs;
delete_except_generated
~skip:["java/com/redhat/et/libguestfs/LibGuestFSException.java";
+ "java/com/redhat/et/libguestfs/LibGuestFSOutOfMemory.java";
"java/com/redhat/et/libguestfs/EventCallback.java"]
"java/com/redhat/et/libguestfs/*.java";
diff --git a/java/Makefile.am b/java/Makefile.am
index 8cfda74..0651fd3 100644
--- a/java/Makefile.am
+++ b/java/Makefile.am
@@ -31,7 +31,8 @@ include $(srcdir)/Makefile.inc
java_sources = \
$(java_built_sources) \
com/redhat/et/libguestfs/EventCallback.java \
- com/redhat/et/libguestfs/LibGuestFSException.java
+ com/redhat/et/libguestfs/LibGuestFSException.java \
+ com/redhat/et/libguestfs/LibGuestFSOutOfMemory.java
java_tests = \
Bindtests.java \
diff --git a/java/com/redhat/et/libguestfs/LibGuestFSOutOfMemory.java
b/java/com/redhat/et/libguestfs/LibGuestFSOutOfMemory.java
new file mode 100644
index 0000000..bc4c929
--- /dev/null
+++ b/java/com/redhat/et/libguestfs/LibGuestFSOutOfMemory.java
@@ -0,0 +1,37 @@
+/* libguestfs Java bindings
+ * Copyright (C) 2009-2016 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+package com.redhat.et.libguestfs;
+
+/**
+ * Libguestfs out of memory class.
+ * <p>
+ * This exception is thrown when malloc or a similar call fails
+ * in the bindings.
+ *
+ * @author rjones
+ * @see Error
+ */
+public class LibGuestFSOutOfMemory extends Error {
+ private static final long serialVersionUID = 1L;
+
+ public LibGuestFSOutOfMemory (String msg)
+ {
+ super (msg);
+ }
+}
diff --git a/java/examples/guestfs-java.pod b/java/examples/guestfs-java.pod
index 53276e8..bcff388 100644
--- a/java/examples/guestfs-java.pod
+++ b/java/examples/guestfs-java.pod
@@ -38,6 +38,9 @@ is the error message (a C<String>).
Calling any method on a closed handle raises the same exception.
+If L<malloc(3)> or some other allocation fails inside the bindings,
+the C<LibGuestFSOutOfMemory> exception is thrown.
+
=head2 EVENTS
The L<libguestfs event API|guestfs(3)/EVENTS> is fully supported from
--
2.5.0