Definition write_file (bytes: list memval): file*nat :=
match write_file_aux bytes (get_size f) fptr with (contents, nwritten) =>
(mkfile (get_size f + (fptr + nwritten - get_size f)) (get_contents f), nwritten)
end.
End read_write.
Section fs_read_write.
Variables (fsys: fs) (fd: int).
Definition fs_read (nbytes: nat): option (list memval) :=
match get_file fsys fd, get_fptr fsys fd with
| Some f, Some cur => Some (read_file f cur nbytes)
| _, _ => None
end.
Definition fs_write (bytes: list memval): option (nat(*nbytes written*)*fs) :=
match get_file fsys fd, get_fptr fsys fd, get_fmode fsys fd with
| Some file, Some cur, Some md =>
if fwritable md then
match write_file file cur bytes with (new_file, nbytes_written) =>
Some (nbytes_written,
mkfs (get_max_fds fsys)
(mkfsdata (fun i => if Int.eq fd i then Some (md, cur + nbytes_written)
else get_fdtable fsys i)
(fun i => if Int.eq fd i then Some new_file
else get_fcache fsys i)
(get_fnames fsys))
(get_fstore fsys))
end
else None
| _, _, _ => None
end.

(* Specifications: *)
Lemma fs_write_length bytes n fs: fs_write bytes = Some (n, fs) -> n=length bytes.
End fs_read_write.