# # patch "glib/gspawn.ml" # from [be2cb8b8a4001b5acb7a292b25b19fd9a101d20a] # to [bfd9e189f852d27c821ac88b0e77d3485f2716c1] # # patch "glib/gspawn.mli" # from [9b0074abfd7c5494a41b430c15c8c7d324fafb83] # to [c43ee9e417dfec498f6b7fa63bfb6ba98257b410] # # patch "glib/ocaml-gspawn.c" # from [8f8b77c9930e734c9c2184481ea5bb368ccb3c16] # to [d7971112446d9d6b160a5ba3d902a6b32a256122] # --- glib/gspawn.ml +++ glib/gspawn.ml @@ -80,7 +80,11 @@ ?child_setup:(unit -> unit) -> flags:spawn_flags list -> string list -> status * string * string = "ml_g_spawn_sync" - + +external command_line_sync : + string -> status * string * string = "ml_g_spawn_command_line_sync" +external command_line_async : string -> unit = "ml_g_spawn_command_line_async" + type source_id external add_child_watch : ?prio:int -> pid -> (int -> unit) -> source_id = "ml_g_add_child_watch_full" external remove_watch : source_id -> unit = "ml_g_source_remove" --- glib/gspawn.mli +++ glib/gspawn.mli @@ -68,6 +68,13 @@ external close_pid : pid -> unit = "ml_g_spawn_close_pid" +external command_line_sync : + string -> status * string * string = "ml_g_spawn_command_line_sync" +(** @raise Error if the spawn fails *) + +external command_line_async : string -> unit = "ml_g_spawn_command_line_async" +(** @raise Error if the spawn fails *) + type source_id external add_child_watch : ?prio:int -> pid -> (int -> unit) -> source_id = "ml_g_add_child_watch_full" external remove_watch : source_id -> unit = "ml_g_source_remove" --- glib/ocaml-gspawn.c +++ glib/ocaml-gspawn.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "wrappers.h" #include "ml_glib.h" @@ -161,6 +162,26 @@ return r; } +static value +convert_sync_status (int exit_status, gchar *standard_output, gchar *standard_error) +{ + CAMLparam0(); + CAMLlocal4(res, status, out, err); + + status = convert_exit_status (exit_status); + out = copy_string (standard_output ? standard_output : ""); + g_free (standard_output); + err = copy_string (standard_error ? standard_error : ""); + g_free (standard_error); + + res = alloc_small (3, 0); + Field (res, 0) = status; + Field (res, 1) = out; + Field (res, 2) = err; + + CAMLreturn (res); +} + CAMLprim value ml_g_spawn_sync (value o_working_directory, value o_envp, @@ -186,6 +207,7 @@ standard_output = NULL; standard_error = NULL; + caml_enter_blocking_section (); g_spawn_sync (working_directory, argv, envp, @@ -196,6 +218,7 @@ &standard_error, &exit_status, &error); + caml_leave_blocking_section (); g_free (working_directory); g_strfreev (argv); @@ -204,35 +227,55 @@ if (error) ml_raise_gerror (error); - { - CAMLparam0(); - CAMLlocal4(res, status, out, err); - - status = convert_exit_status (exit_status); - if (standard_output != NULL) - { - out = copy_string (standard_output); - g_free (standard_output); - } - else - out = copy_string (""); - if (standard_error != NULL) - { - err = copy_string (standard_error); - g_free (standard_error); - } - else - err = copy_string (""); + return convert_sync_status (exit_status, standard_output, standard_error); +} - res = alloc_small (3, 0); - Field (res, 0) = status; - Field (res, 1) = out; - Field (res, 2) = err; +CAMLprim value +ml_g_spawn_command_line_sync (value cmd) +{ + GError *error = NULL; + gchar *command; + gchar *standard_output; + gchar *standard_error; + gint exit_status; - CAMLreturn (res); - } + standard_output = NULL; + standard_error = NULL; + + command = copy_caml_string (cmd); + caml_enter_blocking_section (); + g_spawn_command_line_sync (command, + &standard_output, + &standard_error, + &exit_status, + &error); + caml_leave_blocking_section (); + g_free (command); + + if (error) + ml_raise_gerror (error); + + return convert_sync_status (exit_status, standard_output, standard_error); } +CAMLprim value +ml_g_spawn_command_line_async (value cmd) +{ + GError *error = NULL; + gchar *command; + + command = copy_caml_string (cmd); + caml_enter_blocking_section (); + g_spawn_command_line_async (command, &error); + caml_leave_blocking_section (); + g_free (command); + + if (error) + ml_raise_gerror (error); + + return Val_unit; +} + #if defined (G_OS_UNIX) # define GPid_val(v) (GPid)Int_val(v) #elif defined (G_OS_WIN32)