X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=blobdiff_plain;f=src%2Fgenerator.ml;h=9a9c168ed630f8a3583306edae18cca7440dcf80;hp=a7093768eaac7cbc8603efc0b5ab5b685cc59e0e;hb=f7e6ffa8a82f8a7a214a47ff32f46d9e893902d8;hpb=afca1dba5eeb989c231a22df26e48f0967387547 diff --git a/src/generator.ml b/src/generator.ml index a709376..9a9c168 100755 --- a/src/generator.ml +++ b/src/generator.ml @@ -339,8 +339,12 @@ return the default path."); "set autosync mode", "\ If C is true, this enables autosync. Libguestfs will make a -best effort attempt to run C when the handle is closed -(also if the program exits without closing handles)."); +best effort attempt to run C followed by +C when the handle is closed +(also if the program exits without closing handles). + +This is disabled by default (except in guestfish where it is +enabled by default)."); ("get_autosync", (RBool "autosync", []), -1, [], [], @@ -1074,6 +1078,20 @@ Some internal mounts are not shown."); ("umount_all", (RErr, []), 47, [FishAlias "unmount-all"], [InitBasicFS, TestOutputList ( [["umount_all"]; + ["mounts"]], []); + (* check that umount_all can unmount nested mounts correctly: *) + InitEmpty, TestOutputList ( + [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ",10 ,20 ,"]; + ["mkfs"; "ext2"; "/dev/sda1"]; + ["mkfs"; "ext2"; "/dev/sda2"]; + ["mkfs"; "ext2"; "/dev/sda3"]; + ["mount"; "/dev/sda1"; "/"]; + ["mkdir"; "/mp1"]; + ["mount"; "/dev/sda2"; "/mp1"]; + ["mkdir"; "/mp1/mp2"]; + ["mount"; "/dev/sda3"; "/mp1/mp2"]; + ["mkdir"; "/mp1/mp2/mp3"]; + ["umount_all"]; ["mounts"]], [])], "unmount all filesystems", "\ @@ -1804,6 +1822,13 @@ let rec string_split sep str = s' :: string_split sep s'' ) +let files_equal n1 n2 = + let cmd = sprintf "cmp -s %s %s" (Filename.quote n1) (Filename.quote n2) in + match Sys.command cmd with + | 0 -> true + | 1 -> false + | i -> failwithf "%s: failed with error code %d" cmd i + let rec find_map f = function | [] -> raise Not_found | x :: xs -> @@ -2767,9 +2792,14 @@ and generate_daemon_actions () = | String n -> pr " %s = args.%s;\n" n n | OptString n -> pr " %s = args.%s ? *args.%s : NULL;\n" n n n | StringList n -> - pr " args.%s.%s_val = realloc (args.%s.%s_val, sizeof (char *) * (args.%s.%s_len+1));\n" n n n n n n; - pr " args.%s.%s_val[args.%s.%s_len] = NULL;\n" n n n n; - pr " %s = args.%s.%s_val;\n" n n n + pr " %s = realloc (args.%s.%s_val,\n" n n n; + pr " sizeof (char *) * (args.%s.%s_len+1));\n" n n; + pr " if (%s == NULL) {\n" n; + pr " reply_with_perror (\"realloc\");\n"; + pr " goto done;\n"; + pr " }\n"; + pr " %s[args.%s.%s_len] = NULL;\n" n n n; + pr " args.%s.%s_val = %s;\n" n n n; | Bool n -> pr " %s = args.%s;\n" n n | Int n -> pr " %s = args.%s;\n" n n | FileIn _ | FileOut _ -> () @@ -3899,7 +3929,7 @@ and generate_fish_completion () = #ifdef HAVE_LIBREADLINE -static const char *commands[] = { +static const char *const commands[] = { "; (* Get the commands and sort them, including the aliases. *) @@ -4329,7 +4359,7 @@ copy_table (char * const * argv) pr " %sv != Val_int (0) ? String_val (Field (%sv, 0)) : NULL;\n" n n | StringList n -> - pr " char **%s = ocaml_guestfs_strings_val (%sv);\n" n n + pr " char **%s = ocaml_guestfs_strings_val (g, %sv);\n" n n | Bool n -> pr " int %s = Bool_val (%sv);\n" n n | Int n -> @@ -4551,12 +4581,13 @@ XS_unpack_charPtrPtr (SV *arg) { AV *av; I32 i; - if (!arg || !SvOK (arg) || !SvROK (arg) || SvTYPE (SvRV (arg)) != SVt_PVAV) { + if (!arg || !SvOK (arg) || !SvROK (arg) || SvTYPE (SvRV (arg)) != SVt_PVAV) croak (\"array reference expected\"); - } av = (AV *)SvRV (arg); - ret = (char **)malloc (av_len (av) + 1 + 1); + ret = malloc (av_len (av) + 1 + 1); + if (!ret) + croak (\"malloc failed\"); for (i = 0; i <= av_len (av); i++) { SV **elem = av_fetch (av, i, 0); @@ -5550,7 +5581,8 @@ static VALUE ruby_guestfs_close (VALUE gv) pr " {\n"; pr " int i, len;\n"; pr " len = RARRAY_LEN (%sv);\n" n; - pr " %s = malloc (sizeof (char *) * (len+1));\n" n; + pr " %s = guestfs_safe_malloc (g, sizeof (char *) * (len+1));\n" + n; pr " for (i = 0; i < len; ++i) {\n"; pr " VALUE v = rb_ary_entry (%sv, i);\n" n; pr " %s[i] = StringValueCStr (v);\n" n; @@ -6070,7 +6102,7 @@ Java_com_redhat_et_libguestfs_GuestFS__1close pr " %s = (*env)->GetStringUTFChars (env, j%s, NULL);\n" n n | StringList n -> pr " %s_len = (*env)->GetArrayLength (env, j%s);\n" n n; - pr " %s = malloc (sizeof (char *) * (%s_len+1));\n" n n; + pr " %s = guestfs_safe_malloc (g, sizeof (char *) * (%s_len+1));\n" n n; pr " for (i = 0; i < %s_len; ++i) {\n" n; pr " jobject o = (*env)->GetObjectArrayElement (env, j%s, i);\n" n; @@ -6220,8 +6252,17 @@ let output_to filename = let close () = close_out !chan; chan := stdout; - Unix.rename filename_new filename; - printf "written %s\n%!" filename; + + (* Is the new file different from the current file? *) + if Sys.file_exists filename && files_equal filename filename_new then + Unix.unlink filename_new (* same, so skip it *) + else ( + (* different, overwrite old one *) + (try Unix.chmod filename 0o644 with Unix.Unix_error _ -> ()); + Unix.rename filename_new filename; + Unix.chmod filename 0o444; + printf "written %s\n%!" filename; + ) in close