Shells in OCaml
at main 163 lines 4.4 kB view raw
1module Parameter = struct 2 type t = 3 | String of string 4 | Number of string 5 | Special of string 6 | Null (** Possible shell parameters *) 7end 8 9module type State = sig 10 type t 11 (** State for the shell and operating system that is carried from one 12 evaluation step to the next. *) 13 14 val cwd : t -> Fpath.t 15 (** The current working directory *) 16 17 val set_cwd : t -> Fpath.t -> t 18 (** Update the cwd *) 19 20 val expand : t -> [ `Tilde ] -> string 21 (** Expansions *) 22 23 val lookup : t -> param:string -> Ast.word_cst option 24 (** Parameter lookup. [None] means [unset]. *) 25 26 val update : 27 ?export:bool -> 28 ?readonly:bool -> 29 t -> 30 param:string -> 31 Ast.word_cst -> 32 (t, string) result 33 (** Update the state with a new parameter mapping and whether or not it should 34 exported to the environment (default false). *) 35 36 val remove : param:string -> t -> bool * t 37 (** [remove ~param t] removes [param] from [t] if it exists. [bool] is [true] 38 if a removal took place. *) 39 40 val exports : t -> (string * Ast.word_cst) list 41 (** All of the variables that must be exported to the environment *) 42 43 val readonly : t -> (string * Ast.word_cst) list 44 (** All of the variables that must be exported to the environment *) 45 46 val pp_readonly : t Fmt.t 47 val pp_export : t Fmt.t 48 val dump : t Fmt.t 49end 50 51type redirect = 52 | Redirect of int * Eio_unix.Fd.t * Eio_unix.Private.Fork_action.blocking 53 | Close of Eio_unix.Fd.t 54 55type exec_mode = 56 | Switched of Eio.Switch.t 57 | Async 58 (** How to execute a process. This mainly controls what happens at the end 59 of the running a script or some commands. When a process is 60 "switched", we use the same semantics as Eio, we sigkill the process 61 and cleanup. If the process is complete Async then we do not wait. 62 This allows us to exit before some of our child processes, which is a 63 requirement for implementing the semantics of a shell! *) 64 65module type Exec = sig 66 type t 67 (** An executor for commands *) 68 69 type process 70 71 val signal : process -> int -> unit 72 val pid : process -> int 73 74 val exec : 75 ?delay_reap:unit Eio.Promise.t -> 76 ?fork_actions:Eio_unix__.Fork_action.t list -> 77 ?fds:redirect list -> 78 ?stdin:_ Eio.Flow.source -> 79 ?stdout:_ Eio.Flow.sink -> 80 ?stderr:_ Eio.Flow.sink -> 81 ?env:(string * string) list -> 82 mode:exec_mode -> 83 pgid:int -> 84 cwd:Eio.Fs.dir_ty Eio.Path.t -> 85 executable:string -> 86 t -> 87 string list -> 88 (process, int * [ `Not_found ]) result 89 (** Run a command in a child process *) 90 91 val await : process -> unit Exit.t 92end 93 94module type Job = sig 95 type t 96 (** A job for job control *) 97 98 type process 99 100 val get_reaper : t -> unit Eio.Promise.t * unit Eio.Promise.u 101 102 val make : 103 int -> 104 [ `Built_in of unit Exit.t 105 | `Error of int 106 | `Exit of unit Exit.t 107 | `Process of process 108 | `Rdr of unit Exit.t ] 109 list -> 110 t 111 112 val get_id : t -> int 113 (** Get the ID of the job. *) 114 115 val set_id : int -> t -> t 116 (** Set the ID of the job. *) 117 118 val add_process : process -> t -> t 119 val add_built_in : unit Exit.t -> t -> t 120 val add_error : int -> t -> t 121 val add_rdr : unit Exit.t -> t -> t 122 val add_exit : unit Exit.t -> t -> t 123 124 val size : t -> int 125 (** Number of processes in this job *) 126 127 val await_exit : pipefail:bool -> interactive:bool -> t -> unit Exit.t 128 (** Given a job, [await_exit] will wait for the job to finish and return the 129 exit based on the various options passed in. *) 130end 131 132module type History = sig 133 type t 134 (** A history of commands *) 135 136 val empty : t 137 (** The empty history *) 138 139 type entry 140 (** A history entry, usually a command. *) 141 142 val make_entry : string -> entry 143 (** Construct an entry given a command. *) 144 145 val add : entry -> t -> t 146 (** Add an entry to the history. *) 147 148 val save : t -> _ Eio.Path.t -> unit 149 (** [save t path] should save history [t] to [path]. *) 150 151 val load : _ Eio.Path.t -> t 152 (** [load path] should try to read a history from [path]. *) 153 154 val history : command:string -> t -> t 155 (** [history ~command t] should return some subset of [t] (perhaps all of [t]) 156 based on the current [command] to be used for history searching. *) 157 158 val commands : t -> string list 159 (** Converts your (perhaps richer) history to just a series of commands. *) 160 161 val pp : t Fmt.t 162 (** A pretty printer for the commands *) 163end