+ (* Load or initialize the variables. *)
+ let variables_file = sprintf "%s/variables" !jobsdir in
+ state :=
+ try
+ let chan = open_in variables_file in
+ let r = load_variables !state chan in
+ close_in chan;
+ r
+ with
+ | Sys_error _ ->
+ Whenstate.set_variable !state "JOBSERIAL" (T_int zero_big_int)
+
+(* Try to load the variables from the file. If the file exists and
+ * cannot be read, raise an exception.
+ *)
+and load_variables state chan =
+ let signature = input_line chan in
+ if signature = "WHENJOBS VARIABLES VERSION 1" then (
+ let variables : variables_file_v1 = input_value chan in
+ List.fold_left (
+ fun state (n, v) ->
+ Whenstate.set_variable state n (variable_of_variable_v1 v)
+ ) state variables
+ ) else (* in future, other signatures, but for now ... *)
+ failwith (sprintf "cannot read variables file: invalid signature: %s"
+ signature)
+
+and save_variables () =
+ let variables_file = sprintf "%s/variables" !jobsdir in
+ let new_file = variables_file ^ ".new" in
+ let chan = open_out new_file in
+ fprintf chan "WHENJOBS VARIABLES VERSION 1\n";
+ let variables = Whenstate.get_variables !state in
+ let variables =
+ List.map (fun (n, v) -> n, variable_v1_of_variable v) variables in
+ output_value chan variables;
+
+ (* Try to arrange that the new file is updated atomically. *)
+ flush chan;
+ Netsys_posix.fsync (descr_of_out_channel chan);
+ close_out chan;
+ rename new_file variables_file