diff --git a/generator/GObject.ml b/generator/GObject.ml index b89db690f..87c5b33bf 100644 --- a/generator/GObject.ml +++ b/generator/GObject.ml @@ -206,7 +206,7 @@ let generate_gobject_struct_header filename typ cols () = pr " * @%s: An unsigned 64-bit integer\n" n | n, FInt64 -> pr " * @%s: A signed 64-bit integer\n" n - | n, FString -> + | n, (FString|FDevice) -> pr " * @%s: A NULL-terminated string\n" n | n, FBuffer -> pr " * @%s: A GByteArray\n" n @@ -231,7 +231,7 @@ let generate_gobject_struct_header filename typ cols () = pr " guint64 %s;\n" n | n, FInt64 -> pr " gint64 %s;\n" n - | n, FString -> + | n, (FString|FDevice) -> pr " gchar *%s;\n" n | n, FBuffer -> pr " GByteArray *%s;\n" n @@ -1228,7 +1228,7 @@ guestfs_session_close (GuestfsSession *session, GError **err) | n, FUUID -> pr "%smemcpy (%s%s, %s%s, sizeof (%s%s));\n" indent dst n src n dst n - | n, FString -> + | n, (FString|FDevice) -> pr "%sif (%s%s) %s%s = g_strdup (%s%s);\n" indent src n dst n src n | n, FBuffer -> diff --git a/generator/OCaml.ml b/generator/OCaml.ml index 66ed5e1ae..d4dfe9ed0 100644 --- a/generator/OCaml.ml +++ b/generator/OCaml.ml @@ -512,7 +512,7 @@ copy_table (char * const * argv) List.iteri ( fun i col -> (match col with - | name, FString -> + | name, (FString|FDevice) -> pr " v = caml_copy_string (%s->%s);\n" typ name | name, FBuffer -> pr " v = caml_alloc_initialized_string (%s->%s_len, %s->%s);\n" @@ -839,9 +839,7 @@ and generate_ocaml_structure_decls () = pr "type %s = {\n" typ; List.iter ( function - | name, FString -> pr " %s : string;\n" name - | name, FBuffer -> pr " %s : string;\n" name - | name, FUUID -> pr " %s : string;\n" name + | name, (FString|FDevice|FBuffer|FUUID) -> pr " %s : string;\n" name | name, (FBytes|FInt64|FUInt64) -> pr " %s : int64;\n" name | name, (FInt32|FUInt32) -> pr " %s : int32;\n" name | name, FChar -> pr " %s : char;\n" name diff --git a/generator/XDR.ml b/generator/XDR.ml index c5444b501..431959819 100644 --- a/generator/XDR.ml +++ b/generator/XDR.ml @@ -66,7 +66,7 @@ let generate_xdr () = pr "struct guestfs_int_%s {\n" typ; List.iter (function | name, FChar -> pr " char %s;\n" name - | name, FString -> pr " string %s<>;\n" name + | name, (FString|FDevice) -> pr " string %s<>;\n" name | name, FBuffer -> pr " opaque %s<>;\n" name | name, FUUID -> pr " opaque %s[32];\n" name | name, FInt32 -> pr " int %s;\n" name diff --git a/generator/c.ml b/generator/c.ml index a51031eff..c6e5dd994 100644 --- a/generator/c.ml +++ b/generator/c.ml @@ -352,7 +352,7 @@ and generate_structs_pod () = | name, FInt32 -> pr " int32_t %s;\n" name | name, (FUInt64|FBytes) -> pr " uint64_t %s;\n" name | name, FInt64 -> pr " int64_t %s;\n" name - | name, FString -> pr " char *%s;\n" name + | name, (FString|FDevice) -> pr " char *%s;\n" name | name, FBuffer -> pr " /* The next two fields describe a byte array. */\n"; pr " uint32_t %s_len;\n" name; @@ -609,7 +609,7 @@ extern GUESTFS_DLL_PUBLIC void *guestfs_next_private (guestfs_h *g, const char * List.iter ( function | name, FChar -> pr " char %s;\n" name - | name, FString -> pr " char *%s;\n" name + | name, (FString|FDevice) -> pr " char *%s;\n" name | name, FBuffer -> pr " uint32_t %s_len;\n" name; pr " char *%s;\n" name @@ -916,7 +916,7 @@ and generate_client_structs_compare () = fun { s_name = typ; s_cols = cols } -> let has_nonnumeric_cols = let nonnumeric = function - | _,(FString|FUUID|FBuffer) -> true + | _,(FString|FDevice|FUUID|FBuffer) -> true | _,(FChar|FUInt32|FInt32|FUInt64|FBytes|FInt64|FOptPercent) -> false in List.exists nonnumeric cols in @@ -932,7 +932,7 @@ and generate_client_structs_compare () = ); List.iter ( function - | name, FString -> + | name, (FString|FDevice) -> pr " r = strcmp (s1->%s, s2->%s);\n" name name; pr " if (r != 0) return r;\n" | name, FBuffer -> @@ -1001,7 +1001,7 @@ and generate_client_structs_copy () = fun { s_name = typ; s_cols = cols } -> let has_boxed_cols = let boxed = function - | _,(FString|FBuffer) -> true + | _,(FString|FDevice|FBuffer) -> true | _,(FChar|FUUID|FUInt32|FInt32|FUInt64|FBytes|FInt64|FOptPercent) -> false in @@ -1014,8 +1014,7 @@ and generate_client_structs_copy () = pr "{\n"; List.iter ( function - | name, FString - | name, FBuffer -> pr " free (s->%s);\n" name + | name, (FString|FDevice|FBuffer) -> pr " free (s->%s);\n" name | _, FChar | _, FUUID | _, FUInt32 @@ -1038,8 +1037,7 @@ and generate_client_structs_copy () = pr "\n"; List.iter ( function - | name, FString - | name, FBuffer -> pr " out->%s = NULL;\n" name + | name, (FString|FDevice|FBuffer) -> pr " out->%s = NULL;\n" name | _, FChar | _, FUUID | _, FUInt32 @@ -1051,7 +1049,7 @@ and generate_client_structs_copy () = ) cols; List.iter ( function - | name, FString -> + | name, (FString|FDevice) -> pr " out->%s = strdup (inp->%s);\n" name name; pr " if (out->%s == NULL) goto error;\n" name | name, FBuffer -> @@ -1234,7 +1232,7 @@ and generate_client_structs_print_c () = ); List.iter ( function - | name, FString -> + | name, (FString|FDevice) -> pr " fprintf (dest, \"%%s%s: %%s%%s\", indent, %s->%s, linesep);\n" name typ name | name, FUUID -> diff --git a/generator/csharp.ml b/generator/csharp.ml index d1999bcff..5c77a46b4 100644 --- a/generator/csharp.ml +++ b/generator/csharp.ml @@ -119,7 +119,7 @@ namespace Guestfs List.iter ( function | name, FChar -> pr " char %s;\n" name - | name, FString -> pr " string %s;\n" name + | name, (FString | FDevice) -> pr " string %s;\n" name | name, FBuffer -> pr " uint %s_len;\n" name; pr " string %s;\n" name diff --git a/generator/daemon.ml b/generator/daemon.ml index 9f75f385a..e19fa07d2 100644 --- a/generator/daemon.ml +++ b/generator/daemon.ml @@ -442,15 +442,37 @@ let generate_daemon_stubs actions () = pr " ret.%s.%s_val = r;\n" n n; pr " reply ((xdrproc_t) &xdr_guestfs_%s_ret, (char *) &ret);\n" name - | RStruct (n, _) -> + | RStruct (n, typ) -> + (* XXX RStruct containing an FDevice field would require + * reverse device name translation. That is not implemented. + * See also RStructList immediately below this. + *) + let cols = (Structs.lookup_struct typ).s_cols in + assert (not (List.exists + (function (_, FDevice) -> true | _ -> false) cols)); pr " struct guestfs_%s_ret ret;\n" name; pr " ret.%s = *r;\n" n; pr " reply ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n" name; pr " xdr_free ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n" name - | RStructList (n, _) -> + | RStructList (n, typ) -> pr " struct guestfs_%s_ret ret;\n" name; + let cols = (Structs.lookup_struct typ).s_cols in + List.iter ( + function + | (fname, FDevice) -> + pr " for (size_t i = 0; i < r->guestfs_int_%s_list_len; ++i) {\n" + typ; + pr " char *field = r->guestfs_int_%s_list_val[i].%s;\n" + typ fname; + pr " char *rr = reverse_device_name_translation (field);\n"; + pr " if (!rr) abort ();\n"; + pr " free (field);\n"; + pr " r->guestfs_int_%s_list_val[i].%s = rr;\n" typ fname; + pr " }\n"; + | _ -> () + ) cols; pr " ret.%s = *r;\n" n; pr " reply ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n" name; @@ -619,7 +641,7 @@ let generate_daemon_caml_stubs () = fun i -> pr " v = Field (retv, %d);\n" i; function - | n, (FString|FUUID) -> + | n, (FString|FDevice|FUUID) -> pr " ret->%s = strdup (String_val (v));\n" n; pr " if (ret->%s == NULL) return NULL;\n" n | n, FBuffer -> @@ -986,7 +1008,7 @@ let generate_daemon_lvm_tokenization () = pr " if (*p) next = p+1; else next = NULL;\n"; pr " *p = '\\0';\n"; (match coltype with - | FString -> + | FString | FDevice -> pr " r->%s = strdup (tok);\n" name; pr " if (r->%s == NULL) {\n" name; pr " perror (\"strdup\");\n"; diff --git a/generator/erlang.ml b/generator/erlang.ml index 65af75aaf..864b3ff04 100644 --- a/generator/erlang.ml +++ b/generator/erlang.ml @@ -286,7 +286,7 @@ and generate_erlang_structs () = List.iteri ( fun i col -> (match col with - | name, FString -> + | name, (FString|FDevice) -> pr " if (ei_x_encode_string (buff, %s->%s) != 0) return -1;\n" typ name | name, FBuffer -> pr " if (ei_x_encode_string_len (buff, %s->%s, %s->%s_len) != 0) return -1;\n" diff --git a/generator/golang.ml b/generator/golang.ml index 0d6a92367..a5b39f5df 100644 --- a/generator/golang.ml +++ b/generator/golang.ml @@ -248,7 +248,7 @@ func return_hashtable (argv **C.char) map[string]string { let n = String.capitalize_ascii n in match field with | FChar -> pr " %s byte\n" n - | FString -> pr " %s string\n" n + | FString | FDevice -> pr " %s string\n" n | FBuffer -> pr " %s []byte\n" n | FUInt32 -> pr " %s uint32\n" n | FInt32 -> pr " %s int32\n" n @@ -267,7 +267,7 @@ func return_hashtable (argv **C.char) map[string]string { let gon = String.capitalize_ascii n in match field with | FChar -> pr " r.%s = byte (c.%s)\n" gon n - | FString -> pr " r.%s = C.GoString (c.%s)\n" gon n + | FString | FDevice -> pr " r.%s = C.GoString (c.%s)\n" gon n | FBuffer -> pr " r.%s = C.GoBytes (unsafe.Pointer (c.%s), C.int (c.%s_len))\n" gon n n diff --git a/generator/java.ml b/generator/java.ml index 7a8c0016c..909db4530 100644 --- a/generator/java.ml +++ b/generator/java.ml @@ -560,6 +560,7 @@ public class %s { List.iter ( function | name, FString + | name, FDevice | name, FUUID | name, FBuffer -> pr " public String %s;\n" name | name, (FBytes|FUInt64|FInt64) -> pr " public long %s;\n" name @@ -947,7 +948,7 @@ and generate_java_struct_return typ jtyp cols = pr " jr = (*env)->AllocObject (env, cl);\n"; List.iter ( function - | name, FString -> + | name, (FString|FDevice) -> pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name; pr " (*env)->SetObjectField (env, jr, fl, (*env)->NewStringUTF (env, r->%s));\n" name; | name, FUUID -> @@ -997,7 +998,7 @@ and generate_java_struct_list_return typ jtyp cols = fun (name, ftyp) -> (* Get the field ID in 'fl'. *) let java_field_type = match ftyp with - | FString | FUUID | FBuffer -> "Ljava/lang/String;" + | FString | FDevice | FUUID | FBuffer -> "Ljava/lang/String;" | FBytes | FUInt64 | FInt64 -> "J" | FUInt32 | FInt32 -> "I" | FOptPercent -> "F" @@ -1007,7 +1008,7 @@ and generate_java_struct_list_return typ jtyp cols = (* Assign the value to this field. *) match ftyp with - | FString -> + | FString | FDevice -> pr " (*env)->SetObjectField (env, jfl, fl,\n"; pr " (*env)->NewStringUTF (env, r->val[i].%s));\n" name; | FUUID -> diff --git a/generator/lua.ml b/generator/lua.ml index 0d7e63be0..685645abf 100644 --- a/generator/lua.ml +++ b/generator/lua.ml @@ -824,7 +824,7 @@ push_event (lua_State *L, uint64_t event) (match field with | FChar -> pr " lua_pushlstring (L, &v->%s, 1);\n" n - | FString -> + | FString | FDevice -> pr " lua_pushstring (L, v->%s);\n" n | FBuffer -> pr " lua_pushlstring (L, v->%s, v->%s_len);\n" n n diff --git a/generator/perl.ml b/generator/perl.ml index 0059d4c1d..17ed64d29 100644 --- a/generator/perl.ml +++ b/generator/perl.ml @@ -607,7 +607,7 @@ and generate_perl_struct_list_code typ cols name style = pr " hv = newHV ();\n"; List.iter ( function - | name, FString -> + | name, (FString|FDevice) -> pr " (void) hv_store (hv, \"%s\", %d, newSVpv (r->val[i].%s, 0), 0);\n" name (String.length name) name | name, FUUID -> @@ -645,7 +645,7 @@ and generate_perl_struct_code typ cols name style = pr " PUSHs (sv_2mortal (newSVpv (\"%s\", 0)));\n" name; match col with - | name, FString -> + | name, (FString|FDevice) -> pr " PUSHs (sv_2mortal (newSVpv (r->%s, 0)));\n" name | name, FBuffer -> diff --git a/generator/php.ml b/generator/php.ml index df8470461..2b336f96f 100644 --- a/generator/php.ml +++ b/generator/php.ml @@ -616,7 +616,7 @@ and generate_php_struct_code typ cols = pr " array_init (return_value);\n"; List.iter ( function - | name, FString -> + | name, (FString|FDevice) -> pr " guestfs_add_assoc_string (return_value, \"%s\", r->%s, 1);\n" name name | name, FBuffer -> pr " guestfs_add_assoc_stringl (return_value, \"%s\", r->%s, r->%s_len, 1);\n" @@ -650,7 +650,7 @@ and generate_php_struct_list_code typ cols = pr " array_init (z_elem);\n"; List.iter ( function - | name, FString -> + | name, (FString|FDevice) -> pr " guestfs_add_assoc_string (z_elem, \"%s\", r->val[c].%s, 1);\n" name name | name, FBuffer -> diff --git a/generator/python.ml b/generator/python.ml index 242721f33..86b70b2de 100644 --- a/generator/python.ml +++ b/generator/python.ml @@ -168,7 +168,7 @@ and generate_python_structs () = pr " return NULL;\n"; List.iter ( function - | name, FString -> + | name, (FString|FDevice) -> pr " value = guestfs_int_py_fromstring (%s->%s);\n" typ name; pr " if (value == NULL)\n"; pr " goto err;\n"; diff --git a/generator/ruby.ml b/generator/ruby.ml index 0f63b82ed..f9787af69 100644 --- a/generator/ruby.ml +++ b/generator/ruby.ml @@ -526,7 +526,7 @@ and generate_ruby_struct_code typ cols = pr " volatile VALUE rv = rb_hash_new ();\n"; List.iter ( function - | name, FString -> + | name, (FString|FDevice) -> pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_str_new2 (r->%s));\n" name name | name, FBuffer -> pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_str_new (r->%s, r->%s_len));\n" name name name @@ -556,7 +556,7 @@ and generate_ruby_struct_list_code typ cols = pr " volatile VALUE hv = rb_hash_new ();\n"; List.iter ( function - | name, FString -> + | name, (FString|FDevice) -> pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), rb_str_new2 (r->val[i].%s));\n" name name | name, FBuffer -> pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), rb_str_new (r->val[i].%s, r->val[i].%s_len));\n" name name name diff --git a/generator/rust.ml b/generator/rust.ml index 1f5cefa62..f4dcfd723 100644 --- a/generator/rust.ml +++ b/generator/rust.ml @@ -115,7 +115,7 @@ extern \"C\" { List.iter ( function | n, FChar -> pr " pub %s: i8,\n" n - | n, FString -> pr " pub %s: String,\n" n + | n, (FString|FDevice) -> pr " pub %s: String,\n" n | n, FBuffer -> pr " pub %s: Vec,\n" n | n, FUInt32 -> pr " pub %s: u32,\n" n | n, FInt32 -> pr " pub %s: i32,\n" n @@ -130,7 +130,7 @@ extern \"C\" { List.iter ( function | n, FChar -> pr " %s: c_char,\n" n - | n, FString -> pr " %s: *const c_char,\n" n + | n, (FString|FDevice) -> pr " %s: *const c_char,\n" n | n, FBuffer -> pr " %s_len: usize,\n" n; pr " %s: *const c_char,\n" n; @@ -154,7 +154,7 @@ extern \"C\" { match x with | n, FChar -> pr "%s: (*raw).%s as i8,\n" n n; - | n, FString -> + | n, (FString|FDevice) -> pr "%s: char_ptr_to_string((*raw).%s)?,\n" n n; | n, FBuffer -> pr "%s: slice::from_raw_parts((*raw).%s as *const u8, (*raw).%s_len).to_vec(),\n" n n n diff --git a/generator/types.ml b/generator/types.ml index 76b699e78..7163da8d2 100644 --- a/generator/types.ml +++ b/generator/types.ml @@ -215,6 +215,7 @@ let defaults = { name = ""; type field = | FChar (* C 'char' (really, a 7 bit byte). *) | FString (* nul-terminated ASCII string, NOT NULL. *) + | FDevice (* device name, needs reverse transl. *) | FBuffer (* opaque buffer of bytes, (char *, int) pair *) | FUInt32 | FInt32 diff --git a/generator/types.mli b/generator/types.mli index 7c549a35e..e8939370e 100644 --- a/generator/types.mli +++ b/generator/types.mli @@ -413,6 +413,7 @@ val defaults : action type field = | FChar (** C 'char' (really, a 7 bit byte). *) | FString (** nul-terminated ASCII string, NOT NULL. *) + | FDevice (** device name, needs reverse transl. *) | FBuffer (** opaque buffer of bytes, (char *, int) pair*) | FUInt32 | FInt32