End alloc_fd.
Definition MAX_FDS := Int.repr (Z_of_nat 1024).
Definition mount_fs (fstore: forall (name: int), option file) :=
mkfs MAX_FDS (mkfsdata (fun _:int => None) (fun _:int => None) (fun _:int => None)) fstore.
Section FSExtension.
Variables
(Z cT genv: Type)
(csem: CoopCoreSem genv cT)
(init_world: Z).
Local Open Scope nat_scope.
Inductive xT: Type := mkxT: forall (z: Z) (c: cT) (fs: fs), xT.
Section selectors.
Variable (s: xT).
Definition get_ext := match s with mkxT z _ _ => z end.
Definition get_core := match s with mkxT _ c _ => c end.
Definition get_fs := match s with mkxT _ _ fs => fs end.
End selectors.
Definition proj_core (i: nat) (s: xT) := if eq_nat_dec i 0 then Some (get_core s) else None.
Definition active := fun _: xT => 0.
Definition runnable := fun (s: xT) =>
match at_external csem (get_core s), halted csem (get_core s) with
| None, None => true
| _, _ => false
end.
Definition proj_zint (s: xT) := get_fs s.
Definition proj_zext (z: fs*Z) := snd z.
Definition zmult := @pair fs Z.
(*SYS_READ/WRITE_SIG: fd, buf, count*)
Notation SYS_READ_SIG := (mksignature (AST.Tint::AST.Tint::AST.Tint::nil) (Some AST.Tint)).
Notation SYS_WRITE_SIG := (mksignature (AST.Tint::AST.Tint::AST.Tint::nil) (Some AST.Tint)).
(*SYS_OPEN_SIG: name*)
Notation SYS_OPEN_SIG := (mksignature (AST.Tint::AST.Tint::nil) (Some AST.Tint)).
Notation SYS_READ := (EF_external 3%positive SYS_READ_SIG).
Notation SYS_WRITE :=  (EF_external 4%positive SYS_WRITE_SIG).
Notation SYS_OPEN := (EF_external 8%positive SYS_OPEN_SIG).
Definition int2fmode (i: int): option fmode :=
if Int.eq i Int.zero then Some RDONLY
else if Int.eq i Int.one then Some WRONLY
else if Int.eq i (Int.repr 3%Z) then Some RDWR
else None.
Definition val2oint (v: val): option int :=
match v with
| Vundef => None
| Vint i => Some i
| Vfloat _ => None
| Vptr _ _ => None
| Vlong _ => None (*LENB: is this ok, Gordon?*)
end.
Definition address := (block * int)%type.
Definition val2oadr (v: val): option address :=
match v with
| Vundef => None
| Vint i => None
| Vlong i => None
| Vfloat _ => None
| Vptr b ofs => Some (b, ofs)
end.
Definition val2omode (mode: val): option fmode :=
match val2oint mode with Some i => int2fmode i | None => None end.
Section read_write.
Variable (f: file) (fptr: nat).
Let contents := get_contents f.
Fixpoint read_file_aux (nbytes sz cur: nat): list memval :=
match nbytes with
| O => nil
| S nbytes' => if eq_nat_dec sz cur then nil
else contents cur :: read_file_aux nbytes' sz (S cur)
end.

(* Specifications: *)
Lemma read_file_aux_length nbytes sz cur: length (read_file_aux nbytes sz cur) <= nbytes.
Lemma read_file_aux_end nbytes sz: read_file_aux nbytes sz sz = nil.
Lemma read_file_aux_id nbytes sz cur:
read_file_aux nbytes sz cur =
read_file_aux (length (read_file_aux nbytes sz cur)) sz cur.
Lemma read_file_aux_length2 nbytes sz cur:
length (read_file_aux nbytes sz cur) =
length (read_file_aux (length (read_file_aux nbytes sz cur)) sz cur).
Lemma loadbytes_read_file_le m b ofs nbytes0 nbytes sz cur:
nbytes0 <= nbytes ->
Mem.loadbytes m b ofs (Z_of_nat nbytes) = Some (read_file_aux nbytes sz cur) ->
Mem.loadbytes m b ofs (Z_of_nat nbytes0) = Some (read_file_aux nbytes0 sz cur).