forked from
patrick.sirref.org/merry
Shells in OCaml
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