[Libguestfs] [PATCH 1/2] generator: add a RelativePathnameList parameter type

Pino Toscano ptoscano at redhat.com
Tue Oct 20 11:59:09 UTC 2015


Mostly like StringList (so it can used in current StringList
parameters), but checking client- and daemon-side that the elements are
relative paths.
---
 generator/bindtests.ml   |  3 ++-
 generator/c.ml           | 29 ++++++++++++++++++++++++-----
 generator/csharp.ml      |  4 ++--
 generator/daemon.ml      | 20 ++++++++++++++++++--
 generator/erlang.ml      |  2 +-
 generator/fish.ml        | 10 ++++++----
 generator/gobject.ml     |  7 ++++---
 generator/golang.ml      |  9 ++++++---
 generator/haskell.ml     |  9 +++++----
 generator/java.ml        | 10 +++++-----
 generator/lua.ml         |  6 +++---
 generator/ocaml.ml       |  7 ++++---
 generator/perl.ml        |  9 ++++++---
 generator/php.ml         | 13 ++++++++-----
 generator/python.ml      | 13 +++++++------
 generator/ruby.ml        |  4 ++--
 generator/tests_c_api.ml |  7 +++++--
 generator/types.ml       |  4 ++++
 generator/utils.ml       |  2 +-
 generator/xdr.ml         |  3 ++-
 20 files changed, 115 insertions(+), 56 deletions(-)

diff --git a/generator/bindtests.ml b/generator/bindtests.ml
index 0959704..1d9ea3e 100644
--- a/generator/bindtests.ml
+++ b/generator/bindtests.ml
@@ -163,7 +163,8 @@ fill_lvm_pv (guestfs_h *g, struct guestfs_lvm_pv *pv, size_t i)
           pr "    fprintf (fp, \"\\n\");\n";
           pr "  }\n";
         | OptString n -> pr "  fprintf (fp, \"%%s\\n\", %s ? %s : \"null\");\n" n n
-        | StringList n | DeviceList n -> pr "  print_strings (g, %s);\n" n
+        | StringList n | DeviceList n | RelativePathnameList n ->
+          pr "  print_strings (g, %s);\n" n
         | Bool n -> pr "  fprintf (fp, \"%%s\\n\", %s ? \"true\" : \"false\");\n" n
         | Int n -> pr "  fprintf (fp, \"%%d\\n\", %s);\n" n
         | Int64 n -> pr "  fprintf (fp, \"%%\" PRIi64 \"\\n\", %s);\n" n
diff --git a/generator/c.ml b/generator/c.ml
index 055b683..183bf94 100644
--- a/generator/c.ml
+++ b/generator/c.ml
@@ -131,7 +131,7 @@ let rec generate_prototype ?(extern = true) ?(static = false)
           pr "const mountable_t *%s" n
         else
           pr "const char *%s" n
-    | StringList n | DeviceList n ->
+    | StringList n | DeviceList n | RelativePathnameList n ->
         next ();
         pr "char *const *%s" n
     | Bool n -> next (); pr "int %s" n
@@ -1252,7 +1252,8 @@ and generate_client_actions hash () =
       | DeviceList n
       | Key n
       | Pointer (_, n)
-      | GUID n ->
+      | GUID n
+      | RelativePathnameList n ->
           pr "  if (%s == NULL) {\n" n;
           pr "    error (g, \"%%s: %%s: parameter cannot be NULL\",\n";
           pr "           \"%s\", \"%s\");\n" c_name n;
@@ -1355,6 +1356,23 @@ and generate_client_actions hash () =
           pr "  }\n";
           pr_newline := true
 
+      | RelativePathnameList n ->
+          pr "  {\n";
+          pr "    size_t i;\n";
+          pr "    for (i = 0; %s[i] != NULL; ++i) {\n" n;
+          pr "      if (%s[i][0] == '/') {\n" n;
+          pr "        error (g, \"%%s: %%s: path '%%s' must be relative\",\n";
+          pr "               \"%s\", \"%s\", %s[i]);\n" c_name n n;
+          let errcode =
+            match errcode_of_ret ret with
+            | `CannotReturnError -> assert false
+            | (`ErrorIsMinusOne |`ErrorIsNULL) as e -> e in
+          pr "        return %s;\n" (string_of_errcode errcode);
+          pr "      }\n";
+          pr "    }\n";
+          pr "  }\n";
+          pr_newline := true
+
       (* not applicable *)
       | String _
       | Device _
@@ -1383,7 +1401,7 @@ and generate_client_actions hash () =
 
     let needs_i =
       List.exists (function
-      | StringList _ | DeviceList _ -> true
+      | StringList _ | DeviceList _ | RelativePathnameList _ -> true
       | _ -> false) args ||
       List.exists (function
       | OStringList _ -> true
@@ -1419,7 +1437,8 @@ and generate_client_actions hash () =
           pr "    else\n";
           pr "      fprintf (trace_buffer.fp, \" null\");\n"
       | StringList n
-      | DeviceList n ->			(* string list *)
+      | DeviceList n
+      | RelativePathnameList n ->			(* string list *)
           pr "    fputc (' ', trace_buffer.fp);\n";
           pr "    fputc ('\"', trace_buffer.fp);\n";
           pr "    for (i = 0; %s[i]; ++i) {\n" n;
@@ -1735,7 +1754,7 @@ and generate_client_actions hash () =
           pr "  args.%s = (char *) %s;\n" n n
         | OptString n ->
           pr "  args.%s = %s ? (char **) &%s : NULL;\n" n n n
-        | StringList n | DeviceList n ->
+        | StringList n | DeviceList n | RelativePathnameList n ->
           pr "  args.%s.%s_val = (char **) %s;\n" n n n;
           pr "  for (args.%s.%s_len = 0; %s[args.%s.%s_len]; args.%s.%s_len++) ;\n" n n n n n n n;
         | Bool n ->
diff --git a/generator/csharp.ml b/generator/csharp.ml
index e2bd25b..59f7be9 100644
--- a/generator/csharp.ml
+++ b/generator/csharp.ml
@@ -195,7 +195,7 @@ namespace Guestfs
           | BufferIn n
           | GUID n ->
               pr ", [In] string %s" n
-          | StringList n | DeviceList n ->
+          | StringList n | DeviceList n | RelativePathnameList n ->
               pr ", [In] string[] %s" n
           | Bool n ->
               pr ", bool %s" n
@@ -224,7 +224,7 @@ namespace Guestfs
           | BufferIn n
           | GUID n ->
               next (); pr "string %s" n
-          | StringList n | DeviceList n ->
+          | StringList n | DeviceList n | RelativePathnameList n ->
               next (); pr "string[] %s" n
           | Bool n ->
               next (); pr "bool %s" n
diff --git a/generator/daemon.ml b/generator/daemon.ml
index 1825de4..e6093a3 100644
--- a/generator/daemon.ml
+++ b/generator/daemon.ml
@@ -255,7 +255,7 @@ cleanup_free_mountable (mountable_t *mountable)
           | Mountable n | Mountable_or_Path n ->
             pr "  CLEANUP_FREE_MOUNTABLE mountable_t %s\n" n;
             pr "      = { .device = NULL, .volume = NULL };\n"
-          | StringList n ->
+          | StringList n | RelativePathnameList n ->
             pr "  char **%s;\n" n
           | DeviceList n ->
             pr "  CLEANUP_FREE_STRING_LIST char **%s = NULL;\n" n
@@ -344,7 +344,23 @@ cleanup_free_mountable (mountable_t *mountable)
                 n n (if is_filein then "cancel_receive ()" else "");
           | String n | Key n | GUID n -> pr_args n
           | OptString n -> pr "  %s = args.%s ? *args.%s : NULL;\n" n n n
-          | StringList n ->
+          | StringList n | RelativePathnameList n as arg ->
+            (match arg with
+            | RelativePathnameList n ->
+              pr "  {\n";
+              pr "    size_t i;\n";
+              pr "    for (i = 0; i < args.%s.%s_len; ++i) {\n" n n;
+              pr "      if (args.%s.%s_val[i][0] == '/') {\n" n n;
+              if is_filein then
+                pr "        cancel_receive ();\n";
+              pr "        reply_with_error (\"%%s: path '%%s' must be relative\", __func__, args.%s.%s_val[i]);\n"
+                n n;
+              pr "        goto done;\n";
+              pr "      }\n";
+              pr "    }\n";
+              pr "  }\n"
+            | _ -> ()
+            );
             pr "  /* Ugly, but safe and avoids copying the strings. */\n";
             pr "  %s = realloc (args.%s.%s_val,\n" n n n;
             pr "                sizeof (char *) * (args.%s.%s_len+1));\n" n n;
diff --git a/generator/erlang.ml b/generator/erlang.ml
index 5d4faaf..c09d97c 100644
--- a/generator/erlang.ml
+++ b/generator/erlang.ml
@@ -310,7 +310,7 @@ extern int64_t get_int64 (ETERM *term);
             pr "  ETERM *%s_bin = erl_iolist_to_binary (ARG (%d));\n" n i;
             pr "  const void *%s = ERL_BIN_PTR (%s_bin);\n" n n;
             pr "  size_t %s_size = ERL_BIN_SIZE (%s_bin);\n" n n
-          | StringList n | DeviceList n ->
+          | StringList n | DeviceList n | RelativePathnameList n ->
             pr "  CLEANUP_FREE_STRING_LIST char **%s = get_string_list (ARG (%d));\n" n i
           | Bool n ->
             pr "  int %s = get_bool (ARG (%d));\n" n i
diff --git a/generator/fish.ml b/generator/fish.ml
index 6f68e65..cfbec2a 100644
--- a/generator/fish.ml
+++ b/generator/fish.ml
@@ -376,7 +376,8 @@ Guestfish will prompt for these separately."
         | BufferIn n ->
             pr "  const char *%s;\n" n;
             pr "  size_t %s_size;\n" n
-        | StringList n | DeviceList n -> pr "  char **%s;\n" n
+        | StringList n | DeviceList n | RelativePathnameList n ->
+            pr "  char **%s;\n" n
         | Bool n -> pr "  int %s;\n" n
         | Int n -> pr "  int %s;\n" n
         | Int64 n -> pr "  int64_t %s;\n" n
@@ -464,7 +465,7 @@ Guestfish will prompt for these separately."
         | FileOut name ->
             pr "  %s = file_out (argv[i++]);\n" name;
             pr "  if (%s == NULL) goto out_%s;\n" name name
-        | StringList name | DeviceList name ->
+        | StringList name | DeviceList name | RelativePathnameList name ->
             pr "  %s = parse_string_list (argv[i++]);\n" name;
             pr "  if (%s == NULL) goto out_%s;\n" name name
         | Key name ->
@@ -678,7 +679,7 @@ Guestfish will prompt for these separately."
         | FileIn name ->
             pr "  free_file_in (%s);\n" name;
             pr " out_%s:\n" name
-        | StringList name | DeviceList name ->
+        | StringList name | DeviceList name | RelativePathnameList name ->
             pr "  guestfs_int_free_string_list (%s);\n" name;
             pr " out_%s:\n" name
         | Pointer _ -> assert false
@@ -917,7 +918,8 @@ and generate_fish_actions_pod () =
         | GUID n ->
             pr " %s" n
         | OptString n -> pr " %s" n
-        | StringList n | DeviceList n -> pr " '%s ...'" n
+        | StringList n | DeviceList n | RelativePathnameList n ->
+            pr " '%s ...'" n
         | Bool _ -> pr " true|false"
         | Int n -> pr " %s" n
         | Int64 n -> pr " %s" n
diff --git a/generator/gobject.ml b/generator/gobject.ml
index 8d5ac06..15f214b 100644
--- a/generator/gobject.ml
+++ b/generator/gobject.ml
@@ -85,7 +85,8 @@ let generate_gobject_proto name ?(single_line = true)
       | GUID n ->
         pr "const gchar *%s" n
       | StringList n
-      | DeviceList n ->
+      | DeviceList n
+      | RelativePathnameList n ->
         pr "gchar *const *%s" n
       | BufferIn n ->
         pr "const guint8 *%s, gsize %s_size" n n
@@ -1052,7 +1053,7 @@ guestfs_session_close (GuestfsSession *session, GError **err)
             pr " (transfer none) (type filename):"
           | StringList _ ->
             pr " (transfer none) (array zero-terminated=1) (element-type utf8): an array of strings"
-          | DeviceList _ ->
+          | DeviceList _ | RelativePathnameList _ ->
             pr " (transfer none) (array zero-terminated=1) (element-type filename): an array of strings"
           | BufferIn n ->
             pr " (transfer none) (array length=%s_size) (element-type guint8): an array of binary data\n" n;
@@ -1211,7 +1212,7 @@ guestfs_session_close (GuestfsSession *session, GError **err)
           | Pathname n | Dev_or_Path n | Mountable_or_Path n
           | OptString n | StringList n
           | DeviceList n | Key n | FileIn n | FileOut n
-          | GUID n ->
+          | GUID n | RelativePathnameList n ->
             pr "%s" n
           | Pointer (_, n) ->
             pr "%s" n
diff --git a/generator/golang.ml b/generator/golang.ml
index b4b2482..cfc5b5b 100644
--- a/generator/golang.ml
+++ b/generator/golang.ml
@@ -315,7 +315,8 @@ func return_hashtable (argv **C.char) map[string]string {
           | GUID n -> pr "%s string" n
           | OptString n -> pr "%s *string" n
           | StringList n
-          | DeviceList n -> pr "%s []string" n
+          | DeviceList n
+          | RelativePathnameList n -> pr "%s []string" n
           | BufferIn n -> pr "%s []byte" n
           | Pointer (_, n) -> pr "%s int64" n
       ) args;
@@ -380,7 +381,8 @@ func return_hashtable (argv **C.char) map[string]string {
           pr "        defer C.free (unsafe.Pointer (c_%s))\n" n;
           pr "    }\n"
         | StringList n
-        | DeviceList n ->
+        | DeviceList n
+        | RelativePathnameList n ->
           pr "\n";
           pr "    c_%s := arg_string_list (%s)\n" n n;
           pr "    defer free_string_list (c_%s)\n" n
@@ -455,7 +457,8 @@ func return_hashtable (argv **C.char) map[string]string {
           | FileIn n | FileOut n
           | GUID n -> pr "c_%s" n
           | StringList n
-          | DeviceList n -> pr "c_%s" n
+          | DeviceList n
+          | RelativePathnameList n -> pr "c_%s" n
           | BufferIn n -> pr "c_%s, C.size_t (len (%s))" n n
           | Pointer _ -> pr "nil"
       ) args;
diff --git a/generator/haskell.ml b/generator/haskell.ml
index 96682e6..7e3e0c2 100644
--- a/generator/haskell.ml
+++ b/generator/haskell.ml
@@ -147,7 +147,8 @@ assocListOfHashtable (a:b:rest) = (a,b) : assocListOfHashtable rest
           | BufferIn n ->
               pr "withCStringLen %s $ \\(%s, %s_size) -> " n n n
           | OptString n -> pr "maybeWith withCString %s $ \\%s -> " n n
-          | StringList n | DeviceList n -> pr "withMany withCString %s $ \\%s -> withArray0 nullPtr %s $ \\%s -> " n n n n
+          | StringList n | DeviceList n | RelativePathnameList n ->
+              pr "withMany withCString %s $ \\%s -> withArray0 nullPtr %s $ \\%s -> " n n n n
           | Bool _ | Int _ | Int64 _ | Pointer _ -> ()
         ) args;
         (* Convert integer arguments. *)
@@ -161,7 +162,7 @@ assocListOfHashtable (a:b:rest) = (a,b) : assocListOfHashtable rest
             | Pathname n | Device n | Mountable n
             | Dev_or_Path n | Mountable_or_Path n
             | String n | OptString n
-            | StringList n | DeviceList n
+            | StringList n | DeviceList n | RelativePathnameList n
             | Key n | GUID n -> n
             | BufferIn n -> sprintf "%s (fromIntegral %s_size)" n n
           ) args in
@@ -224,7 +225,7 @@ and generate_haskell_prototype ~handle ?(hs = false) (ret, args, optargs) =
           pr "CString -> CInt"
         | OptString _ ->
           pr "CString"
-        | StringList _ | DeviceList _ ->
+        | StringList _ | DeviceList _ | RelativePathnameList _ ->
           pr "Ptr CString"
         | Bool _ -> pr "CInt"
         | Int _ -> pr "CInt"
@@ -267,7 +268,7 @@ and generate_haskell_prototype ~handle ?(hs = false) (ret, args, optargs) =
           pr "String"
         | OptString _ ->
           pr "Maybe String"
-        | StringList _ | DeviceList _ ->
+        | StringList _ | DeviceList _ | RelativePathnameList _ ->
           pr "[String]"
         | Bool _ -> pr "Bool"
         | Int _ -> pr "Int"
diff --git a/generator/java.ml b/generator/java.ml
index 4c89197..81fbf9b 100644
--- a/generator/java.ml
+++ b/generator/java.ml
@@ -485,7 +485,7 @@ and generate_java_prototype ?(public=false) ?(privat=false) ?(native=false)
           pr "String %s" n
       | BufferIn n ->
           pr "byte[] %s" n
-      | StringList n | DeviceList n ->
+      | StringList n | DeviceList n | RelativePathnameList n ->
           pr "String[] %s" n
       | Bool n ->
           pr "boolean %s" n
@@ -846,7 +846,7 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
             pr ", jstring j%s" n
         | BufferIn n ->
             pr ", jbyteArray j%s" n
-        | StringList n | DeviceList n ->
+        | StringList n | DeviceList n | RelativePathnameList n ->
             pr ", jobjectArray j%s" n
         | Bool n ->
             pr ", jboolean j%s" n
@@ -917,7 +917,7 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
         | BufferIn n ->
             pr "  char *%s;\n" n;
             pr "  size_t %s_size;\n" n
-        | StringList n | DeviceList n ->
+        | StringList n | DeviceList n | RelativePathnameList n ->
             pr "  size_t %s_len;\n" n;
             pr "  char **%s;\n" n
         | Bool n
@@ -979,7 +979,7 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
         | BufferIn n ->
             pr "  %s = (char *) (*env)->GetByteArrayElements (env, j%s, NULL);\n" n n;
             pr "  %s_size = (*env)->GetArrayLength (env, j%s);\n" n n
-        | StringList n | DeviceList n ->
+        | StringList n | DeviceList n | RelativePathnameList 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 "  for (i = 0; i < %s_len; ++i) {\n" n;
@@ -1044,7 +1044,7 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
             pr "    (*env)->ReleaseStringUTFChars (env, j%s, %s);\n" n n
         | BufferIn n ->
             pr "  (*env)->ReleaseByteArrayElements (env, j%s, (jbyte *) %s, 0);\n" n n
-        | StringList n | DeviceList n ->
+        | StringList n | DeviceList n | RelativePathnameList n ->
             pr "  for (i = 0; i < %s_len; ++i) {\n" n;
             pr "    jobject o = (*env)->GetObjectArrayElement (env, j%s, i);\n"
               n;
diff --git a/generator/lua.ml b/generator/lua.ml
index 630d805..ea47739 100644
--- a/generator/lua.ml
+++ b/generator/lua.ml
@@ -474,7 +474,7 @@ guestfs_lua_delete_event_callback (lua_State *L)
           pr "  size_t %s_size;\n" n;
         | OptString n ->
           pr "  const char *%s;\n" n;
-        | StringList n | DeviceList n ->
+        | StringList n | DeviceList n | RelativePathnameList n ->
           pr "  char **%s;\n" n
         | Bool n -> pr "  int %s;\n" n
         | Int n -> pr "  int %s;\n" n
@@ -504,7 +504,7 @@ guestfs_lua_delete_event_callback (lua_State *L)
             pr "  %s = luaL_checklstring (L, %d, &%s_size);\n" n i n
           | OptString n ->
             pr "  %s = luaL_optstring (L, %d, NULL);\n" n i
-          | StringList n | DeviceList n ->
+          | StringList n | DeviceList n | RelativePathnameList n ->
             pr "  %s = get_string_list (L, %d);\n" n i
           | Bool n ->
             pr "  %s = lua_toboolean (L, %d);\n" n i
@@ -564,7 +564,7 @@ guestfs_lua_delete_event_callback (lua_State *L)
         | BufferIn _ | OptString _
         | Bool _ | Int _ | Int64 _
         | Pointer _ | GUID _ -> ()
-        | StringList n | DeviceList n ->
+        | StringList n | DeviceList n | RelativePathnameList n ->
           pr "  free (%s);\n" n
       ) args;
       List.iter (
diff --git a/generator/ocaml.ml b/generator/ocaml.ml
index 5d92fcb..d8ab3b1 100644
--- a/generator/ocaml.ml
+++ b/generator/ocaml.ml
@@ -600,7 +600,7 @@ copy_table (char * const * argv)
         | BufferIn n ->
             pr "  size_t %s_size = caml_string_length (%sv);\n" n n;
             pr "  char *%s = guestfs_int_safe_memdup (g, String_val (%sv), %s_size);\n" n n n
-        | StringList n | DeviceList n ->
+        | StringList n | DeviceList n | RelativePathnameList n ->
             pr "  char **%s = ocaml_guestfs_strings_val (g, %sv);\n" n n
         | Bool n ->
             pr "  int %s = Bool_val (%sv);\n" n n
@@ -677,7 +677,7 @@ copy_table (char * const * argv)
         | OptString n | FileIn n | FileOut n | BufferIn n
         | Key n | GUID n ->
             pr "  free (%s);\n" n
-        | StringList n | DeviceList n ->
+        | StringList n | DeviceList n | RelativePathnameList n ->
             pr "  guestfs_int_free_string_list (%s);\n" n;
         | Bool _ | Int _ | Int64 _ | Pointer _ -> ()
       ) args;
@@ -850,7 +850,8 @@ and generate_ocaml_function_type ?(extra_unit = false) (ret, args, optargs) =
     | FileIn _ | FileOut _ | BufferIn _ | Key _
     | GUID _ -> pr "string -> "
     | OptString _ -> pr "string option -> "
-    | StringList _ | DeviceList _ -> pr "string array -> "
+    | StringList _ | DeviceList _ | RelativePathnameList _ ->
+        pr "string array -> "
     | Bool _ -> pr "bool -> "
     | Int _ -> pr "int -> "
     | Int64 _ | Pointer _ -> pr "int64 -> "
diff --git a/generator/perl.ml b/generator/perl.ml
index dcd180f..f1d5d6d 100644
--- a/generator/perl.ml
+++ b/generator/perl.ml
@@ -365,7 +365,8 @@ PREINIT:
                * to add 1 to the ST(x) operator.
                *)
               pr "      char *%s = SvOK(ST(%d)) ? SvPV_nolen(ST(%d)) : NULL;\n" n (i+1) (i+1)
-          | StringList n | DeviceList n -> pr "      char **%s;\n" n
+          | StringList n | DeviceList n | RelativePathnameList n ->
+              pr "      char **%s;\n" n
           | Bool n -> pr "      int %s;\n" n
           | Int n -> pr "      int %s;\n" n
           | Int64 n -> pr "      int64_t %s;\n" n
@@ -510,7 +511,8 @@ PREINIT:
         | OptString _ | Bool _ | Int _ | Int64 _
         | FileIn _ | FileOut _
         | BufferIn _ | Key _ | Pointer _ | GUID _ -> ()
-        | StringList n | DeviceList n -> pr "      free (%s);\n" n
+        | StringList n | DeviceList n | RelativePathnameList n ->
+            pr "      free (%s);\n" n
       ) args;
 
       (* Check return value for errors and return it if necessary. *)
@@ -955,6 +957,7 @@ errnos:
         | Int n -> pr "[ '%s', 'int', %d ]" n i
         | Int64 n -> pr "[ '%s', 'int64', %d ]" n i
         | Pointer (t, n) -> pr "[ '%s', 'pointer(%s)', %d ]" n t i
+        | RelativePathnameList n -> pr "[ '%s', 'string(path) list', %d ]" n i
       in
       pr "    args => [\n";
       iteri (fun i arg ->
@@ -1113,7 +1116,7 @@ and generate_perl_prototype name (ret, args, optargs) =
       | OptString n | Bool n | Int n | Int64 n | FileIn n | FileOut n
       | BufferIn n | Key n | Pointer (_, n) | GUID n ->
           pr "$%s" n
-      | StringList n | DeviceList n ->
+      | StringList n | DeviceList n | RelativePathnameList n ->
           pr "\\@%s" n
   ) args;
   List.iter (
diff --git a/generator/php.ml b/generator/php.ml
index b49bf60..82e0cd4 100644
--- a/generator/php.ml
+++ b/generator/php.ml
@@ -240,7 +240,8 @@ PHP_FUNCTION (guestfs_last_error)
             pr "  char *%s = NULL;\n" n;
             pr "  int %s_size;\n" n
         | StringList n
-        | DeviceList n ->
+        | DeviceList n
+        | RelativePathnameList n ->
             pr "  zval *z_%s;\n" n;
             pr "  char **%s;\n" n;
         | Bool n ->
@@ -284,7 +285,7 @@ PHP_FUNCTION (guestfs_last_error)
           | FileIn n | FileOut n | BufferIn n | Key n
           | GUID n -> "s"
           | OptString n -> "s!"
-          | StringList n | DeviceList n -> "a"
+          | StringList n | DeviceList n | RelativePathnameList n -> "a"
           | Bool n -> "b"
           | Int n | Int64 n -> "l"
           | Pointer _ -> ""
@@ -319,7 +320,7 @@ PHP_FUNCTION (guestfs_last_error)
         | FileIn n | FileOut n | BufferIn n | Key n
         | OptString n | GUID n ->
             pr ", &%s, &%s_size" n n
-        | StringList n | DeviceList n ->
+        | StringList n | DeviceList n | RelativePathnameList n ->
             pr ", &z_%s" n
         | Bool n ->
             pr ", &%s" n
@@ -372,7 +373,8 @@ PHP_FUNCTION (guestfs_last_error)
             pr "\n"
         | BufferIn n -> ()
         | StringList n
-        | DeviceList n ->
+        | DeviceList n
+        | RelativePathnameList n ->
             pr "  %s = get_stringlist (z_%s);\n" n n;
             pr "\n"
         | Bool _ | Int _ | Int64 _ -> ()
@@ -453,7 +455,8 @@ PHP_FUNCTION (guestfs_last_error)
         | OptString n | GUID n -> ()
         | BufferIn n -> ()
         | StringList n
-        | DeviceList n ->
+        | DeviceList n
+        | RelativePathnameList n ->
             pr "  guestfs_efree_stringlist (%s);\n" n;
             pr "\n"
         | Bool _ | Int _ | Int64 _ | Pointer _ -> ()
diff --git a/generator/python.ml b/generator/python.ml
index 1e043fc..b8329a5 100644
--- a/generator/python.ml
+++ b/generator/python.ml
@@ -292,7 +292,7 @@ put_table (char * const * const argv)
         | BufferIn n ->
             pr "  const char *%s;\n" n;
             pr "  Py_ssize_t %s_size;\n" n
-        | StringList n | DeviceList n ->
+        | StringList n | DeviceList n | RelativePathnameList n ->
             pr "  PyObject *py_%s;\n" n;
             pr "  char **%s = NULL;\n" n
         | Bool n -> pr "  int %s;\n" n
@@ -326,7 +326,7 @@ put_table (char * const * const argv)
         | Dev_or_Path _ | Mountable_or_Path _ | String _ | Key _
         | FileIn _ | FileOut _ | GUID _ -> pr "s"
         | OptString _ -> pr "z"
-        | StringList _ | DeviceList _ -> pr "O"
+        | StringList _ | DeviceList _ | RelativePathnameList _ -> pr "O"
         | Bool _ -> pr "i" (* XXX Python has booleans? *)
         | Int _ -> pr "i"
         | Int64 _ ->
@@ -349,7 +349,8 @@ put_table (char * const * const argv)
         | Dev_or_Path n | Mountable_or_Path n | String n | Key n
         | FileIn n | FileOut n | GUID n -> pr ", &%s" n
         | OptString n -> pr ", &%s" n
-        | StringList n | DeviceList n -> pr ", &py_%s" n
+        | StringList n | DeviceList n | RelativePathnameList n ->
+            pr ", &py_%s" n
         | Bool n -> pr ", &%s" n
         | Int n -> pr ", &%s" n
         | Int64 n -> pr ", &%s" n
@@ -372,7 +373,7 @@ put_table (char * const * const argv)
         | Dev_or_Path _ | Mountable_or_Path _ | String _ | Key _
         | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
         | BufferIn _ | GUID _ -> ()
-        | StringList n | DeviceList n ->
+        | StringList n | DeviceList n | RelativePathnameList n ->
             pr "  %s = get_string_list (py_%s);\n" n n;
             pr "  if (!%s) goto out;\n" n
         | Pointer (_, n) ->
@@ -522,7 +523,7 @@ put_table (char * const * const argv)
         | Dev_or_Path _ | Mountable_or_Path _ | String _ | Key _
         | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
         | BufferIn _ | Pointer _ | GUID _ -> ()
-        | StringList n | DeviceList n ->
+        | StringList n | DeviceList n | RelativePathnameList n ->
             pr "  free (%s);\n" n
       ) args;
 
@@ -829,7 +830,7 @@ class GuestFS(object):
         | Dev_or_Path _ | Mountable_or_Path _ | String _ | Key _
         | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
         | BufferIn _ | GUID _ -> ()
-        | StringList n | DeviceList n ->
+        | StringList n | DeviceList n | RelativePathnameList n ->
           pr "        %s = list (%s)\n" n n
         | Pointer (_, n) ->
           pr "        %s = %s.c_pointer()\n" n n
diff --git a/generator/ruby.ml b/generator/ruby.ml
index cb187b0..5e22ed0 100644
--- a/generator/ruby.ml
+++ b/generator/ruby.ml
@@ -582,7 +582,7 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
           pr "  size_t %s_size = RSTRING_LEN (%sv);\n" n n
         | OptString n ->
           pr "  const char *%s = !NIL_P (%sv) ? StringValueCStr (%sv) : NULL;\n" n n n
-        | StringList n | DeviceList n ->
+        | StringList n | DeviceList n | RelativePathnameList n ->
           pr "  char **%s;\n" n;
           pr "  Check_Type (%sv, T_ARRAY);\n" n;
           pr "  {\n";
@@ -677,7 +677,7 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
         | Dev_or_Path _ | Mountable_or_Path _ | String _ | Key _
         | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
         | BufferIn _ | Pointer _ | GUID _ -> ()
-        | StringList n | DeviceList n ->
+        | StringList n | DeviceList n | RelativePathnameList n ->
             pr "  free (%s);\n" n
       ) args;
 
diff --git a/generator/tests_c_api.ml b/generator/tests_c_api.ml
index 1522eff..c5af42f 100644
--- a/generator/tests_c_api.ml
+++ b/generator/tests_c_api.ml
@@ -419,7 +419,8 @@ and generate_test_command_call ?(expect_error = false) ?test ?ret test_name cmd=
     | DeviceList _, "", sym ->
       pr "  const char *const %s[1] = { NULL };\n" sym
     | StringList _, arg, sym
-    | DeviceList _, arg, sym ->
+    | DeviceList _, arg, sym
+    | RelativePathnameList _, arg, sym ->
       let strs = string_split " " arg in
       iteri (
         fun i str ->
@@ -527,7 +528,9 @@ and generate_test_command_call ?(expect_error = false) ?test ?ret test_name cmd=
     | GUID _, _, sym -> pr ", %s" sym
     | BufferIn _, _, sym -> pr ", %s, %s_size" sym sym
     | FileOut _, arg, _ -> pr ", \"%s\"" (c_quote arg)
-    | StringList _, _, sym | DeviceList _, _, sym -> pr ", (char **) %s" sym
+    | StringList _, _, sym | DeviceList _, _, sym
+    | RelativePathnameList _, _, sym ->
+      pr ", (char **) %s" sym
     | Int _, arg, _ ->
       let i =
         try int_of_string arg
diff --git a/generator/types.ml b/generator/types.ml
index 83a6a98..156df3b 100644
--- a/generator/types.ml
+++ b/generator/types.ml
@@ -190,6 +190,10 @@ and argt =
      * guestfs_int_validate_guid.
      *)
   | GUID of string
+    (* List of file names, where the list cannot be NULL, and each
+     * filename cannot be NULL, empty, or an absolute path.
+     *)
+  | RelativePathnameList of string
 
 and optargs = optargt list
 
diff --git a/generator/utils.ml b/generator/utils.ml
index 1b00ce5..5b97b2b 100644
--- a/generator/utils.ml
+++ b/generator/utils.ml
@@ -254,7 +254,7 @@ let name_of_argt = function
   | Mountable_or_Path n | String n | OptString n
   | StringList n | DeviceList n | Bool n | Int n | Int64 n
   | FileIn n | FileOut n | BufferIn n | Key n | Pointer (_, n)
-  | GUID n -> n
+  | GUID n | RelativePathnameList n -> n
 
 let name_of_optargt = function
   | OBool n | OInt n | OInt64 n | OString n | OStringList n -> n
diff --git a/generator/xdr.ml b/generator/xdr.ml
index 37a52b7..aef5c1e 100644
--- a/generator/xdr.ml
+++ b/generator/xdr.ml
@@ -115,7 +115,8 @@ let generate_xdr () =
           | Key n | GUID n ->
             pr "  string %s<>;\n" n
           | OptString n -> pr "  guestfs_str *%s;\n" n
-          | StringList n | DeviceList n -> pr "  guestfs_str %s<>;\n" n
+          | StringList n | DeviceList n | RelativePathnameList n ->
+            pr "  guestfs_str %s<>;\n" n
           | Bool n -> pr "  bool %s;\n" n
           | Int n -> pr "  int %s;\n" n
           | Int64 n -> pr "  int64_t %s;\n" n
-- 
2.1.0




More information about the Libguestfs mailing list