(* clear file *) let trunc inode = assert (inode.stats.st_kind == S_REG); if inode.stats.st_size > max_file_size then raise (File_system_error "Inconsistant file system"); let rec free_blocks n = if n != 0 then begin if inode.blocktbl.(n) != 0 then begin free_block inode.blocktbl.(n); inode.blocktbl.(n) <- 0 end; free_blocks (n-1) end in free_blocks (inode.stats.st_size / D.block_size + 1); inode.stats.st_size <- 0;; let openfile name flags = let inode = namei name in if inode.stats.st_size > max_file_size then raise (File_system_error "Inconsistant file system"); let block = ref 0 in let pos = ref 0 in let desc_flag = ref None in let rec read flags = match flags with O_RDONLY :: tail -> begin match !desc_flag with None -> desc_flag := Some O_RDONLY | _ -> raise (File_system_exception "Invalid open flags") end; read tail | O_WRONLY :: tail -> begin match !desc_flag with None -> desc_flag := Some O_WRONLY | _ -> raise (File_system_exception "Invalid open flags") end; read tail | O_RDWR :: tail -> begin match !desc_flag with None -> desc_flag := Some O_RDWR | _ -> raise (File_system_exception "Invalid open flags") end; read tail | O_APPEND :: tail -> block := inode.stats.st_size / D.block_size; pos := inode.stats.st_size mod D.block_size; read tail | O_TRUNC :: tail -> trunc inode; block := 0; pos := 0; read tail | _ :: tail -> raise (File_system_exception "Not supported flag") | [] -> () in read flags; let flag = match !desc_flag with None -> raise (File_system_exception "Invalid open flags") | Some mode -> mode in inode.reference_number <- inode.reference_number + 1; { inode = inode; block = !block; pos = !pos; flag = flag };; |