package core_unix
Unix-specific portions of Core
Install
Dune Dependency
Authors
Maintainers
Sources
v0.15.2.tar.gz
sha256=486d0e954603960fa081b3fd23e3cc3e50ac0892544acd35f9c2919c4bf5f67b
doc/src/core_unix.filename_unix/filename_unix.ml.html
Source file filename_unix.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
open! Core open! Import open Core.Filename let create_arg_type ?key of_string = Core.Command.Arg_type.create ?key of_string ~complete:(fun _ ~part -> let completions = (* `compgen -f` handles some fiddly things nicely, e.g. completing "foo" and "foo/" appropriately. *) let command = sprintf "bash -c 'compgen -f %s'" part in let chan_in = Unix.open_process_in command in let completions = In_channel.input_lines chan_in in ignore (Unix.close_process_in chan_in); List.map (List.sort ~compare:String.compare completions) ~f:(fun comp -> match Sys_unix.is_directory comp with | `Yes -> comp ^ "/" | `No | `Unknown -> comp) in match completions with | [dir] when String.is_suffix dir ~suffix:"/" -> (* If the only match is a directory, we fake out bash here by creating a bogus entry, which the user will never see - it forces bash to push the completion out to the slash. Then when the user hits tab again, they will be at the end of the line, at the directory with a slash and completion will continue into the subdirectory. *) [dir; dir ^ "x"] | _ -> completions ) let arg_type = create_arg_type Fn.id external realpath : string -> string = "core_unix_realpath" let prng = Random.State.make_self_init ~allow_in_tests:true () (* We want [random_bits ()] to be thread-safe. We think it's currently safe because [Random.State.bits] does no allocation. (note even [Random.State.t] is implemented as a [lazy], this lazy will always be forced because [make_self_init] constructs it with [Lazy.from_val]) *) let random_bits () = Random.State.bits prng (* try up to 1000 times to not get a Sys_error when opening a temp file / name: *) let retry ?(in_dir=temp_dir_name) ~f prefix suffix = let escape s = String.map s ~f:(function | '/' | '\'' | '\000' | '\n' | '-' -> '_' | c -> c) in let prefix = escape prefix in let suffix = escape suffix in let rec try_name counter = let name = let rnd = random_bits () land 0xFF_FFFF in (Printf.sprintf "%s.tmp.%06x%s" prefix rnd suffix) in let name = concat in_dir name in try f name with Sys_error _ | Unix.Unix_error _ as e -> if Int.(counter >= 1000) then raise e else try_name (counter + 1) in try_name 0 (* these functions are the same as the ones in the std lib but you can override the temporary directory you are working in. They also try the exact filename specified by the user before reverting to the "try with" machinery. Another difference is that we allocate the [prng] eagerly at program startup instead of using [lazy]. *) let temp_dir ?(perm=0o700) ?in_dir prefix suffix = retry ?in_dir prefix suffix ~f:(fun name -> Unix.mkdir name perm; name) let open_temp_file ?(perm=0o600) ?in_dir prefix suffix = retry ?in_dir prefix suffix ~f:(fun name -> (name, Out_channel.create ~perm ~fail_if_exists:true name)) let open_temp_file_fd ?(perm=0o600) ?in_dir prefix suffix = retry ?in_dir prefix suffix ~f:(fun name -> (name, UnixLabels.openfile ~perm ~mode:[O_EXCL; O_CREAT; O_RDWR] name)) let temp_file ?perm ?in_dir prefix suffix = let (name, oc) = open_temp_file ?perm ?in_dir prefix suffix in Out_channel.close oc; name
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>