├── .travis.yml ├── fs_test ├── lib │ ├── old │ │ ├── Makefile.common │ │ ├── Makefile.depend │ │ └── .depend.linear │ ├── .gitignore │ ├── Makefile.doc │ ├── Makefile.toplevel │ ├── bash_env.sh │ ├── mk_fs_test_version.sh │ ├── .depend │ ├── Makefile.srcs │ ├── Makefile │ ├── .interactive │ ├── fs_test_util.mli │ ├── checkLib_with_posix.ml │ ├── checkLib_with_posix.mli │ ├── fs_path.mli │ ├── fs_test_util.ml │ ├── diff.mli │ ├── posix_ops.mli │ ├── checklib_shared_types.mli │ ├── stat.mli │ ├── diff.ml │ ├── fs_path.ml │ └── fs_test_system.mli ├── repro │ ├── .gitignore │ ├── rmdir_cwd_spin.c │ └── rename_leak.c ├── example_traces │ ├── simple_dump-int.trace │ ├── interp_state_fail_none-int.trace │ ├── interp_state_fail_special-int.trace │ ├── interp_warn_state_mixed-int.trace │ ├── interp_warn_dump_failed-int.trace │ ├── interp_label_fail_dump-result-int.trace │ ├── interleave-check.trace.expected.stderr │ ├── interp_state_fail_none-int.trace.expected.stderr │ ├── no_errors-check.trace.expected.stderr │ ├── interp_dump_failed-check.trace │ ├── simple_dump_missing-check.trace │ ├── no_errors-check.trace │ ├── interp_dump_failed-check.trace.expected.stderr │ ├── check_state_fail_special-check.trace │ ├── unexpected-check.trace │ ├── unexpected-check.trace.expected.stderr │ ├── interp_warn_dump_failed-check.trace.expected.stderr │ ├── interp_warn_multi_return-int.trace │ ├── interp_label_fail_dump-result-int.trace.expected.stderr │ ├── simple_dump_type_error-check.trace │ ├── simple_dump-int.trace.interp.expected-check.trace │ ├── simple_dump_unexpected-check.trace │ ├── simple_dump_missing-check.trace.expected.stderr │ ├── check_state_fail_special-check.trace.expected.stderr │ ├── interp_dump_impossible-check.trace │ ├── interleave-check.trace │ ├── interp_state_fail_special-int.trace.expected.stderr │ ├── simple_dump_type_error-check.trace.expected.stderr │ ├── interp_dump_impossible-check.trace.expected.stderr │ ├── interp_warn_state_mixed-int.trace.expected.stderr │ ├── simple_dump_unexpected-check.trace.expected.stderr │ ├── interp_dump_failed-check.trace.expected │ ├── interp_state_fail_none-int.trace.expected │ ├── simple_dump-int.trace.check.expected │ ├── simple_dump_deviant-check.trace │ ├── interp_warn_dump_failed-check.trace.expected │ ├── interp_label_fail_dump-result-int.trace.expected │ ├── interp_warn_dump_failed-int.trace.expected.stderr │ ├── simple_dump_deviant-check.trace.expected.stderr │ ├── interp_warn_multi_return-int.trace.expected.stderr │ ├── interp_warn_dump_failed-check.trace │ ├── interp_state_fail_special-int.trace.expected │ ├── interp_warn_dump_failed-int.trace.expected │ ├── no_errors-check.trace.expected │ ├── unexpected-check.trace.expected │ ├── os_trace1-int.trace │ ├── interp_warn_state_mixed-int.trace.expected │ ├── interleave-check.trace.expected │ ├── interp_trace1-int.trace │ ├── simple_dump_missing-check.trace.expected │ ├── check_state_fail_special-check.trace.expected │ ├── interp_dump_impossible-check.trace.expected │ ├── simple_dump_type_error-check.trace.expected │ ├── trace1-int.trace │ ├── simple_dump_unexpected-check.trace.expected │ ├── os_trace1-check.trace │ ├── interp_warn_multi_return-int.trace.expected │ ├── simple_dump_deviant-check.trace.expected │ ├── trace1-check.trace │ ├── os_trace1-check.trace.check.expected │ ├── os_trace1-int.trace.interp.expected-check.trace │ ├── os_trace1-int.trace.check.expected │ ├── fs_trace1-fs.trace │ ├── resolve_test-int.trace │ ├── resolve_test-fs.trace │ ├── os_perms1-os.trace │ └── os_perms_group1-os.trace ├── debug │ ├── .depend │ ├── README.md │ ├── old │ │ └── Makefile.depend │ ├── bash_env.sh │ └── Makefile ├── docker │ ├── README │ └── docker.sh ├── .gitignore ├── ld_preload │ ├── testmain.c │ ├── Makefile │ └── mycommand.ml ├── test_generation │ ├── README │ └── .interactive ├── adhoc_tests │ ├── adhoc_det_read_write-int.trace │ ├── adhoc_file_descriptor_change_tests-int.trace │ ├── adhoc_rename_test_tr_7 │ ├── adhoc_readdir_tests-int.trace │ ├── adhoc_open_test │ ├── adhoc_open_test.interp_result │ ├── adhoc_open_test.posix_result │ ├── adhoc_state_explosion-check.trace │ ├── adhoc_open_multiple_tests-os.trace │ └── adhoc_lseek_tests-int.trace ├── bash_env.sh ├── default.nix ├── Makefile └── README.md ├── fs_spec ├── src │ ├── posix │ │ ├── 1 │ │ ├── make.sh │ │ ├── style.css │ │ ├── Makefile │ │ ├── dir_protect.md │ │ ├── README │ │ ├── base_definitions │ │ │ └── errno.h.txt │ │ ├── permissions │ │ │ ├── ch_3_definitions │ │ │ ├── utils_ch2 │ │ │ └── ch_4_general_concepts │ │ ├── closedir.md │ │ ├── write.md.old │ │ ├── lseek.md │ │ └── opendir.md │ ├── tr │ │ ├── 1 │ │ ├── 2 │ │ ├── 3 │ │ ├── 4 │ │ ├── 5 │ │ ├── 6 │ │ ├── 7 │ │ ├── 8 │ │ ├── 9 │ │ ├── 10 │ │ ├── 11 │ │ ├── 12 │ │ ├── 13 │ │ ├── 14 │ │ ├── 15 │ │ ├── 16 │ │ ├── 17 │ │ ├── 18 │ │ ├── 19 │ │ ├── 20 │ │ └── 27 │ ├── patch_gen_ml.sed │ ├── patch_lem.sed │ ├── .depend │ ├── bash_env.sh │ ├── T_fs_spec.patch │ ├── t_fs_specScript.patch │ ├── Makefile │ ├── fs_interface.ml │ ├── Lem_support.thy │ ├── abstract_string.mli │ ├── list_array.mli │ ├── fs_dict_wrappers.mli │ ├── t_fs_spec_properties_perms.lem_cppo │ ├── lem_support.ml │ ├── abstract_string.ml │ ├── fs_dict_wrappers.ml │ └── README ├── Makefile └── default.nix ├── CHANGES ├── README.md ├── default.nix ├── .nix ├── Makefile ├── sha │ └── default.nix ├── dyntype │ └── default.nix ├── fd-send-recv │ └── default.nix ├── omd │ └── default.nix ├── ocaml-unix-fcntl │ └── default.nix ├── default.nix ├── ulex │ └── default.nix ├── ocaml-unix-errno │ └── default.nix ├── lem │ └── default.nix ├── ocaml_cow │ └── default.nix └── isabelle │ └── default.nix ├── sibylfs.install ├── .tr61 ├── .merlin ├── patchelf_nix-build.sh ├── run_nix-build.sh ├── release.org ├── Makefile.local └── create_coverage_report.sh ├── configure ├── Makefile ├── opam ├── LICENSE.txt ├── config.sh.in ├── install_opam_deps.sh └── .gitignore /.travis.yml: -------------------------------------------------------------------------------- 1 | language: nix 2 | -------------------------------------------------------------------------------- /fs_test/lib/old/Makefile.common: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /fs_spec/src/posix/make.sh: -------------------------------------------------------------------------------- 1 | make & 2 | -------------------------------------------------------------------------------- /fs_test/repro/.gitignore: -------------------------------------------------------------------------------- 1 | rename_leak 2 | -------------------------------------------------------------------------------- /CHANGES: -------------------------------------------------------------------------------- 1 | 0.5.0 (2015-10-02): 2 | * Initial public release 3 | -------------------------------------------------------------------------------- /fs_test/example_traces/simple_dump-int.trace: -------------------------------------------------------------------------------- 1 | @type script 2 | dump 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Documentation 2 | 3 | Please see 4 | 5 | -------------------------------------------------------------------------------- /fs_test/debug/.depend: -------------------------------------------------------------------------------- 1 | check2.x: checklib_2.x 2 | debug.x: checklib_2.x 3 | -------------------------------------------------------------------------------- /fs_test/docker/README: -------------------------------------------------------------------------------- 1 | See the documentation, section testing and search for docker. -------------------------------------------------------------------------------- /default.nix: -------------------------------------------------------------------------------- 1 | { }: 2 | let 3 | fs_test = import ./fs_test { }; 4 | in fs_test 5 | -------------------------------------------------------------------------------- /fs_spec/src/tr/8: -------------------------------------------------------------------------------- 1 | rename /tmp_dir_94/d1/empty_dir1 /tmp_dir_94/d1/empty_dir1 2 | None1 3 | -------------------------------------------------------------------------------- /fs_test/example_traces/interp_state_fail_none-int.trace: -------------------------------------------------------------------------------- 1 | @type script 2 | Pid 2 -> destroy 3 | -------------------------------------------------------------------------------- /fs_spec/src/tr/2: -------------------------------------------------------------------------------- 1 | rename /tmp_dir_1150/d1/nonempty_dir1/f1.txt/ /tmp_dir_1150/ 2 | [ENOTDIR] 3 | -------------------------------------------------------------------------------- /fs_spec/src/tr/9: -------------------------------------------------------------------------------- 1 | rename /tmp_dir_96/d1/empty_dir1 /tmp_dir_96/d1/nonempty_dir1 2 | [ENOTEMPTY] 3 | -------------------------------------------------------------------------------- /fs_test/example_traces/interp_state_fail_special-int.trace: -------------------------------------------------------------------------------- 1 | @type script 2 | mkdir /foo 0o10000 3 | -------------------------------------------------------------------------------- /fs_test/example_traces/interp_warn_state_mixed-int.trace: -------------------------------------------------------------------------------- 1 | @type script 2 | open /foo [O_EXCL] 3 | -------------------------------------------------------------------------------- /fs_spec/src/tr/18: -------------------------------------------------------------------------------- 1 | OS_CALL(Pid 1,open /tmp_dir_0/nonempty_dir/f3.txt [O_RDWR;O_CREAT]) 2 | Int1(4) 3 | -------------------------------------------------------------------------------- /fs_spec/src/tr/15: -------------------------------------------------------------------------------- 1 | OS_CALL(Pid 1,open /tmp_dir_2299/nonempty_dir/f1.txt [O_RDWR;O_EXCL] 0) 2 | Int1(574) 3 | -------------------------------------------------------------------------------- /fs_spec/src/tr/17: -------------------------------------------------------------------------------- 1 | OS_CALL(Pid 1,open /tmp_dir_0/nonempty_dir/f1.txt [O_RDWR;O_WRONLY] 0) 2 | Int1(3) 3 | -------------------------------------------------------------------------------- /fs_test/example_traces/interp_warn_dump_failed-int.trace: -------------------------------------------------------------------------------- 1 | @type script 2 | dump /gone 3 | dump /not_there 4 | -------------------------------------------------------------------------------- /.nix/Makefile: -------------------------------------------------------------------------------- 1 | SHELL:=bash 2 | 3 | ## link in lem 4 | ../src_ext/lem: 5 | ln -s $$lem/lem ../src_ext/lem 6 | -------------------------------------------------------------------------------- /fs_spec/src/patch_gen_ml.sed: -------------------------------------------------------------------------------- 1 | s/T_f/F/g 2 | s/T_l/L/g 3 | s/T_d/D/g 4 | s/[(][*]o/ /g 5 | s/o[*][)]/ /g 6 | -------------------------------------------------------------------------------- /fs_spec/src/tr/10: -------------------------------------------------------------------------------- 1 | OS_CALL(Pid 1,link /tmp_dir_32// /tmp_dir_32//d1/nonempty_dir1/f1.txt/) 2 | [EEXIST] 3 | 4 | -------------------------------------------------------------------------------- /fs_spec/src/tr/4: -------------------------------------------------------------------------------- 1 | rename /tmp_dir_235/d1/nonempty_dir1/f1.txt /tmp_dir_235/d1/nonempty_dir1/f1.txt 2 | None1 3 | -------------------------------------------------------------------------------- /fs_test/.gitignore: -------------------------------------------------------------------------------- 1 | fs_test 2 | fs_test_posix 3 | fs_test_check 4 | run_trace 5 | tgen 6 | 2014-* 7 | 2015-* 8 | -------------------------------------------------------------------------------- /fs_test/example_traces/interp_label_fail_dump-result-int.trace: -------------------------------------------------------------------------------- 1 | @type script 2 | dump-result / 3 | end dump-result 4 | -------------------------------------------------------------------------------- /fs_spec/src/tr/11: -------------------------------------------------------------------------------- 1 | rename /tmp_dir_1106/d1/nonexist_dir1 /tmp_dir_1106/d1/nonempty_dir1/f1.txt/nonexist4 2 | [ENOTDIR] 3 | -------------------------------------------------------------------------------- /fs_spec/src/tr/1: -------------------------------------------------------------------------------- 1 | rename /tmp_dir_1194/d1/nonempty_dir1/f1.txt/ /tmp_dir_1194/d1/nonexist_dir1/nonexist_dir3 2 | [ENOENT] 3 | -------------------------------------------------------------------------------- /fs_test/example_traces/interleave-check.trace.expected.stderr: -------------------------------------------------------------------------------- 1 | 2 | Error: 13: Pid 1 <- RV_none 3 | errors and values mixed in result 4 | -------------------------------------------------------------------------------- /fs_test/example_traces/interp_state_fail_none-int.trace.expected.stderr: -------------------------------------------------------------------------------- 1 | 2 | Fatal error: 2: Pid 2 -> destroy 3 | no result states 4 | -------------------------------------------------------------------------------- /fs_spec/src/tr/14: -------------------------------------------------------------------------------- 1 | OS_CALL(Pid 1,open /tmp_dir_2000/nonempty_dir/f1.txt [O_RDONLY;O_CLOEXEC;O_DIRECTORY;O_EXCL;O_NOFOLLOW;O_TRUNC] 0) 2 | Int1(3) 3 | -------------------------------------------------------------------------------- /fs_test/ld_preload/testmain.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main (void) 4 | { 5 | rename("/tmp/a.txt","/tmp/b.txt"); 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /fs_spec/src/posix/style.css: -------------------------------------------------------------------------------- 1 | blockquote { 2 | margin: 1em 3em; 3 | color: #999; 4 | border-left: 2px solid #999; 5 | padding-left: 1em; } -------------------------------------------------------------------------------- /fs_test/example_traces/no_errors-check.trace.expected.stderr: -------------------------------------------------------------------------------- 1 | 2 | Error: 5: - 3 | errors possible: ENOENT 4 | continuing execution with ENOENT 5 | -------------------------------------------------------------------------------- /fs_test/test_generation/README: -------------------------------------------------------------------------------- 1 | testgen.ml - generate lots of labels to test responses of various 2 | filesystems (via posix and check executables) 3 | 4 | -------------------------------------------------------------------------------- /fs_spec/src/tr/16: -------------------------------------------------------------------------------- 1 | OS_CALL(Pid 1,open /tmp_dir_2686/nonempty_dir/f2.txt [O_RDONLY;O_TRUNC] 0) 2 | Int1(3) 3 | and f2.txt is empty!!!! (initially contains data) 4 | -------------------------------------------------------------------------------- /fs_test/example_traces/interp_dump_failed-check.trace: -------------------------------------------------------------------------------- 1 | # processing file 'example_traces/interp_warn_dump_failed-int.trace' ... 2 | @type trace 3 | 1: dump / 4 | -------------------------------------------------------------------------------- /fs_test/example_traces/simple_dump_missing-check.trace: -------------------------------------------------------------------------------- 1 | # processing file 'example_traces/simple_dump-int.trace' ... 2 | @type trace 3 | dump-result / 4 | end dump-result 5 | -------------------------------------------------------------------------------- /sibylfs.install: -------------------------------------------------------------------------------- 1 | bin: [ 2 | "fs_test/fs_test" {"fs_test"} 3 | "fs_test/fs_test_posix" {"fs_test_posix"} 4 | "fs_test/fs_test_check" {"fs_test_check"} 5 | ] 6 | -------------------------------------------------------------------------------- /fs_spec/src/patch_lem.sed: -------------------------------------------------------------------------------- 1 | # fix lem bugs 2 | s/let >>= = fsm_bind/let (>>=) = fsm_bind/ 3 | s/let <|||> = /let (<|||>) = / 4 | s/let |||> = /let (|||>) = / 5 | s/let ||| = /let (|||) = / 6 | -------------------------------------------------------------------------------- /fs_test/example_traces/no_errors-check.trace: -------------------------------------------------------------------------------- 1 | # processing file 'example_traces/os_trace1-int.trace' ... 2 | @type trace 3 | 1: open /ooOOoo [] 0o000 4 | Tau 5 | - 6 | -------------------------------------------------------------------------------- /fs_test/lib/.gitignore: -------------------------------------------------------------------------------- 1 | fs_lexer.ml 2 | fs_lr_parser.conflicts 3 | fs_lr_parser.ml 4 | fs_lr_parser.mli 5 | fs_test_version.ml 6 | cmo 7 | cmx 8 | depend.dot 9 | depend.pdf 10 | srcs 11 | -------------------------------------------------------------------------------- /fs_test/example_traces/interp_dump_failed-check.trace.expected.stderr: -------------------------------------------------------------------------------- 1 | 2 | Fatal error: File "example_traces/interp_dump_failed-check.trace", line 3, characters 5-15: 3 | dump not allowed in trace 4 | -------------------------------------------------------------------------------- /fs_test/example_traces/check_state_fail_special-check.trace: -------------------------------------------------------------------------------- 1 | @type trace 2 | 3 | open_close "file" [O_CREAT] 0o700 4 | Tau 5 | RV_none 6 | 7 | open_close "file" [O_TRUNC] 8 | Tau 9 | RV_none 10 | -------------------------------------------------------------------------------- /fs_test/example_traces/unexpected-check.trace: -------------------------------------------------------------------------------- 1 | # processing file 'example_traces/os_trace1-int.trace' ... 2 | @type trace 3 | 1: open /ooOOoo [] 0o000 4 | Tau 5 | RV_num(3) 6 | -------------------------------------------------------------------------------- /fs_test/example_traces/unexpected-check.trace.expected.stderr: -------------------------------------------------------------------------------- 1 | 2 | Error: 5: RV_num(3) 3 | unexpected results: RV_num(3) 4 | allowed are only: ENOENT 5 | continuing execution with ENOENT 6 | -------------------------------------------------------------------------------- /fs_test/example_traces/interp_warn_dump_failed-check.trace.expected.stderr: -------------------------------------------------------------------------------- 1 | 2 | Fatal error: File "example_traces/interp_warn_dump_failed-check.trace", line 6, characters 5-20: 3 | dump not allowed in trace 4 | -------------------------------------------------------------------------------- /fs_test/example_traces/interp_warn_multi_return-int.trace: -------------------------------------------------------------------------------- 1 | @type script 2 | open "f1.txt" [O_CREAT;O_RDWR] 0o600 3 | write! (FD 3) "0123456789" 10 4 | pread (FD 3) 100 0 5 | close (FD 3) 6 | unlink "f1.txt" 7 | -------------------------------------------------------------------------------- /fs_spec/Makefile: -------------------------------------------------------------------------------- 1 | TMP:=_build 2 | 3 | all: 4 | mkdir -p $(TMP) 5 | cd $(TMP) && ln -sf ../src/* ../src/.depend . 6 | $(MAKE) -C $(TMP) 7 | 8 | clean: FORCE 9 | rm -rf $(TMP) ./result 10 | 11 | FORCE: 12 | -------------------------------------------------------------------------------- /fs_test/example_traces/interp_label_fail_dump-result-int.trace.expected.stderr: -------------------------------------------------------------------------------- 1 | 2 | Fatal error: File "example_traces/interp_label_fail_dump-result-int.trace", line 2, characters 0-14: 3 | dump-result not allowed in script 4 | -------------------------------------------------------------------------------- /fs_test/lib/Makefile.doc: -------------------------------------------------------------------------------- 1 | include Makefile.common 2 | 3 | doc: ocamldoc 4 | 5 | ocamldoc: srcs FORCE 6 | mkdir -p ocamldoc 7 | $(OCAMLDOC) -d ocamldoc -html -I ../include `$(OCAMLDEP) -sort $(wildcard *.mli) $(DOTML)` 8 | -------------------------------------------------------------------------------- /fs_test/example_traces/simple_dump_type_error-check.trace: -------------------------------------------------------------------------------- 1 | # processing file 'example_traces/simple_dump-int.trace' ... 2 | @type trace 3 | 1: dump-result / 4 | "/"|F|0|0|"0" 5 | end dump-result 6 | -------------------------------------------------------------------------------- /fs_test/debug/README.md: -------------------------------------------------------------------------------- 1 | * `check2.{ml,native}` - a "minimal" checker; should give same 2 | result as `check` 3 | 4 | * `debug.{ml,native}` - similar to `check2`, but prints debug 5 | information in sexp format 6 | 7 | -------------------------------------------------------------------------------- /fs_test/example_traces/simple_dump-int.trace.interp.expected-check.trace: -------------------------------------------------------------------------------- 1 | # processing file 'example_traces/simple_dump-int.trace' ... 2 | @type trace 3 | 2: dump-result "/" 4 | "/"|D|0 5 | end dump-result 6 | -------------------------------------------------------------------------------- /.tr61/.merlin: -------------------------------------------------------------------------------- 1 | S build_spec 2 | S fs_test 3 | S fs_test/lib 4 | 5 | B src_ext/p3 6 | B build_spec 7 | B fs_test 8 | B fs_test/lib 9 | 10 | PKG unix cmdliner fd-send-recv str bigarray num sha sexplib cow 11 | PKG unix-errno unix-fcntl 12 | -------------------------------------------------------------------------------- /fs_test/example_traces/simple_dump_unexpected-check.trace: -------------------------------------------------------------------------------- 1 | # processing file 'example_traces/simple_dump-int.trace' ... 2 | @type trace 3 | 2: dump-result / 4 | "/"|D|0 5 | "/oooOOOOOoooo"|D|1 6 | end dump-result 7 | -------------------------------------------------------------------------------- /fs_spec/src/posix/Makefile: -------------------------------------------------------------------------------- 1 | # S HELL=bash 2 | 3 | all: link.html mkdir.html open.html rename.html rmdir.html 4 | 5 | # pandoc --css=style.css rename -o rename.html 6 | 7 | %.html: %.md FORCE 8 | pandoc --css=style.css $< -o $@ 9 | 10 | FORCE: 11 | -------------------------------------------------------------------------------- /fs_spec/src/tr/6: -------------------------------------------------------------------------------- 1 | rename /tmp_dir_234/d1/nonempty_dir1/f1.txt /tmp_dir_234/d1/nonempty_dir1 2 | [ENOTEMPTY] 3 | 4 | posix says: 5 | 6 | [EEXIST] or [ENOTEMPTY] 7 | [CX] 8 | The link named by new is a directory that is not an empty directory. 9 | -------------------------------------------------------------------------------- /fs_test/example_traces/simple_dump_missing-check.trace.expected.stderr: -------------------------------------------------------------------------------- 1 | 2 | "/"|D|0 3 | 4 | 5 | Error: 3: dump-result "/" 6 | end dump-result 7 | 8 | comparison of dump-results failed: 9 | missing entry: / 10 | 11 | -------------------------------------------------------------------------------- /fs_test/example_traces/check_state_fail_special-check.trace.expected.stderr: -------------------------------------------------------------------------------- 1 | 2 | Fatal error: 8: Tau 3 | special states found: 4 | - OS_special (Undefined, "open: O_TRUNC, no O_RDWR or O_WRONLY, posix/open.md O_TRUNC:4") 5 | no normal result states 6 | -------------------------------------------------------------------------------- /fs_test/example_traces/interp_dump_impossible-check.trace: -------------------------------------------------------------------------------- 1 | # processing file 'example_traces/simple_dump-int.trace' ... 2 | @type trace 3 | 1: dump-result /impossible 4 | "/"|D|0 5 | "/oooOOOOOoooo"|D|1 6 | end dump-result 7 | -------------------------------------------------------------------------------- /configure: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "Please edit file `config.sh` to ensure paths are set 4 | appropriately; alternatively make sure the paths are set in the 5 | environment (config.sh takes precedence). There is a sample in 6 | config.sh.in." 7 | 8 | false 9 | -------------------------------------------------------------------------------- /fs_test/example_traces/interleave-check.trace: -------------------------------------------------------------------------------- 1 | @type trace 2 | 3 | Pid 2 -> create 4 | 5 | open_close "foo" [O_CREAT] 0o600 6 | Tau 7 | RV_none 8 | 9 | Pid 1 -> unlink "foo" 10 | Pid 2 -> unlink "foo" 11 | Tau 12 | Tau 13 | Pid 1 <- RV_none 14 | Pid 2 <- ENOENT 15 | -------------------------------------------------------------------------------- /fs_test/example_traces/interp_state_fail_special-int.trace.expected.stderr: -------------------------------------------------------------------------------- 1 | 2 | Fatal error: 2: mkdir "/foo" 0o10000 3 | special states found: 4 | - OS_special (Implementation_defined, "mkdir: additional file permission bits") 5 | no normal result states 6 | -------------------------------------------------------------------------------- /fs_test/example_traces/simple_dump_type_error-check.trace.expected.stderr: -------------------------------------------------------------------------------- 1 | 2 | "/"|D|0 3 | 4 | 5 | Error: 3: dump-result "/" 6 | "/"|F|0|0|"0" 7 | end dump-result 8 | 9 | comparison of dump-results failed: 10 | differing entry: / 11 | 12 | -------------------------------------------------------------------------------- /fs_test/example_traces/interp_dump_impossible-check.trace.expected.stderr: -------------------------------------------------------------------------------- 1 | Error: error while dumping fs-state: Dump.Dump_error("ls_path") 2 | 3 | Error: 3: dump-result "/impossible" 4 | "/"|D|0 5 | "/oooOOOOOoooo"|D|1 6 | end dump-result 7 | execution of dump failed 8 | -------------------------------------------------------------------------------- /fs_test/example_traces/interp_warn_state_mixed-int.trace.expected.stderr: -------------------------------------------------------------------------------- 1 | 2 | Error: 2: open "/foo" [O_RDONLY;O_EXCL] 3 | special states found: 4 | - OS_special (Undefined, "open: O_EXCL, no O_CREAT, posix/open.md D:1") 5 | continuing with normal result states 6 | Warning: trace caused problems 7 | -------------------------------------------------------------------------------- /.tr61/patchelf_nix-build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cp -R -L result result.tmp 4 | rm -rf result 5 | mv result.tmp result 6 | chmod u+wx result 7 | chmod u+wx result/bin 8 | 9 | 10 | for f in result/bin/*; do 11 | echo Patching $f 12 | patchelf --set-rpath "" --set-interpreter "/lib64/ld-linux-x86-64.so.2" $f 13 | done 14 | -------------------------------------------------------------------------------- /fs_test/example_traces/simple_dump_unexpected-check.trace.expected.stderr: -------------------------------------------------------------------------------- 1 | 2 | "/"|D|0 3 | 4 | 5 | Error: 3: dump-result "/" 6 | "/"|D|0 7 | "/oooOOOOOoooo"|D|1 8 | end dump-result 9 | 10 | comparison of dump-results failed: 11 | unexpected entry: /oooOOOOOoooo 12 | 13 | -------------------------------------------------------------------------------- /fs_test/example_traces/interp_dump_failed-check.trace.expected: -------------------------------------------------------------------------------- 1 | # processing file 'example_traces/interp_dump_failed-check.trace' ... 2 | # 3 | # Fatal error: File "example_traces/interp_dump_failed-check.trace", line 3, characters 5-15: 4 | # dump not allowed in trace 5 | # processing file 'example_traces/interp_dump_failed-check.trace' failed 6 | -------------------------------------------------------------------------------- /fs_test/example_traces/interp_state_fail_none-int.trace.expected: -------------------------------------------------------------------------------- 1 | # processing file 'example_traces/interp_state_fail_none-int.trace' ... 2 | @type trace 3 | 2: Pid 2 -> destroy 4 | # 5 | # Fatal error: 2: Pid 2 -> destroy 6 | # no result states 7 | # processing file 'example_traces/interp_state_fail_none-int.trace' failed 8 | -------------------------------------------------------------------------------- /fs_test/example_traces/simple_dump-int.trace.check.expected: -------------------------------------------------------------------------------- 1 | # processing file 'example_traces/simple_dump-int.trace.interp.expected-check.trace' ... 2 | # processing file 'example_traces/simple_dump-int.trace' ... 3 | @type trace 4 | 3: dump-result "/" 5 | "/"|D|0 6 | end dump-result 7 | 8 | # trace accepted 9 | -------------------------------------------------------------------------------- /fs_test/example_traces/simple_dump_deviant-check.trace: -------------------------------------------------------------------------------- 1 | # processing file 'example_traces/simple_dump-int.trace' ... 2 | @type trace 3 | 1: open_close "rebel_zero" [O_CREAT] 4 | Tau 5 | RV_none 6 | 2: dump-result / 7 | "/"|D|0 8 | "/rebel_zero"|F|0|0|"0" 9 | end dump-result 10 | -------------------------------------------------------------------------------- /fs_test/lib/Makefile.toplevel: -------------------------------------------------------------------------------- 1 | 2 | # those that don't depend on syscall_stubs.c 3 | TOP_LEVEL_MLS:=diff.ml fs_path.ml posix_agent.ml stat.ml dump.ml \ 4 | checklib_shared_types.ml fs_ast.ml fs_lr_parser.ml fs_lexer.ml trace.ml checkLib.ml 5 | 6 | top_level_lib.cma: $(TOP_LEVEL_MLS:.ml=.cmo) 7 | ocamlfind ocamlc -g -a -o $@ $(TOP_LEVEL_MLS:.ml=.cmo) 8 | 9 | -------------------------------------------------------------------------------- /fs_test/example_traces/interp_warn_dump_failed-check.trace.expected: -------------------------------------------------------------------------------- 1 | # processing file 'example_traces/interp_warn_dump_failed-check.trace' ... 2 | # 3 | # Fatal error: File "example_traces/interp_warn_dump_failed-check.trace", line 6, characters 5-20: 4 | # dump not allowed in trace 5 | # processing file 'example_traces/interp_warn_dump_failed-check.trace' failed 6 | -------------------------------------------------------------------------------- /fs_test/example_traces/interp_label_fail_dump-result-int.trace.expected: -------------------------------------------------------------------------------- 1 | # processing file 'example_traces/interp_label_fail_dump-result-int.trace' ... 2 | # 3 | # Fatal error: File "example_traces/interp_label_fail_dump-result-int.trace", line 2, characters 0-14: 4 | # dump-result not allowed in script 5 | # processing file 'example_traces/interp_label_fail_dump-result-int.trace' failed 6 | -------------------------------------------------------------------------------- /fs_test/example_traces/interp_warn_dump_failed-int.trace.expected.stderr: -------------------------------------------------------------------------------- 1 | Error: error while dumping fs-state: Dump.Dump_error("ls_path") 2 | 3 | Error: 2: dump "/gone" 4 | execution of dump failed 5 | Error: error while dumping fs-state: Dump.Dump_error("ls_path") 6 | 7 | Error: 3: dump "/not_there" 8 | execution of dump failed 9 | Warning: trace caused problems 10 | -------------------------------------------------------------------------------- /fs_test/example_traces/simple_dump_deviant-check.trace.expected.stderr: -------------------------------------------------------------------------------- 1 | 2 | "/"|D|0 3 | "/rebel_zero"|F|1|0|"da39a3ee5e6b4b0d3255bfef95601890afd80709" 4 | 5 | 6 | Error: 6: dump-result "/" 7 | "/"|D|0 8 | "/rebel_zero"|F|0|0|"0" 9 | end dump-result 10 | 11 | comparison of dump-results failed: 12 | differing entry: /rebel_zero 13 | 14 | -------------------------------------------------------------------------------- /fs_test/docker/docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd ../../test-suite 4 | 5 | echo -e "Running tests ...\n" 6 | 7 | exec 3>&- 8 | 9 | #sometimes handy while working on just one suite 10 | #rm -r /results/* 11 | 12 | #calls 13 | ../fs_test/fs_test run --fs=ext --suite=permissions_root 14 | 15 | #./testall.sh 16 | 17 | echo -e "\nTests finished, starting interactive session ...\n" 18 | 19 | /bin/bash 20 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # FIXME we should probably make fs_test depend on fs_spec_lib.{cma,cmxa} rather than rebuilding everything 2 | 3 | SUBDIRS:=fs_spec fs_test 4 | 5 | all: fs_spec fs_test 6 | 7 | FORCE: 8 | 9 | .PHONY: $(SUBDIRS) dep 10 | 11 | dep: 12 | ./install_opam_deps.sh 13 | 14 | $(SUBDIRS): 15 | $(MAKE) -C $@ 16 | 17 | clean: 18 | for f in $(SUBDIRS); do ($(MAKE) -C $$f clean); done 19 | 20 | 21 | -include Makefile.local 22 | -------------------------------------------------------------------------------- /fs_test/example_traces/interp_warn_multi_return-int.trace.expected.stderr: -------------------------------------------------------------------------------- 1 | 2 | Warning: 4: pread (FD 3) 100 0 3 | more than one possible result value 4 | randomly continuing execution with RV_bytes("") 5 | possible results: {RV_bytes("0123456789");RV_bytes("012345678");RV_bytes("01234567");RV_bytes("0123456");RV_bytes("012345");RV_bytes("01234");RV_bytes("0123");RV_bytes("012");RV_bytes("01");RV_bytes("0");RV_bytes("")} 6 | -------------------------------------------------------------------------------- /fs_test/lib/old/Makefile.depend: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # depend 3 | 4 | # .depend is not generated automatically; needs to be rebuilt when 5 | # files change 6 | 7 | all: depend .depend.linear 8 | 9 | include Makefile.common 10 | 11 | depend: srcs 12 | $(OCAMLDEP) -one-line *.ml *.mli >.depend 13 | 14 | .depend.linear: srcs 15 | $(OCAMLDEP) -sort *.ml *.mli >.depend.linear 16 | 17 | -include Makefile.srcs 18 | -------------------------------------------------------------------------------- /fs_test/example_traces/interp_warn_dump_failed-check.trace: -------------------------------------------------------------------------------- 1 | # processing file 'example_traces/interp_warn_dump_failed-int.trace' ... 2 | @type trace 3 | # 4 | # Error: 2: dump "/gone" 5 | # execution of dump failed 6 | 2: dump "/gone" 7 | # 8 | # Error: 3: dump "/not_there" 9 | # execution of dump failed 10 | 3: dump "/not_there" 11 | # Warning: trace caused problems 12 | # processing file 'example_traces/interp_warn_dump_failed-int.trace' failed 13 | -------------------------------------------------------------------------------- /fs_test/example_traces/interp_state_fail_special-int.trace.expected: -------------------------------------------------------------------------------- 1 | # processing file 'example_traces/interp_state_fail_special-int.trace' ... 2 | @type trace 3 | 2: mkdir "/foo" 0o10000 4 | # 5 | # Fatal error: 2: mkdir "/foo" 0o10000 6 | # special states found: 7 | # - OS_special (Implementation_defined, "mkdir: additional file permission bits") 8 | # no normal result states 9 | # processing file 'example_traces/interp_state_fail_special-int.trace' failed 10 | -------------------------------------------------------------------------------- /fs_test/example_traces/interp_warn_dump_failed-int.trace.expected: -------------------------------------------------------------------------------- 1 | # processing file 'example_traces/interp_warn_dump_failed-int.trace' ... 2 | @type trace 3 | # 4 | # Error: 2: dump "/gone" 5 | # execution of dump failed 6 | 2: dump "/gone" 7 | # 8 | # Error: 3: dump "/not_there" 9 | # execution of dump failed 10 | 3: dump "/not_there" 11 | # Warning: trace caused problems 12 | # processing file 'example_traces/interp_warn_dump_failed-int.trace' failed 13 | -------------------------------------------------------------------------------- /fs_test/example_traces/no_errors-check.trace.expected: -------------------------------------------------------------------------------- 1 | # processing file 'example_traces/no_errors-check.trace' ... 2 | # processing file 'example_traces/os_trace1-int.trace' ... 3 | @type trace 4 | 3: open "/ooOOoo" [O_RDONLY] 0o000 5 | 4: Tau 6 | 5: - 7 | # 8 | # Error: 5: - 9 | # errors possible: ENOENT 10 | # continuing execution with ENOENT 11 | 12 | # trace not accepted 13 | # processing file 'example_traces/no_errors-check.trace' failed 14 | -------------------------------------------------------------------------------- /fs_test/debug/old/Makefile.depend: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # depend 3 | 4 | # .depend is not generated automatically; needs to be rebuilt when 5 | # files change 6 | 7 | OCAMLDEP:=ocamlfind ocamldep -package sexplib,sexplib.syntax,cow,cow.syntax -syntax camlp4o 8 | 9 | all: depend #.depend.linear 10 | 11 | depend: 12 | $(OCAMLDEP) -one-line *.ml *.mli >.depend 13 | 14 | .depend.linear: 15 | $(OCAMLDEP) -sort *.ml *.mli >.depend.linear 16 | -------------------------------------------------------------------------------- /fs_test/repro/rmdir_cwd_spin.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | int main() { 12 | int err; 13 | 14 | mkdir("dmz",0700); 15 | chdir("dmz"); 16 | errno = 0; 17 | err = rmdir("../dmz"); 18 | if (err == -1) printf("rmdir error: %s\n",strerror(errno)); 19 | open("bar",O_CREAT | O_RDONLY,0600); 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /fs_test/debug/bash_env.sh: -------------------------------------------------------------------------------- 1 | set -a # export all vars 2 | # set -x # debug 3 | 4 | BASH_DIR=$(realpath $(dirname $BASH_SOURCE)) 5 | ROOT=$BASH_DIR/../.. 6 | 7 | test -f $ROOT/config.sh && source $ROOT/config.sh 8 | source ../bash_env.sh 9 | 10 | ocamlc="$DISABLE_BYTE ocamlfind ocamlc $WARN $CCFLAGS $PKGS -I $BASH_DIR/include extract.cma fs_spec_lib.cma $SYNTAX $WITH_FS_CHECK_LIB" 11 | ocamlopt="$DISABLE_NTVE ocamlfind ocamlopt $WARN $CCFLAGS $PKGS -I $BASH_DIR/include extract.cmxa fs_spec_lib.cmxa $SYNTAX $WITH_FS_CHECK_LIB" 12 | -------------------------------------------------------------------------------- /fs_test/lib/old/.depend.linear: -------------------------------------------------------------------------------- 1 | fs_test_cli.ml fs_test_config.ml fs_test_index.ml fs_test_version.ml posix_agent.ml diff.mli fs_path.mli fs_test_system.mli fs_test_util.mli stat.mli syscall.mli dump.mli checklib_shared_types.mli syscall.ml fs_test_util.ml fs_test_system.ml fs_test_mount.ml fs_path.ml diff.ml dump.ml stat.ml fs_ast.mli fs_lr_parser.mli posix_ops.mli trace.mli checkLib.mli fs_ast.ml checklib_shared_types.ml fs_lr_parser.ml posix_ops.ml checkLib_with_posix.mli fs_lexer.ml trace.ml checkLib.ml checkLib_with_posix.ml fs_test_html.ml 2 | -------------------------------------------------------------------------------- /fs_test/example_traces/unexpected-check.trace.expected: -------------------------------------------------------------------------------- 1 | # processing file 'example_traces/unexpected-check.trace' ... 2 | # processing file 'example_traces/os_trace1-int.trace' ... 3 | @type trace 4 | 3: open "/ooOOoo" [O_RDONLY] 0o000 5 | 4: Tau 6 | 5: RV_num(3) 7 | # 8 | # Error: 5: RV_num(3) 9 | # unexpected results: RV_num(3) 10 | # allowed are only: ENOENT 11 | # continuing execution with ENOENT 12 | 13 | # trace not accepted 14 | # processing file 'example_traces/unexpected-check.trace' failed 15 | -------------------------------------------------------------------------------- /fs_test/example_traces/os_trace1-int.trace: -------------------------------------------------------------------------------- 1 | @type script 2 | 3 | mkdir /tmp_dir_1490/ 0o000 4 | 5 | mkdir /tmp_dir_1490/d1 0o000 6 | 7 | mkdir /tmp_dir_1490/d1/empty_dir1 0o000 8 | 9 | mkdir /tmp_dir_1490/d1/empty_dir2 0o000 10 | 11 | mkdir /tmp_dir_1490/d1/nonempty_dir1 0o000 12 | 13 | open /tmp_dir_1490/d1/nonempty_dir1/f1.txt [O_RDWR;O_CREAT] 0o000 14 | 15 | open /tmp_dir_1490/d1/nonempty_dir1/f1.txt [O_RDWR] 16 | 17 | stat /tmp_dir_1490/d1/nonempty_dir1/f1.txt 18 | 19 | # stat a non-existing file 20 | stat /tmp_dir_1490/d1/nosuchdir/non.txt 21 | 22 | 23 | -------------------------------------------------------------------------------- /fs_test/example_traces/interp_warn_state_mixed-int.trace.expected: -------------------------------------------------------------------------------- 1 | # processing file 'example_traces/interp_warn_state_mixed-int.trace' ... 2 | @type trace 3 | 2: open "/foo" [O_RDONLY;O_EXCL] 4 | # 5 | # Error: 2: open "/foo" [O_RDONLY;O_EXCL] 6 | # special states found: 7 | # - OS_special (Undefined, "open: O_EXCL, no O_CREAT, posix/open.md D:1") 8 | # continuing with normal result states 9 | Tau 10 | ENOENT 11 | # Warning: trace caused problems 12 | # processing file 'example_traces/interp_warn_state_mixed-int.trace' failed 13 | -------------------------------------------------------------------------------- /fs_test/example_traces/interleave-check.trace.expected: -------------------------------------------------------------------------------- 1 | # processing file 'example_traces/interleave-check.trace' ... 2 | @type trace 3 | 4 | 3: Pid 2 -> create (User_id 0) (Group_id 0) 5 | 6 | 5: open_close "foo" [O_RDONLY;O_CREAT] 0o600 7 | 6: Tau 8 | 7: RV_none 9 | 10 | 9: Pid 1 -> unlink "foo" 11 | 10: Pid 2 -> unlink "foo" 12 | 11: Tau 13 | 12: Tau 14 | 13: Pid 1 <- RV_none 15 | # 16 | # Error: 13: Pid 1 <- RV_none 17 | # errors and values mixed in result 18 | 14: Pid 2 <- ENOENT 19 | 20 | # trace accepted 21 | -------------------------------------------------------------------------------- /.tr61/run_nix-build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # generate fs_test/lib/fs_test_version.ml using git commit id; 4 | # requires git checkout 5 | 6 | 7 | # determine git revision 8 | GIT_REV=`git rev-parse HEAD | tr -d '\n'` 9 | 10 | # and whether dirty 11 | DIRTY_FLAG=`git diff-index --quiet HEAD || echo "dirty"` 12 | 13 | if [ "$DIRTY_FLAG"="dirty" ]; 14 | then 15 | DIRTY=true 16 | else 17 | DIRTY=false 18 | fi 19 | 20 | 21 | # generate version file 22 | (cd fs_test/lib; make clean; make -f Makefile.srcs fs_test_version.ml) 23 | 24 | 25 | # run nix-build 26 | nix-build 27 | -------------------------------------------------------------------------------- /fs_spec/src/tr/13: -------------------------------------------------------------------------------- 1 | OS_CALL(Pid 1,link /tmp_dir_302//d1/nonempty_dir1/f1.txt /tmp_dir_302//d1/nonempty_dir1/f1.txt/) 2 | [EEXIST] 3 | 4 | This is observed on Linux, but posix spec says 5 | 6 | ## [EEXIST] reconciled 7 | 8 | > The path2 argument resolves to an existing directory entry or refers 9 | > to a symbolic link. 10 | > 11 | 12 | EEXIST:1 13 | 14 | Note that "existing directory entry" means a file, directory or other. 15 | 16 | -- 17 | 18 | Here, it is not clear whether .../f1.txt/ resolves to an existing 19 | directory entry. Maybe it does if you ignore the trailing slash. 20 | -------------------------------------------------------------------------------- /fs_test/example_traces/interp_trace1-int.trace: -------------------------------------------------------------------------------- 1 | mkdir /empty_dir 0o777 2 | mkdir /non_empty_dir 0o777 3 | 4 | open /non_empty_dir/f1.txt [O_RDWR;O_CREAT] 0o666 5 | write (FD 3) "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" 100 6 | pread (FD 3) 50 0 7 | close (FD 3) 8 | 9 | open_close /non_empty_dir/f2.txt [O_RDWR;O_CREAT] 0o666 10 | 11 | opendir /non_empty_dir 12 | readdir (DH 1) 13 | readdir (DH 1) 14 | readdir (DH 1) 15 | readdir (DH 1) 16 | closedir (DH 1) 17 | 18 | rename /non_empty_dir/f1.txt /non_empty_dir/f1a.txt 19 | 20 | dump -------------------------------------------------------------------------------- /.nix/sha/default.nix: -------------------------------------------------------------------------------- 1 | { }: 2 | let 3 | pkgs = import {}; 4 | stdenv = pkgs.stdenv; 5 | fetchurl = pkgs.fetchurl; 6 | ocaml = pkgs.ocaml; 7 | findlib = pkgs.ocamlPackages.findlib; # needed? 8 | in stdenv.mkDerivation { 9 | name = "ocaml_sha"; 10 | 11 | src = fetchurl { 12 | url = https://github.com/vincenthz/ocaml-sha/archive/ocaml-sha-v1.9.tar.gz; 13 | sha256 = "caa1dd9071c2c56ca180061bb8e1824ac3b5e83de8ec4ed197275006c2a088d0"; 14 | }; 15 | 16 | buildInputs = [ ocaml findlib ]; 17 | 18 | createFindlibDestdir = true; 19 | 20 | } 21 | -------------------------------------------------------------------------------- /fs_test/example_traces/simple_dump_missing-check.trace.expected: -------------------------------------------------------------------------------- 1 | # processing file 'example_traces/simple_dump_missing-check.trace' ... 2 | # processing file 'example_traces/simple_dump-int.trace' ... 3 | @type trace 4 | 3: dump-result "/" 5 | end dump-result 6 | # 7 | # "/"|D|0 8 | # 9 | # 10 | # Error: 3: dump-result "/" 11 | # end dump-result 12 | # 13 | # comparison of dump-results failed: 14 | # missing entry: / 15 | # 16 | # 17 | 18 | # trace not accepted 19 | # processing file 'example_traces/simple_dump_missing-check.trace' failed 20 | -------------------------------------------------------------------------------- /.nix/dyntype/default.nix: -------------------------------------------------------------------------------- 1 | { }: 2 | let 3 | pkgs = import {}; 4 | stdenv = pkgs.stdenv; 5 | fetchurl = pkgs.fetchurl; 6 | ocaml = pkgs.ocaml; 7 | op = pkgs.ocamlPackages; 8 | in stdenv.mkDerivation { 9 | name = "ocaml_dyntype"; 10 | 11 | src = fetchurl { 12 | url = https://github.com/mirage/dyntype/archive/dyntype-0.9.0.tar.gz; 13 | sha256 = "60e9417f7613d121cea4e9cde4aaafde26b1914b6fd5f4096f6b384e442ab1d0"; 14 | }; 15 | 16 | buildInputs = [ ocaml op.findlib op.type_conv pkgs.which op.camlp4 ]; 17 | 18 | createFindlibDestdir = true; 19 | 20 | } 21 | -------------------------------------------------------------------------------- /.nix/fd-send-recv/default.nix: -------------------------------------------------------------------------------- 1 | { }: 2 | let 3 | pkgs = import {}; 4 | stdenv = pkgs.stdenv; 5 | fetchurl = pkgs.fetchurl; 6 | ocaml = pkgs.ocaml; 7 | findlib = pkgs.ocamlPackages.findlib; # needed? 8 | in stdenv.mkDerivation { 9 | name = "ocaml_fd-send-recv"; 10 | 11 | src = fetchurl { 12 | url = https://github.com/xen-org/ocaml-fd-send-recv/archive/ocaml-fd-send-recv-1.0.1.tar.gz; 13 | sha256 = "664f109b63412493d3689057010938fe8d0fe122e57e4eecc6a2adf0e94f3c92"; 14 | }; 15 | 16 | buildInputs = [ ocaml findlib ]; 17 | 18 | createFindlibDestdir = true; 19 | 20 | } 21 | -------------------------------------------------------------------------------- /fs_test/example_traces/check_state_fail_special-check.trace.expected: -------------------------------------------------------------------------------- 1 | # processing file 'example_traces/check_state_fail_special-check.trace' ... 2 | @type trace 3 | 4 | 3: open_close "file" [O_RDONLY;O_CREAT] 0o700 5 | 4: Tau 6 | 5: RV_none 7 | 8 | 7: open_close "file" [O_RDONLY;O_TRUNC] 9 | 8: Tau 10 | # 11 | # Fatal error: 8: Tau 12 | # special states found: 13 | # - OS_special (Undefined, "open: O_TRUNC, no O_RDWR or O_WRONLY, posix/open.md O_TRUNC:4") 14 | # no normal result states 15 | 16 | # trace not accepted 17 | # processing file 'example_traces/check_state_fail_special-check.trace' failed 18 | -------------------------------------------------------------------------------- /fs_test/example_traces/interp_dump_impossible-check.trace.expected: -------------------------------------------------------------------------------- 1 | # processing file 'example_traces/interp_dump_impossible-check.trace' ... 2 | # processing file 'example_traces/simple_dump-int.trace' ... 3 | @type trace 4 | 3: dump-result "/impossible" 5 | "/"|D|0 6 | "/oooOOOOOoooo"|D|1 7 | end dump-result 8 | # 9 | # Error: 3: dump-result "/impossible" 10 | # "/"|D|0 11 | # "/oooOOOOOoooo"|D|1 12 | # end dump-result 13 | # execution of dump failed 14 | 15 | # trace not accepted 16 | # processing file 'example_traces/interp_dump_impossible-check.trace' failed 17 | -------------------------------------------------------------------------------- /fs_spec/src/tr/12: -------------------------------------------------------------------------------- 1 | OS_CALL(Pid 1,link /tmp_dir_47// /tmp_dir_47//d1/nonexist_dir1/) 2 | [ENOENT] 3 | 4 | This looks like a reasonable path error to return. At the moment, we 5 | are not clear about whether path resolution should look at the last 6 | component or not. 7 | 8 | However, the specification of link says (and none apply): 9 | 10 | ## [ENOENT] reconciled 11 | 12 | > A component of either path prefix does not exist; 13 | 14 | ENOENT:1 15 | 16 | > the file named by path1 does not exist; 17 | 18 | ENOENT:2 19 | 20 | > or path1 or path2 points to an empty string. 21 | 22 | ENOENT:3 23 | 24 | So it looks like this is Linux specific behaviour. 25 | -------------------------------------------------------------------------------- /fs_test/example_traces/simple_dump_type_error-check.trace.expected: -------------------------------------------------------------------------------- 1 | # processing file 'example_traces/simple_dump_type_error-check.trace' ... 2 | # processing file 'example_traces/simple_dump-int.trace' ... 3 | @type trace 4 | 3: dump-result "/" 5 | "/"|F|0|0|"0" 6 | end dump-result 7 | # 8 | # "/"|D|0 9 | # 10 | # 11 | # Error: 3: dump-result "/" 12 | # "/"|F|0|0|"0" 13 | # end dump-result 14 | # 15 | # comparison of dump-results failed: 16 | # differing entry: / 17 | # 18 | # 19 | 20 | # trace not accepted 21 | # processing file 'example_traces/simple_dump_type_error-check.trace' failed 22 | -------------------------------------------------------------------------------- /fs_test/lib/bash_env.sh: -------------------------------------------------------------------------------- 1 | set -a # export all vars 2 | # set -x # debug 3 | 4 | BASH_DIR=$(realpath $(dirname $BASH_SOURCE)) 5 | ROOT=$BASH_DIR/../.. 6 | 7 | test -f $ROOT/config.sh && source $ROOT/config.sh 8 | source ../bash_env.sh 9 | 10 | ocamlc="$DISABLE_BYTE ocamlfind ocamlc $WARN $CCFLAGS $PKGS -I ../include fs_spec_lib.cma $SYNTAX" 11 | ocamlopt="$DISABLE_NTVE ocamlfind ocamlopt $WARN $CCFLAGS $PKGS -I ../include fs_spec_lib.cmxa $SYNTAX" 12 | 13 | mk_cma="$DISABLE_BYTE ocamlfind ocamlc" 14 | mk_cmxa="$DISABLE_NTVE ocamlfind ocamlopt" 15 | 16 | function run_menhir { 17 | menhir --explain --infer --ocamlc "ocamlfind ocamlc $PKGS -I ../include $SYNTAX" $@ 18 | } 19 | -------------------------------------------------------------------------------- /.nix/omd/default.nix: -------------------------------------------------------------------------------- 1 | { }: 2 | let 3 | pkgs = import {}; 4 | stdenv = pkgs.stdenv; 5 | fetchurl = pkgs.fetchurl; 6 | ocaml = pkgs.ocaml; 7 | op = pkgs.ocamlPackages; 8 | in stdenv.mkDerivation { 9 | name = "ocaml_omd"; 10 | 11 | src = fetchurl { 12 | url = http://pw374.github.io/distrib/omd/omd-1.2.6.tar.gz; 13 | sha256 = "4164fe538149e51e19c2bd786f5f817b7c2f6ba9d1376965d2e43d93d745aeb6"; 14 | }; 15 | 16 | buildInputs = [ ocaml op.findlib ]; 17 | 18 | configurePhase=" 19 | mkdir -p $out/bin 20 | export bindir=$out/bin 21 | make configure 22 | "; 23 | 24 | createFindlibDestdir = true; 25 | 26 | } 27 | -------------------------------------------------------------------------------- /.tr61/release.org: -------------------------------------------------------------------------------- 1 | Notes on releasing 2 | 3 | 4 | - "installing prebuilt binaries via nix" 5 | - make nix_binaries 6 | - rename closure (change ARCH to linux or mac) 7 | - eg mv sibylfs_nix_OS_ARCH.closure sibylfs_nix_linux_amd64.closure 8 | - create a release on github https://github.com/sibylfs/sibylfs_binaries 9 | - add closures to release 10 | - currently we release linux and mac binaries 11 | 12 | 13 | - "plain binaries" 14 | - make plain_binaries 15 | - rename .tar.gz 16 | - eg mv sibylfs_OS_ARCH.tar.gz sibylfs_linux_amd64.tar.gz 17 | - add to release on sibylfs_binaries 18 | - currently we only release linux executables this way 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /fs_test/example_traces/trace1-int.trace: -------------------------------------------------------------------------------- 1 | Pid 1 -> mkdir /tmp_dir_1490/ 0o777 2 | 3 | # Pid 1 can be omitted 4 | mkdir /tmp_dir_1490/d1 0o777 5 | 6 | # Other processes have to be always mentioned 7 | create Pid 2 (User_id 0) (Group_id 0) 8 | Pid 2 -> mkdir /tmp_dir_1490/d1/empty_dir1 0o777 9 | 10 | mkdir /tmp_dir_1490/d1/empty_dir2 0o777 11 | 12 | Pid 1 -> mkdir /tmp_dir_1490/d1/nonempty_dir1 0o777 13 | 14 | open /tmp_dir_1490/d1/nonempty_dir1/f1.txt [O_CREAT;O_RDWR] 0o666 15 | 16 | open /tmp_dir_1490/d1/nonempty_dir1/f1.txt [O_RDWR] 17 | 18 | write (FD 4) "01234" 5 19 | 20 | Pid 1 -> stat /tmp_dir_1490/d1/nonempty_dir1/f1.txt 21 | 22 | # stat a non-existing file 23 | Pid 1 -> stat /tmp_dir_1490/d1/nosuchdir/non.txt/ 24 | 25 | 26 | -------------------------------------------------------------------------------- /fs_test/example_traces/simple_dump_unexpected-check.trace.expected: -------------------------------------------------------------------------------- 1 | # processing file 'example_traces/simple_dump_unexpected-check.trace' ... 2 | # processing file 'example_traces/simple_dump-int.trace' ... 3 | @type trace 4 | 3: dump-result "/" 5 | "/"|D|0 6 | "/oooOOOOOoooo"|D|1 7 | end dump-result 8 | # 9 | # "/"|D|0 10 | # 11 | # 12 | # Error: 3: dump-result "/" 13 | # "/"|D|0 14 | # "/oooOOOOOoooo"|D|1 15 | # end dump-result 16 | # 17 | # comparison of dump-results failed: 18 | # unexpected entry: /oooOOOOOoooo 19 | # 20 | # 21 | 22 | # trace not accepted 23 | # processing file 'example_traces/simple_dump_unexpected-check.trace' failed 24 | -------------------------------------------------------------------------------- /.nix/ocaml-unix-fcntl/default.nix: -------------------------------------------------------------------------------- 1 | { }: 2 | let 3 | pkgs = import {}; 4 | stdenv = pkgs.stdenv; 5 | fetchgit = pkgs.fetchgit; 6 | ocaml = pkgs.ocaml; 7 | findlib = pkgs.ocamlPackages.findlib; # needed? 8 | ocaml-unix-errno = import ../ocaml-unix-errno { } ; 9 | in stdenv.mkDerivation { 10 | name = "ocaml-unix-fcntl"; 11 | 12 | src = fetchgit { 13 | url = https://github.com/dsheets/ocaml-unix-fcntl.git; 14 | rev = "83ae867"; # july 27 2015 15 | sha256 = "06fznyvgkgfxkwk60v499ifb74y0ip6p5wwggckj2fspp0ljnlyg"; 16 | }; 17 | 18 | buildInputs = [ ocaml findlib pkgs.ocamlPackages.ctypes ocaml-unix-errno ocaml-unix-errno.rresult ]; 19 | 20 | createFindlibDestdir = true; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /fs_test/example_traces/os_trace1-check.trace: -------------------------------------------------------------------------------- 1 | @type trace 2 | 3 | mkdir /tmp_dir_1490/ 0o000 4 | Tau 5 | RV_none 6 | 7 | mkdir /tmp_dir_1490/d1 0o000 8 | Tau 9 | RV_none 10 | 11 | mkdir /tmp_dir_1490/d1/empty_dir1 0o000 12 | Tau 13 | RV_none 14 | 15 | mkdir /tmp_dir_1490/d1/empty_dir2 0o000 16 | Tau 17 | RV_none 18 | 19 | mkdir /tmp_dir_1490/d1/nonempty_dir1 0o000 20 | Tau 21 | RV_none 22 | 23 | open /tmp_dir_1490/d1/nonempty_dir1/f1.txt [O_RDWR;O_CREAT] 0o000 24 | Tau 25 | RV_num(3) 26 | 27 | open /tmp_dir_1490/d1/nonempty_dir1/f1.txt [O_RDWR] 28 | Tau 29 | RV_num(4) 30 | 31 | stat /tmp_dir_1490/d1/nonempty_dir1/f1.txt 32 | Tau 33 | - 34 | 35 | # stat a non-existing file 36 | stat /tmp_dir_1490/d1/nosuchdir/non.txt 37 | Tau 38 | ENOENT 39 | 40 | 41 | -------------------------------------------------------------------------------- /fs_test/test_generation/.interactive: -------------------------------------------------------------------------------- 1 | (* -*- mode: tuareg -*- *) 2 | #use "topfind";; 3 | #require "unix";; 4 | #require "bigarray";; 5 | #require "str";; 6 | #require "sha";; 7 | #require "num";; 8 | 9 | #require "sexplib";; 10 | #require "sexplib.syntax";; 11 | #require "sexplib.top";; 12 | #camlp4o;; 13 | 14 | #require "bytes";; 15 | #require "cmdliner";; 16 | #require "fd-send-recv";; 17 | 18 | (* 19 | #require "cow";; (* stops "let lexer = " bindings *) 20 | #require "cow.syntax";; 21 | *) 22 | 23 | #directory "../../src_ext/lem/ocaml-lib/_build";; 24 | #load "extract.cma";; 25 | 26 | #directory "../../fs_spec/build";; 27 | #load "fs_spec_lib.cma";; 28 | 29 | #directory "../lib";; 30 | #load "top_level_lib.cma";; 31 | 32 | #mod_use "property_testgen.ml";; 33 | -------------------------------------------------------------------------------- /fs_spec/src/posix/dir_protect.md: -------------------------------------------------------------------------------- 1 | 4.2 Directory Protection 2 | ======================== 3 | 4 | If a directory is writable and the mode bit S_ISVTX is set on the directory, a process may remove or rename files within that directory only if one or more of the following is true: 5 | 6 | - The effective user ID of the process is the same as that of the owner ID of the file. 7 | 8 | - The effective user ID of the process is the same as that of the owner ID of the directory. 9 | 10 | - The process has appropriate privileges. 11 | 12 | - Optionally, the file is writable by the process. Whether or not files that are writable by the process can be removed or renamed is implementation-defined. 13 | 14 | If the S_ISVTX bit is set on a non-directory file, the behavior is unspecified. 15 | -------------------------------------------------------------------------------- /fs_spec/src/posix/README: -------------------------------------------------------------------------------- 1 | This directory contains annotated copies of the Open Group online 2 | version of the POSIX specification 2013 Edition, available here: 3 | http://pubs.opengroup.org/onlinepubs/9699919799/ 4 | 5 | This allows us to internally comment on the POSIX spec, and provide 6 | references to particular sentences or paragraphs in POSIX. For 7 | example, we use references like `posix/rename.md ENOENT:2` which 8 | refers to the rename.md file in this directory, at the ENOENT:2 label. 9 | 10 | In order to make these references public, we need to map references 11 | like `posix/rename.md ENOENT:2` to page and line numbers in the 12 | official C138.pdf (2013 version) of the spec published by the Open 13 | Group. The mapping will be maintained in the file C138_references.txt 14 | 15 | -------------------------------------------------------------------------------- /fs_spec/src/posix/base_definitions/errno.h.txt: -------------------------------------------------------------------------------- 1 | http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html 2 | 3 | > The header shall define the following macros which shall 4 | > expand to integer constant expressions with type int, distinct 5 | > positive values (except as noted below)" -- 6 | > http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html 7 | 8 | Note also that the ints must be positive. 9 | 10 | Later we have: 11 | 12 | > EAGAIN may be same as EWOULDBLOCK 13 | > ENOTSUP may be same as EOPNOTSUPP 14 | 15 | There is a question: what does it mean when a function specifies that 16 | a given error message may be returned, and another error message with 17 | the same representation may be returned under different (mutually 18 | disjoint) conditions? 19 | 20 | -------------------------------------------------------------------------------- /fs_test/ld_preload/Makefile: -------------------------------------------------------------------------------- 1 | UNAME=$(shell uname) 2 | 3 | ifeq ($(UNAME),Linux) 4 | DL_FLAGS=-ldl 5 | else 6 | ifeq ($(UNAME),FreeBSD) 7 | DL_FLAGS= 8 | else 9 | DL_FLAGS= 10 | endif 11 | endif 12 | 13 | all: mycommand.native libtestlib.so a.out 14 | 15 | mycommand.native: mycommand.ml 16 | ocamlbuild $@ # may produce a /bin/sh: 1: tput: not found error; not sure why 17 | cp $@ /tmp 18 | 19 | # http://stackoverflow.com/questions/14884126/build-so-file-from-c-file-using-gcc-command-line 20 | libtestlib.so: testlib.c 21 | cc -shared -o libtestlib.so -fPIC $< $(DL_FLAGS) 22 | 23 | a.out: testmain.c 24 | cc $< 25 | 26 | testnolib: all 27 | ./a.out 28 | 29 | testlib: all 30 | LD_PRELOAD=$(PWD)/libtestlib.so ./a.out 31 | 32 | clean: 33 | rm -f a.out libtestlib.so *.o 34 | -ocamlbuild -clean 35 | -------------------------------------------------------------------------------- /fs_spec/src/.depend: -------------------------------------------------------------------------------- 1 | abstract_string.x : # camlp4o 2 | lem_support.x : 3 | list_array.x : abstract_string.x 4 | fs_prelude.x : lem_support.x 5 | fs_dict_wrappers.x : fs_prelude.x lem_support.x 6 | fs_spec.x : list_array.x abstract_string.x fs_prelude.x lem_support.x # camlp4o 7 | dir_heap.x : fs_spec.x list_array.x fs_prelude.x lem_support.x # camlp4o 8 | fs_dump.x : dir_heap.x list_array.x fs_spec.x fs_dict_wrappers.x # camlp4o 9 | fs_printer.x : list_array.x fs_spec.x fs_dict_wrappers.x lem_support.x # camlp4o 10 | fs_interface.x : fs_dump.x dir_heap.x fs_printer.x fs_spec.x abstract_string.x lem_support.x # camlp4o 11 | 12 | # need to get .cmo in right order 13 | xs:=abstract_string.x lem_support.x list_array.x fs_prelude.x fs_spec.x dir_heap.x fs_dict_wrappers.x fs_dump.x fs_printer.x fs_interface.x 14 | 15 | -------------------------------------------------------------------------------- /fs_spec/src/posix/permissions/ch_3_definitions: -------------------------------------------------------------------------------- 1 | 3.20 Appropriate Privileges 2 | 3 | An implementation-defined means of associating privileges with a process with regard to the function calls, function call options, and the commands that need special privileges. There may be zero or more such means. These means (or lack thereof) are described in the conformance document. 4 | 5 | 3.168 File Mode 6 | 7 | An object containing the file mode bits and file type of a file. 8 | 9 | Note: 10 | File mode bits and file types are defined in detail in . 11 | 12 | 3.169 File Mode Bits 13 | 14 | A file's file permission bits, set-user-ID-on-execution bit (S_ISUID), set-group-ID-on-execution bit (S_ISGID), and, on directories, the restricted deletion flag bit (S_ISVTX). 15 | 16 | Note: 17 | File Mode Bits are defined in detail in . 18 | 19 | -------------------------------------------------------------------------------- /fs_test/lib/mk_fs_test_version.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # allow override in case not git repo 4 | 5 | # what if sibylfs_src is a subdir of a git repo? 6 | IN_GIT_DIR=`git status || echo false` 7 | if [ "$IN_GIT_DIR" = "false" ]; then 8 | if [ -z "$DIRTY"]; then DIRTY=true; fi 9 | if [ -z "$GIT_REV" ]; then GIT_REV="unknown_git_rev"; fi 10 | else 11 | GIT_DIFF=`git diff-index --quiet HEAD || echo "dirty"` 12 | if [ "$GIT_DIFF" = "dirty" ]; then DIRTY=true; else DIRTY=false; fi 13 | if [ -z "$GIT_REV" ]; then GIT_REV=`git rev-parse HEAD | tr -d '\n'`; fi 14 | fi 15 | 16 | # note we don't force this to be rebuilt every time, but the sources 17 | # could change from clean to dirty 18 | 19 | cat >fs_test_version.ml < #include 4 | 5 | > int closedir(DIR *dirp); 6 | 7 | # DESCRIPTION 8 | 9 | > The closedir() function shall close the directory stream 10 | > referred to by the argument dirp. Upon return, the value of dirp 11 | > may no longer point to an accessible object of the type DIR. If 12 | > a file descriptor is used to implement type DIR, that file 13 | > descriptor shall be closed. 14 | 15 | # RETURN VALUE 16 | 17 | > Upon successful completion, closedir() shall return 0; 18 | > otherwise, -1 shall be returned and errno set to indicate the 19 | > error. 20 | 21 | > ERRORS 22 | 23 | > The closedir() function may fail if: 24 | 25 | > [EBADF] 26 | > The dirp argument does not refer to an open directory stream. 27 | EBADF:1 28 | 29 | > [EINTR] 30 | > The closedir() function was interrupted by a signal. 31 | 32 | -------------------------------------------------------------------------------- /opam: -------------------------------------------------------------------------------- 1 | opam-version: "1.2" 2 | maintainer: "tom.j.ridge@googlemail.com" 3 | authors: [ 4 | "Tom Ridge " 5 | "Thomas Tuerk " 6 | "David Sheets " 7 | "Andrea Giugliano " 8 | ] 9 | homepage: "http://sibylfs.io/" 10 | dev-repo: "https://github.com/sibylfs/sibylfs_src.git" 11 | bug-reports: "https://github.com/sibylfs/sibylfs_src/issues" 12 | build: [ 13 | ["mkdir" "-p" "src_ext/lem/ocaml-lib"] 14 | ["ln" "-s" sibylfs-lem:lib "src_ext/lem/ocaml-lib/_build"] 15 | ["ln" "-s" "%{sibylfs-lem:bin}%/lem" "src_ext/lem/lem"] 16 | [make] 17 | ] 18 | depends: [ 19 | "base-unix" 20 | "base-bytes" 21 | "ocamlfind" { build } 22 | "sibylfs-lem" { build } 23 | "cppo" { build } 24 | "sha" 25 | "cmdliner" 26 | "fd-send-recv" 27 | "camlp4" 28 | "sexplib" {< "113.01.00"} 29 | "menhir" 30 | "cow" {>= "1.2.0" & < "2.0.0"} 31 | "unix-fcntl" {>= "0.2.0" & < "0.3.0"} 32 | ] 33 | -------------------------------------------------------------------------------- /.nix/default.nix: -------------------------------------------------------------------------------- 1 | { }: 2 | let 3 | pkgs = import {}; 4 | stdenv = pkgs.stdenv; 5 | fetchgit = pkgs.fetchgit; 6 | perl = pkgs.perl; 7 | ocaml = pkgs.ocaml; 8 | op = pkgs.ocamlPackages; 9 | findlib=op.findlib; 10 | cppo=op.cppo; 11 | sha = import ./sha { }; 12 | ocaml_sexplib = op.ocaml_sexplib; 13 | isabelle = import ./isabelle { }; 14 | lem = import ./lem { }; 15 | in stdenv.mkDerivation { 16 | name = "lemenv"; 17 | 18 | # make these available in nix-shell 19 | lem = lem; 20 | isabelle = isabelle; 21 | sha = sha; 22 | 23 | 24 | src = lem; 25 | buildInputs = [ isabelle ocaml findlib sha cppo ocaml_sexplib lem ]; 26 | 27 | buildPhase = '' 28 | false 29 | ''; 30 | 31 | # eval "${!curPhase:-$curPhase}" from nix-shell 32 | 33 | shellHook = '' 34 | export LEMPATH=${lem}/lem 35 | export PATH=$PATH:${lem}/lem 36 | export LEMLIB=${lem}/lem/library 37 | ''; 38 | 39 | } 40 | -------------------------------------------------------------------------------- /.nix/ulex/default.nix: -------------------------------------------------------------------------------- 1 | { }: 2 | 3 | let 4 | pkgs = import {}; 5 | stdenv = pkgs.stdenv; 6 | fetchurl = pkgs.fetchurl; 7 | ocaml = pkgs.ocaml; 8 | op = pkgs.ocamlPackages; 9 | findlib=op.findlib; 10 | ocaml_version = (builtins.parseDrvName ocaml.name).version; 11 | version = "1.1"; 12 | pname = "ulex"; 13 | 14 | in 15 | 16 | stdenv.mkDerivation { 17 | name = "${pname}-${version}"; 18 | 19 | src = fetchurl { 20 | url = "http://www.cduce.org/download/${pname}-${version}.tar.gz"; 21 | sha256 = "0fjlkwps14adfgxdrbb4yg65fhyimplvjjs1xqj5np197cig67x0"; 22 | }; 23 | 24 | createFindlibDestdir = true; 25 | 26 | buildInputs = [ocaml findlib]; 27 | 28 | buildFlags = "all all.opt"; 29 | 30 | meta = { 31 | homepage = http://www.cduce.org/download.html; 32 | description = "A lexer generator for Unicode and OCaml"; 33 | license = stdenv.lib.licenses.mit; 34 | maintainers = [ stdenv.lib.maintainers.roconnor ]; 35 | }; 36 | } 37 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013, 2014, 2015, Tom Ridge, David Sheets, Thomas Tuerk, 2 | Andrea Giugliano (as part of the SibylFS project) 3 | 4 | Permission to use, copy, modify, and/or distribute this software for 5 | any purpose with or without fee is hereby granted, provided that the 6 | above copyright notice and this permission notice appear in all 7 | copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 | WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 | WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 | AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 | DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 | PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 | TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 | PERFORMANCE OF THIS SOFTWARE. 17 | 18 | Meta: 19 | - Headers maintained using headache. 20 | - License source: http://opensource.org/licenses/ISC 21 | -------------------------------------------------------------------------------- /fs_test/example_traces/trace1-check.trace: -------------------------------------------------------------------------------- 1 | Pid 1 -> mkdir /tmp_dir_1490/ 0o777 2 | Tau 3 | Pid 1 <- RV_none 4 | 5 | # Pid 1 can be omitted 6 | mkdir /tmp_dir_1490/d1 0o777 7 | Tau 8 | RV_none 9 | 10 | # Other processes have to be always mentioned 11 | create Pid 2 User_id 0 Group_id 0 12 | Pid 2 -> mkdir /tmp_dir_1490/d1/empty_dir1 0o777 13 | Tau 14 | Pid 2 <- RV_none 15 | 16 | mkdir /tmp_dir_1490/d1/empty_dir2 0o777 17 | Tau 18 | RV_none 19 | 20 | Pid 1 -> mkdir /tmp_dir_1490/d1/nonempty_dir1 0o777 21 | Tau 22 | Pid 1 <- RV_none 23 | 24 | open /tmp_dir_1490/d1/nonempty_dir1/f1.txt [O_CREAT;O_RDWR] 0o666 25 | Tau 26 | RV_num(3) 27 | 28 | open /tmp_dir_1490/d1/nonempty_dir1/f1.txt [O_RDWR] 29 | Tau 30 | RV_num(4) 31 | 32 | write (FD 4) "01234" 5 33 | Tau 34 | {RV_num(5) ; RV_num(3); RV_num(1);RV_num(2)} 35 | 36 | Pid 1 -> stat /tmp_dir_1490/d1/nonempty_dir1/f1.txt 37 | Tau 38 | Pid 1 <- - 39 | 40 | # stat a non-existing file 41 | Pid 1 -> stat /tmp_dir_1490/d1/nosuchdir/non.txt/ 42 | Tau 43 | Pid 1 <- ENOENT 44 | 45 | 46 | -------------------------------------------------------------------------------- /fs_test/adhoc_tests/adhoc_det_read_write-int.trace: -------------------------------------------------------------------------------- 1 | # adhoc_det_read_write: adhoc tests to test deterministic versions of read and write 2 | 3 | # f1.txt contains some short text 4 | # notice the use of write and write! 5 | open f1.txt [O_RDWR;O_CREAT] 0o666 6 | write! (FD 3) "Lorem ipsum dolor sit" 21 7 | write (FD 3) "0123456789" 10 8 | close (FD 3) 9 | 10 | # now read it with pread and pread!, 11 | # read and read! 12 | open f1.txt [] 13 | pread (FD 3) 10 0 14 | pread! (FD 3) 10 0 15 | read (FD 3) 10 16 | read (FD 3) 5 17 | lseek (FD 3) 0 SEEK_SET 18 | read! (FD 3) 10 19 | read! (FD 3) 5 20 | close (FD 3) 21 | 22 | 23 | # now test write and pwrite 24 | open f2a.txt [O_RDWR;O_CREAT] 0o666 25 | open f2b.txt [O_RDWR;O_CREAT] 0o666 26 | 27 | write (FD 3) "0123456789" 10 28 | write! (FD 4) "0123456789" 10 29 | 30 | pread! (FD 3) 100 0 31 | pread! (FD 4) 100 0 32 | 33 | pwrite (FD 3) "ABCD" 4 3 34 | pwrite! (FD 4) "ABCD" 4 3 35 | 36 | pread! (FD 3) 100 0 37 | pread! (FD 4) 100 0 38 | 39 | close (FD 3) 40 | close (FD 4) 41 | 42 | -------------------------------------------------------------------------------- /fs_spec/src/bash_env.sh: -------------------------------------------------------------------------------- 1 | set -a # export all vars 2 | # set -x # debug 3 | 4 | root=$(realpath $(dirname $BASH_SOURCE))/../.. 5 | 6 | # if using nix, this may not be present 7 | test -f $root/config.sh && source $root/config.sh 8 | 9 | CPPO_ARGS="-D aspect_perms" 10 | 11 | LEMFLAGS="-lib $LEMLIB -only_changed_output -wl_unused_vars ign -wl_rename err -wl_comp_message ign -wl_pat_exh ign" 12 | 13 | PKGS="-package sexplib,sexplib.syntax,sha" 14 | SYNTAX="-syntax camlp4o" # simplify: use for every file 15 | 16 | # 8~"pattern-matching is not exhaustive"; 17 | # 11~"this match case is unused"; 18 | # 26~"unused variable s2" 19 | WARN="-w @f@p@u@s@40-8-11-26" 20 | 21 | # these include syntax, so should work on all files; may be overridden in ocamlc.sh 22 | ocamlc="$DISABLE_BYTE ocamlfind ocamlc $WARN -I $EXTRACTDIR extract.cma $PKGS $SYNTAX" 23 | ocamlopt="$DISABLE_NTVE ocamlfind ocamlopt $WARN -I $EXTRACTDIR extract.cmxa $PKGS $SYNTAX" 24 | ocamldep="ocamlfind ocamldep $PKGS" 25 | 26 | mk_cma="$DISABLE_BYTE ocamlfind ocamlc" 27 | mk_cmxa="$DISABLE_NTVE ocamlfind ocamlopt" 28 | -------------------------------------------------------------------------------- /fs_test/adhoc_tests/adhoc_file_descriptor_change_tests-int.trace: -------------------------------------------------------------------------------- 1 | # Tests for a file underlying a file-descriptor 2 | # being modified while the descriptor is open 3 | 4 | # create a file with some content 5 | open f1.txt [O_RDWR;O_CREAT] rw-r--r-- 6 | write (FD 3) "0123456789" 10 7 | 8 | open f1.txt [] 9 | # check we are at the beginning 10 | read (FD 4) 100 11 | 12 | # check lseek to FD 4 does not affect FD 3 13 | lseek (FD 4) 0 SEEK_SET 14 | write (FD 3) "AB" 2 15 | 16 | # but content is present in both 17 | pread (FD 3) 100 0 18 | pread (FD 4) 100 0 19 | 20 | close (FD 3) 21 | close (FD 4) 22 | 23 | 24 | 25 | # open f1, then delete it 26 | open f1.txt [] 27 | unlink f1.txt 28 | pread (FD 3) 100 0 29 | 30 | open_close f1.txt [] 31 | 32 | close (FD 3) 33 | 34 | 35 | # open f1, then rename it 36 | open f1.txt [O_RDWR;O_CREAT] rw-r--r-- 37 | write (FD 3) "0123456789" 10 38 | close (FD 3) 39 | 40 | open f1.txt [] 41 | rename f1.txt f2.txt 42 | pread (FD 3) 100 0 43 | 44 | open_close f1.txt [] 45 | open f2.txt [] 46 | pread (FD 4) 100 0 47 | close (FD 4) 48 | close (FD 3) 49 | 50 | -------------------------------------------------------------------------------- /fs_test/example_traces/os_trace1-check.trace.check.expected: -------------------------------------------------------------------------------- 1 | # processing file 'example_traces/os_trace1-check.trace' ... 2 | @type trace 3 | 4 | 3: mkdir "/tmp_dir_1490/" 0o000 5 | 4: Tau 6 | 5: RV_none 7 | 8 | 7: mkdir "/tmp_dir_1490/d1" 0o000 9 | 8: Tau 10 | 9: RV_none 11 | 12 | 11: mkdir "/tmp_dir_1490/d1/empty_dir1" 0o000 13 | 12: Tau 14 | 13: RV_none 15 | 16 | 15: mkdir "/tmp_dir_1490/d1/empty_dir2" 0o000 17 | 16: Tau 18 | 17: RV_none 19 | 20 | 19: mkdir "/tmp_dir_1490/d1/nonempty_dir1" 0o000 21 | 20: Tau 22 | 21: RV_none 23 | 24 | 23: open "/tmp_dir_1490/d1/nonempty_dir1/f1.txt" [O_CREAT;O_RDWR] 0o000 25 | 24: Tau 26 | 25: RV_num(3) 27 | 28 | 27: open "/tmp_dir_1490/d1/nonempty_dir1/f1.txt" [O_RDWR] 29 | 28: Tau 30 | 29: RV_num(4) 31 | 32 | 31: stat "/tmp_dir_1490/d1/nonempty_dir1/f1.txt" 33 | 32: Tau 34 | 33: - 35 | 36 | # stat a non-existing file 37 | 36: stat "/tmp_dir_1490/d1/nosuchdir/non.txt" 38 | 37: Tau 39 | 38: ENOENT 40 | 41 | 42 | 43 | # trace accepted 44 | -------------------------------------------------------------------------------- /fs_spec/src/T_fs_spec.patch: -------------------------------------------------------------------------------- 1 | 1816,1818c1816 2 | < (*val >>= : forall 'impl 'a 'b. fsmonad 'impl 'a -> ('a -> fsmonad 'impl 'b) -> fsmonad 'impl 'b*) 3 | < definition >>= :: "('impl,'a)fsmonad \('a \('impl,'b)fsmonad) \('impl,'b)fsmonad " where 4 | < " >>= = ( fsm_bind )" 5 | --- 6 | > notation fsm_bind (infixl ">>=" 55) 7 | 1897,1905c1895,1896 8 | < 9 | < (*val <|||> : forall 'impl 'a 'b. fsmonad 'impl 'a -> fsmonad 'impl 'b -> fsmonad 'impl ('a * 'b)*) 10 | < definition <|||> :: "('impl,'a)fsmonad \('impl,'b)fsmonad \('impl,('a*'b))fsmonad " where 11 | < " <|||> = ( fsm_parallel_composition )" 12 | < 13 | < 14 | < (*val ||| : forall 'impl. fsmonad 'impl ret_value -> fsmonad 'impl ret_value -> fsmonad 'impl ret_value*) 15 | < definition ||| :: "('impl,(ret_value))fsmonad \('impl,(ret_value))fsmonad \('impl,(ret_value))fsmonad " where 16 | < " ||| = ( fsm_parallel_composition_drop )" 17 | --- 18 | > notation fsm_parallel_composition (infixl "<|||>" 55) 19 | > notation fsm_parallel_composition_drop (infixl "|||" 55) 20 | -------------------------------------------------------------------------------- /config.sh.in: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Edit this file to ensure the paths are set appropriately 4 | 5 | # for debugging 6 | # set -x 7 | 8 | # path to the lem executable; must be an absolute path 9 | lem=/nix/store/25fb9v3c69lv0l4ymcc0k52n86kj7m6l-lem/lem/lem 10 | 11 | # path to lem's library (lots of .lem files); must be an absolute path 12 | LEMLIB=/nix/store/25fb9v3c69lv0l4ymcc0k52n86kj7m6l-lem/lem/library 13 | 14 | # path to lem's ocaml library; must be an absolute path; we expect to 15 | # find EXTRACTDIR, with extract.cm[x]a 16 | EXTRACTDIR=/nix/store/25fb9v3c69lv0l4ymcc0k52n86kj7m6l-lem/lem/ocaml-lib/_build 17 | 18 | # if on your path, this does not have to be an absolute path; it is 19 | # the command to run the ocaml preprocessor 20 | cppo=/nix/store/lbfqdl6bxaqm6mzhwcqv9szn09lzzycj-cppo-1.3.2/bin/cppo 21 | 22 | # may or may not be needed; needed when using nix dependencies, but 23 | # building manually 24 | LD_LIBRARY_PATH=/nix/store/gjc187wilf18d45c87s59xiqxb5vwisf-ocaml-cstruct-1.6.0/lib/ocaml/4.01.0/site-lib/cstruct 25 | 26 | DISABLE_BYTE=true 27 | 28 | # needed? 29 | export lem LEMLIB EXTRACTDIR cppo LD_LIBRARY_PATH DISABLE_BYTE 30 | -------------------------------------------------------------------------------- /fs_spec/src/posix/1: -------------------------------------------------------------------------------- 1 | These functions shall fail if: 2 | 3 | [EEXIST] 4 | The path2 argument resolves to an existing directory entry or refers to a symbolic link. 5 | 6 | FIXME shouldn't this also be a file entry? FIXME error in posix spec? 7 | 8 | [ENOENT] 9 | A component of either path prefix does not exist; the file named by path1 does not exist; or path1 or path2 points to an empty string. 10 | [ENOTDIR] 11 | A component of either path prefix names an existing file that is neither a directory nor a symbolic link to a directory, or the path1 argument contains at least one non- character and ends with one or more trailing characters and the last pathname component names an existing file that is neither a directory nor a symbolic link to a directory, or the path1 argument names an existing non-directory file and the path2 argument names a nonexistent file, contains at least one non- character, and ends with one or more trailing characters. 12 | [EPERM] 13 | The file named by path1 is a directory and either the calling process does not have appropriate privileges or the implementation prohibits using link() on directories. 14 | -------------------------------------------------------------------------------- /fs_spec/src/posix/write.md.old: -------------------------------------------------------------------------------- 1 | OOOOOOOOOOOOOOOOOOOOLD 2 | 3 | # Description 4 | 5 | > The write() function shall attempt to write nbyte bytes from the buffer pointed 6 | > to by buf to the file associated with the open file descriptor, fildes. 7 | > 8 | > Before any action described below is taken, and if nbyte is zero and 9 | > the file is a regular file, the write() function may detect and return errors as described below. 10 | > In the absence of errors, or if error detection is not performed, 11 | > the write() function shall return zero and have no other results. 12 | > If nbyte is zero and the file is not a regular file, the results are unspecified. 13 | 14 | Times 15 | 16 | > Upon successful completion, where nbyte is greater than 0, 17 | > write() shall mark for update the last data modification and 18 | > last file status change timestamps of the file, 19 | > and if the file is a regular file, the S_ISUID and S_ISGID bits of the file mode may be cleared. 20 | 21 | What about the access time? 22 | Likely we have the following situations: 23 | 1) Write for new file creation -> the access time is unset 24 | 2) Write for file modification -> the access time does not change. 25 | -------------------------------------------------------------------------------- /fs_test/example_traces/os_trace1-int.trace.interp.expected-check.trace: -------------------------------------------------------------------------------- 1 | # processing file 'example_traces/os_trace1-int.trace' ... 2 | @type trace 3 | 4 | 3: mkdir "/tmp_dir_1490/" 0o000 5 | Tau 6 | RV_none 7 | 8 | 5: mkdir "/tmp_dir_1490/d1" 0o000 9 | Tau 10 | RV_none 11 | 12 | 7: mkdir "/tmp_dir_1490/d1/empty_dir1" 0o000 13 | Tau 14 | RV_none 15 | 16 | 9: mkdir "/tmp_dir_1490/d1/empty_dir2" 0o000 17 | Tau 18 | RV_none 19 | 20 | 11: mkdir "/tmp_dir_1490/d1/nonempty_dir1" 0o000 21 | Tau 22 | RV_none 23 | 24 | 13: open "/tmp_dir_1490/d1/nonempty_dir1/f1.txt" [O_CREAT;O_RDWR] 0o000 25 | Tau 26 | RV_num(3) 27 | 28 | 15: open "/tmp_dir_1490/d1/nonempty_dir1/f1.txt" [O_RDWR] 29 | Tau 30 | RV_num(4) 31 | 32 | 17: stat "/tmp_dir_1490/d1/nonempty_dir1/f1.txt" 33 | Tau 34 | RV_stat { st_dev=2049; st_ino=6; st_kind=S_IFREG; st_perm=0o000; st_nlink=2; st_uid=0; st_gid=0; st_rdev=0; st_size=0; } 35 | 36 | # stat a non-existing file 37 | 20: stat "/tmp_dir_1490/d1/nosuchdir/non.txt" 38 | Tau 39 | ENOENT 40 | 41 | 42 | -------------------------------------------------------------------------------- /.tr61/Makefile.local: -------------------------------------------------------------------------------- 1 | # -*- mode: makefile -*- 2 | 3 | install: 4 | cd fs_test && cp check.native fs_test fs_test.sh posix.native run_trace tgen debug/debug.native debug/check2.native /tmp/l/bin/tmp 5 | 6 | uninstall: 7 | cd /tmp/l/bin/tmp && rm -f check.native fs_test fs_test.sh posix.native run_trace tgen debug.native check2.native 8 | 9 | plain_binaries: sibylfs_OS_ARCH.tar.gz FORCE 10 | 11 | # assumes result is present 12 | sibylfs_OS_ARCH.tar.gz: FORCE 13 | ./patchelf_nix-build.sh 14 | -chmod -R ugo+w /tmp/sibylfs 15 | -rm -rf /tmp/sibylfs 16 | -mkdir /tmp/sibylfs 17 | cp -R result/bin /tmp/sibylfs 18 | # cp result/fs_test/lib/fs_test_version.ml /tmp/sibylfs 19 | tar -C /tmp -cvzf $@ sibylfs 20 | #cp /tmp/$@ sibylfs_OS_ARCH.tar.gz 21 | 22 | 23 | # http://sandervanderburg.blogspot.co.uk/2014/07/backing-up-nix-and-hydra-builds.html 24 | 25 | nix_binaries: sibylfs_nix_OS_ARCH.closure FORCE 26 | 27 | sibylfs_nix_OS_ARCH.closure: FORCE 28 | nix-store --export $$(nix-store --query --requisites ./result) > $@ 29 | # nix-store --export $$(nix-store --query --requisites --include-outputs ./result) > $@ 30 | 31 | 32 | clean_not_lib: 33 | cd fs_test && $(MAKE) clean_not_lib 34 | 35 | FORCE: 36 | -------------------------------------------------------------------------------- /fs_spec/default.nix: -------------------------------------------------------------------------------- 1 | { }: 2 | let 3 | pkgs = import {}; 4 | inherit (pkgs) stdenv fetchgit ocaml; 5 | op = pkgs.ocamlPackages; 6 | inherit (op) findlib cppo sexplib cstruct; 7 | sha = import ../.nix/sha { }; 8 | fd_send_recv = import ../.nix/fd-send-recv { }; 9 | lem_in_nix = import ../.nix/lem { }; 10 | ocaml_cow = import ../.nix/ocaml_cow { }; 11 | ocaml_dyntype = import ../.nix/dyntype { }; 12 | ocaml_version = (stdenv.lib.getVersion ocaml); 13 | in stdenv.mkDerivation { 14 | 15 | name = "fs_spec"; 16 | 17 | src = ./.; 18 | 19 | # git for version num 20 | buildInputs = [ ocaml findlib cppo sexplib sha op.cmdliner fd_send_recv 21 | lem_in_nix pkgs.coreutils pkgs.git op.menhir ocaml_cow ]; 22 | 23 | cppo="${cppo}/bin/cppo"; 24 | lem="${lem_in_nix}/lem/lem"; 25 | LEMLIB="${lem_in_nix}/lem/library"; 26 | LD_LIBRARY_PATH="${cstruct}/lib/ocaml/${ocaml_version}/site-lib/cstruct"; 27 | EXTRACTDIR="${lem_in_nix}/lem/ocaml-lib/_build"; 28 | DISABLE_BYTE="true"; 29 | 30 | buildPhase = '' 31 | make 32 | mkdir -p $out 33 | cp -RL _build $out 34 | ''; 35 | 36 | installPhase = "true"; # skip 37 | 38 | } 39 | -------------------------------------------------------------------------------- /fs_test/adhoc_tests/adhoc_rename_test_tr_7: -------------------------------------------------------------------------------- 1 | mkdir /tmp_dir_37/ 0 2 | mkdir /tmp_dir_37/d1 0 3 | mkdir /tmp_dir_37/d1/empty_dir1 0 4 | mkdir /tmp_dir_37/d1/empty_dir2 0 5 | mkdir /tmp_dir_37/d1/nonempty_dir1 0 6 | open /tmp_dir_37/d1/nonempty_dir1/f1.txt [O_CREAT] 7 | open /tmp_dir_37/d1/nonempty_dir1/f2.txt [O_CREAT] 8 | mkdir /tmp_dir_37/d1/nonempty_dir1/d2 0 9 | open /tmp_dir_37/d1/nonempty_dir1/d2/f3.txt [O_CREAT] 10 | open /tmp_dir_37/d1/nonempty_dir1/d2/f4.txt [O_CREAT] 11 | mkdir /tmp_dir_37/d1/nonempty_dir1/d2/d3 0 12 | mkdir /tmp_dir_37/d1/nonempty_dir1/d2/d4 0 13 | mkdir /tmp_dir_37/d1/nonempty_dir2 0 14 | open /tmp_dir_37/d1/nonempty_dir2/f1.txt [O_CREAT] 15 | open /tmp_dir_37/d1/nonempty_dir2/f2.txt [O_CREAT] 16 | mkdir /tmp_dir_37/d1/nonempty_dir2/d2 0 17 | open /tmp_dir_37/d1/nonempty_dir2/d2/f3.txt [O_CREAT] 18 | open /tmp_dir_37/d1/nonempty_dir2/d2/f4.txt [O_CREAT] 19 | mkdir /tmp_dir_37/d1/nonempty_dir2/d2/d3 0 20 | mkdir /tmp_dir_37/d1/nonempty_dir2/d2/d4 0 21 | stat "The following may give EINVAL, but is expected to give ENOTDIR" 22 | rename /tmp_dir_37/ /tmp_dir_37/d1/nonempty_dir1/f1.txt/ 23 | stat "The following must not give EINVAL, and shall give ENOTDIR" 24 | rename /tmp_dir_37/d1/nonempty_dir2 /tmp_dir_37/d1/nonempty_dir1/f1.txt/ 25 | -------------------------------------------------------------------------------- /fs_test/lib/.depend: -------------------------------------------------------------------------------- 1 | checkLib.x : trace.x stat.x dump.x diff.x checklib_shared_types.x 2 | checkLib_with_posix.x : checkLib.x posix_ops.x 3 | checklib_shared_types.x : dump.x 4 | diff.x : 5 | dump.x : diff.x fs_path.x 6 | fs_ast.x : dump.x 7 | fs_lexer.x : fs_ast.x fs_lr_parser.x 8 | fs_lr_parser.x : dump.x fs_ast.x 9 | fs_path.x : 10 | fs_test_cli.x : 11 | fs_test_config.x : 12 | fs_test_html.x : trace.x fs_test_util.x stat.x checkLib.x fs_test_version.x dump.x fs_test_index.x fs_test_config.x 13 | fs_test_index.x : fs_test_config.x 14 | fs_test_mount.x : fs_test_config.x fs_test_system.x 15 | fs_test_system.x : fs_test_config.x syscall.x 16 | fs_test_util.x : 17 | fs_test_version.x : 18 | posix_agent.x : 19 | posix_ops.x : fs_path.x dump.x fs_test_system.x posix_agent.x syscall.x checklib_shared_types.x 20 | stat.x : diff.x 21 | syscall.x : 22 | trace.x : fs_lexer.x fs_lr_parser.x dump.x fs_ast.x 23 | 24 | 25 | xs:=fs_test_version.x posix_agent.x syscall.x fs_test_config.x fs_test_system.x fs_test_mount.x fs_path.x fs_test_cli.x diff.x fs_test_index.x dump.x checklib_shared_types.x posix_ops.x fs_ast.x fs_lr_parser.x fs_lexer.x trace.x fs_test_util.x stat.x checkLib.x checkLib_with_posix.x fs_test_html.x 26 | 27 | -------------------------------------------------------------------------------- /fs_test/adhoc_tests/adhoc_readdir_tests-int.trace: -------------------------------------------------------------------------------- 1 | # adhoc_readdir_tests 2 | # 3 | # initialization 4 | mkdir /empty_dir 0o777 5 | mkdir /non_empty_dir 0o777 6 | 7 | open_close /non_empty_dir/f1.txt [O_RDWR;O_CREAT] 0o666 8 | open_close /non_empty_dir/f2.txt [O_RDWR;O_CREAT] 0o666 9 | open_close /non_empty_dir/f3.txt [O_RDWR;O_CREAT] 0o666 10 | open_close /non_empty_dir/f4.txt [O_RDWR;O_CREAT] 0o666 11 | open_close /non_empty_dir/f5.txt [O_RDWR;O_CREAT] 0o666 12 | 13 | 14 | # the read tests 15 | 16 | opendir /empty_dir 17 | readdir (DH 1) 18 | readdir (DH 1) 19 | readdir (DH 1) 20 | readdir (DH 1) 21 | closedir (DH 1) 22 | 23 | 24 | opendir /non_empty_dir 25 | readdir (DH 1) 26 | unlink /non_empty_dir/f3.txt 27 | readdir (DH 1) 28 | readdir (DH 1) 29 | readdir (DH 1) 30 | open_close /non_empty_dir/f6.txt [O_RDWR;O_CREAT] 0o666 31 | readdir (DH 1) 32 | readdir (DH 1) 33 | readdir (DH 1) 34 | readdir (DH 1) 35 | readdir (DH 1) 36 | readdir (DH 1) 37 | readdir (DH 1) 38 | readdir (DH 1) 39 | rewinddir (DH 1) 40 | readdir (DH 1) 41 | readdir (DH 1) 42 | readdir (DH 1) 43 | readdir (DH 1) 44 | readdir (DH 1) 45 | readdir (DH 1) 46 | readdir (DH 1) 47 | readdir (DH 1) 48 | readdir (DH 1) 49 | closedir (DH 1) 50 | 51 | 52 | opendir /no_such_dir 53 | readdir (DH 1) 54 | closedir (DH 1) 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /fs_test/example_traces/os_trace1-int.trace.check.expected: -------------------------------------------------------------------------------- 1 | # processing file 'example_traces/os_trace1-int.trace.interp.expected-check.trace' ... 2 | # processing file 'example_traces/os_trace1-int.trace' ... 3 | @type trace 4 | 5 | 4: mkdir "/tmp_dir_1490/" 0o000 6 | 5: Tau 7 | 6: RV_none 8 | 9 | 8: mkdir "/tmp_dir_1490/d1" 0o000 10 | 9: Tau 11 | 10: RV_none 12 | 13 | 12: mkdir "/tmp_dir_1490/d1/empty_dir1" 0o000 14 | 13: Tau 15 | 14: RV_none 16 | 17 | 16: mkdir "/tmp_dir_1490/d1/empty_dir2" 0o000 18 | 17: Tau 19 | 18: RV_none 20 | 21 | 20: mkdir "/tmp_dir_1490/d1/nonempty_dir1" 0o000 22 | 21: Tau 23 | 22: RV_none 24 | 25 | 24: open "/tmp_dir_1490/d1/nonempty_dir1/f1.txt" [O_CREAT;O_RDWR] 0o000 26 | 25: Tau 27 | 26: RV_num(3) 28 | 29 | 28: open "/tmp_dir_1490/d1/nonempty_dir1/f1.txt" [O_RDWR] 30 | 29: Tau 31 | 30: RV_num(4) 32 | 33 | 32: stat "/tmp_dir_1490/d1/nonempty_dir1/f1.txt" 34 | 33: Tau 35 | 34: RV_stat { st_dev=2049; st_ino=6; st_kind=S_IFREG; st_perm=0o000; st_nlink=2; st_uid=0; st_gid=0; st_rdev=0; st_size=0; } 36 | 37 | # stat a non-existing file 38 | 37: stat "/tmp_dir_1490/d1/nosuchdir/non.txt" 39 | 38: Tau 40 | 39: ENOENT 41 | 42 | 43 | 44 | # trace accepted 45 | -------------------------------------------------------------------------------- /fs_test/lib/Makefile.srcs: -------------------------------------------------------------------------------- 1 | # -*- mode: makefile -*- 2 | SHELL:=/bin/bash 3 | 4 | # bash will read this config file first 5 | BASH_ENV=bash_env.sh 6 | export BASH_ENV 7 | 8 | ######################################################################## 9 | # srcs 10 | 11 | # this is self-contained: we don't have the .depend info before we 12 | # build the srcs 13 | 14 | srcs: fs_lr_parser.mli fs_lr_parser.ml fs_lexer.ml fs_test_version.ml 15 | touch srcs 16 | 17 | FS_AST_MLIS:=diff.mli fs_path.mli dump.mli fs_ast.mli 18 | 19 | fs_ast.cmi: $(FS_AST_MLIS) 20 | (export DISABLE_NTVE=""; $$ocamlopt -c $(FS_AST_MLIS)) 21 | 22 | fs_lr_parser.mli: fs_lr_parser.mly fs_ast.cmi 23 | run_menhir $< 24 | 25 | 26 | # following is a dummy rule so that make only runs menhir once 27 | # http://stackoverflow.com/questions/2973445/gnu-makefile-rule-generating-a-few-targets-from-a-single-source-file 28 | # http://stackoverflow.com/questions/12322823/semi-colon-in-makefile-rule-definition 29 | fs_lr_parser.ml: fs_lr_parser.mli ; 30 | 31 | fs_lr_parser.cmi: fs_lr_parser.mli fs_ast.cmi # fs_ast.cmi will already exist 32 | $$ocamlc fs_lr_parser.mli 33 | 34 | fs_lexer.ml: fs_lexer.mll fs_lr_parser.cmi 35 | ocamllex $< 36 | 37 | 38 | 39 | ######################################## 40 | # fs_test_version.ml 41 | 42 | fs_test_version.ml: 43 | ./mk_fs_test_version.sh 44 | 45 | -------------------------------------------------------------------------------- /fs_spec/src/tr/3: -------------------------------------------------------------------------------- 1 | rename /tmp_dir_306/d1/nonempty_dir1/f1.txt /tmp_dir_306/d1/nonexist_dir1/ 2 | [ENOTDIR] 3 | 4 | POSIX says 5 | 6 | [ENOTDIR] [CX] A component of either path prefix names an existing 7 | file that is neither a directory nor a symbolic link to a directory; 8 | 9 | NA 10 | 11 | or the old argument names a directory and the new argument names a 12 | non-directory file; 13 | 14 | NA 15 | 16 | or the old argument contains at least one non- 17 | character and ends with one or more trailing 18 | characters and the last pathname component names an existing file that 19 | is neither a directory nor a symbolic link to a directory; 20 | 21 | NA 22 | 23 | or the old 24 | argument names an existing non-directory file and the new argument 25 | names a nonexistent file, contains at least one non- 26 | character, and ends with one or more trailing characters; 27 | 28 | Yes, this is applicable 29 | 30 | FIXME note the requirement that "the new argument ... contains at least one non- character. This implies that 31 | 32 | rename f1.txt nonexist_dir1/ should not fail with ENOTDIR 33 | 34 | or 35 | the new argument names an existing non-directory file, contains at 36 | least one non- character, and ends with one or more trailing 37 | characters. 38 | 39 | -------------------------------------------------------------------------------- /fs_spec/src/t_fs_specScript.patch: -------------------------------------------------------------------------------- 1 | 2422,2425c2422,2427 2 | < (*val >>= : forall 'impl 'a 'b. fsmonad 'impl 'a -> ('a -> fsmonad 'impl 'b) -> fsmonad 'impl 'b*) 3 | < val _ = Define ` 4 | < (>>= = fsm_bind)`; 5 | < 6 | --- 7 | > (* manually added *) 8 | > val _ = add_infix(">>=", 90, HOLgrammars.NONASSOC); 9 | > val fsm_bind'_def = new_infixl_definition( 10 | > "fsm_bind'", 11 | > --`$>>= x y = fsm_bind x y`--, 12 | > 500); 13 | 2658,2665c2660,2672 14 | < (*val <|||> : forall 'impl 'a 'b. fsmonad 'impl 'a -> fsmonad 'impl 'b -> fsmonad 'impl ('a * 'b)*) 15 | < val _ = Define ` 16 | < (<|||> = fsm_parallel_composition)`; 17 | < 18 | < 19 | < (*val ||| : forall 'impl. fsmonad 'impl ret_value -> fsmonad 'impl ret_value -> fsmonad 'impl ret_value*) 20 | < val _ = Define ` 21 | < (||| = fsm_parallel_composition_drop)`; 22 | --- 23 | > (* manually added *) 24 | > val _ = add_infix("<|||>", 90, HOLgrammars.NONASSOC); 25 | > val fsm_parallel_composition'_def = new_infixl_definition( 26 | > "fsm_parallel_composition'", 27 | > --`$<|||> x y = fsm_parallel_composition x y`--, 28 | > 500); 29 | > 30 | > (* manually added *) 31 | > val _ = add_infix("|||", 90, HOLgrammars.NONASSOC); 32 | > val fsm_parallel_composition_drop'_def = new_infixl_definition( 33 | > "fsm_parallel_composition_drop'", 34 | > --`$||| x y = fsm_parallel_composition_drop x y`--, 35 | > 500); 36 | -------------------------------------------------------------------------------- /fs_test/lib/Makefile: -------------------------------------------------------------------------------- 1 | SHELL:=/bin/bash 2 | 3 | # bash will read this config file first 4 | BASH_ENV=bash_env.sh 5 | export BASH_ENV 6 | 7 | ######################################## all, srcs, before_all 8 | all: before_all srcs 9 | $(MAKE) fs_check_lib.cma fs_check_lib.cmxa syscall_stubs.o 10 | 11 | 12 | srcs: # FIXME depends? 13 | $(MAKE) -f Makefile.srcs srcs 14 | 15 | before_all: 16 | $(MAKE) -C .. include 17 | 18 | 19 | ######################################## compile 20 | 21 | compile: $(xs) 22 | 23 | include .depend 24 | 25 | %.x: %.mli %.ml srcs 26 | $$ocamlc -c $*.mli $*.ml 27 | $$ocamlopt -c $*.mli $*.ml 28 | touch $@ 29 | 30 | %.x: %.ml srcs 31 | $$ocamlc -c $*.ml 32 | $$ocamlopt -c $*.ml 33 | touch $@ 34 | 35 | fs_check_lib.cma: $(xs) 36 | $$mk_cma -g -a -o $@ $(xs:.x=.cmo) 37 | 38 | fs_check_lib.cmxa: $(xs) 39 | $$mk_cmxa -g -a -o $@ $(xs:.x=.cmx) 40 | 41 | 42 | .SUFFIXES: .o .c 43 | 44 | CFLAGS:=-I $(shell ocamlc -where) -fPIC -Wall -Wextra -Werror -std=c99 45 | 46 | %.o: %.c 47 | cc $(CFLAGS) -o $*.o -c $*.c 48 | 49 | clean: 50 | rm -f *.cmi *.cmo *.cmx *.o *.x *.cma *.cmxa *.a a.out 51 | rm -f *.x 52 | rm -f fs_lexer.ml fs_lr_parser.mli fs_lr_parser.ml 53 | rm -f fs_test_version.ml 54 | rm -f srcs 55 | rm -rf ocamldoc 56 | 57 | -include Makefile.local 58 | 59 | FORCE: 60 | 61 | ## local vars 62 | # Local variables: 63 | # mode: outline-minor 64 | # outline-regexp: "[#][#]+ .*" 65 | # End: 66 | -------------------------------------------------------------------------------- /fs_spec/src/tr/19: -------------------------------------------------------------------------------- 1 | OS_CALL(Pid 1,mkdir /tmp_dir_0/ 0o000) 2 | None1 3 | OS_CALL(Pid 1,mkdir /tmp_dir_0/empty_dir 0o000) 4 | None1 5 | OS_CALL(Pid 1,mkdir /tmp_dir_0/nonempty_dir 0o000) 6 | None1 7 | OS_CALL(Pid 1,open_close /tmp_dir_0/nonempty_dir/f1.txt [O_RDWR;O_CREAT] 0o000) 8 | None1 9 | OS_CALL(Pid 1,open_close /tmp_dir_0/nonempty_dir/f2.txt [O_RDWR;O_CREAT] 0o000) 10 | None1 11 | OS_CALL(Pid 1,pwrite /tmp_dir_0/nonempty_dir/f2.txt 0 "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit an" 875) 12 | Int1(875) 13 | OS_CALL(Pid 1,open /tmp_dir_0/ [O_RDONLY;O_APPEND;O_CLOEXEC;O_CREAT;O_DIRECTORY;O_EXCL;O_NOFOLLOW;O_TRUNC] 0o000) 14 | [EISDIR] 15 | -------------------------------------------------------------------------------- /fs_test/bash_env.sh: -------------------------------------------------------------------------------- 1 | set -a # export all vars 2 | # set -x # debug 3 | 4 | BASH_DIR=$(realpath $(dirname $BASH_SOURCE)) 5 | ROOT=$BASH_DIR/.. 6 | 7 | test -f $ROOT/config.sh && source $ROOT/config.sh 8 | 9 | SPEC_BUILD="${SPEC_BUILD:-$ROOT/fs_spec/_build}" # default if not set 10 | 11 | # cmis from elsewhere 12 | from_lem=" 13 | $EXTRACTDIR/*.cmi 14 | $EXTRACTDIR/extract.* 15 | " 16 | from_spec=" 17 | $SPEC_BUILD/lem_support.cmi 18 | $SPEC_BUILD/abstract_string.cmi 19 | $SPEC_BUILD/fs_interface.cmi 20 | $SPEC_BUILD/fs_dict_wrappers.cmi 21 | $SPEC_BUILD/fs_prelude.cmi 22 | $SPEC_BUILD/fs_spec_lib.* 23 | " 24 | 25 | COREPKGS="unix,bigarray,str,num,bytes" 26 | XTRAPKGS="bytes,sexplib,sexplib.syntax,cmdliner,fd-send-recv,sha,cow,cow.syntax,unix-fcntl,$BISECT" 27 | PKGS="-package $COREPKGS,$XTRAPKGS" 28 | SYNTAX="-syntax camlp4o" 29 | WARN="-w @f@p@u@s@40" 30 | CCFLAGS="-g" 31 | 32 | WITH_FS_CHECK_LIB="-I $BASH_DIR/lib fs_check_lib.cmxa" 33 | 34 | # FIXME we should include fs_check_lib when we know it has been built 35 | ocamlc="$DISABLE_BYTE ocamlfind ocamlc $WARN $CCFLAGS $PKGS -I $BASH_DIR/include extract.cma fs_spec_lib.cma $SYNTAX" 36 | ocamlopt="$DISABLE_NTVE ocamlfind ocamlopt $WARN $CCFLAGS $PKGS -I $BASH_DIR/include extract.cmxa fs_spec_lib.cmxa $SYNTAX" 37 | ocamldep="ocamlfind ocamldep $WARN $CCFLAGS $PKGS -I $BASH_DIR/include extract.cmxa fs_spec_lib.cmxa $SYNTAX $FCLXA" 38 | 39 | mk_native="$ocamlopt $WITH_FS_CHECK_LIB $BASH_DIR/lib/syscall_stubs.o" 40 | -------------------------------------------------------------------------------- /fs_test/repro/rename_leak.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | int write_sz = 4096*4096*4; 11 | 12 | int main() { 13 | long* page; 14 | int fd, i, j, sz; 15 | struct stat st; 16 | 17 | page = (long *)malloc(write_sz); 18 | 19 | for (j = 0; j < 32; j++) { 20 | errno = 0; 21 | fd = open("space_64M",O_CREAT | O_WRONLY,0600); 22 | if (fd == -1) { 23 | printf("open error: %s\n",strerror(errno)); 24 | } 25 | 26 | errno = 0; 27 | sz = write(fd,page,write_sz); 28 | if (sz == -1) { 29 | printf("write error: %s\n",strerror(errno)); 30 | } else if (sz != write_sz) { 31 | printf("write only %d\n",sz); 32 | } 33 | close(fd); 34 | 35 | link("space_64M","space_64M_hardlink"); 36 | link("space_64M_hardlink","space_64M_hardlink2"); 37 | 38 | fd = open("empty",O_CREAT,0600); 39 | close(fd); 40 | rename("empty","space_64M"); 41 | rename("space_64M","empty"); 42 | rename("empty","space_64M_hardlink"); 43 | rename("space_64M_hardlink","empty"); 44 | 45 | stat("space_64M_hardlink2",&st); 46 | 47 | printf("nlink = %d\n",(int)st.st_nlink); 48 | 49 | fd = open("empty",O_CREAT,0600); 50 | close(fd); 51 | 52 | rename("empty","space_64M_hardlink2"); 53 | rename("space_64M_hardlink2","empty"); 54 | } 55 | 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /fs_spec/src/tr/20: -------------------------------------------------------------------------------- 1 | OS_CALL(Pid 1,mkdir /tmp_dir_8336/ 0o000) 2 | None1 3 | OS_CALL(Pid 1,mkdir /tmp_dir_8336/empty_dir 0o000) 4 | None1 5 | OS_CALL(Pid 1,mkdir /tmp_dir_8336/nonempty_dir 0o000) 6 | None1 7 | OS_CALL(Pid 1,open_close /tmp_dir_8336/nonempty_dir/f1.txt [O_RDWR;O_CREAT] 0o000) 8 | None1 9 | OS_CALL(Pid 1,open_close /tmp_dir_8336/nonempty_dir/f2.txt [O_RDWR;O_CREAT] 0o000) 10 | None1 11 | OS_CALL(Pid 1,pwrite /tmp_dir_8336/nonempty_dir/f2.txt 0 "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit an" 875) 12 | Int1(875) 13 | OS_CALL(Pid 1,open /tmp_dir_8336/nonempty_dir/f1.txt/ [O_RDONLY;O_APPEND;O_CLOEXEC;O_DIRECTORY;O_EXCL;O_NOFOLLOW;O_TRUNC] 0o000) 14 | [ENOTDIR] 15 | OS_CALL(Pid 1,close (FD 3)) 16 | [EBADF] 17 | -------------------------------------------------------------------------------- /.nix/ocaml-unix-errno/default.nix: -------------------------------------------------------------------------------- 1 | { }: 2 | let 3 | pkgs = import {}; 4 | stdenv = pkgs.stdenv; 5 | fetchgit = pkgs.fetchgit; 6 | ocaml = pkgs.ocaml; 7 | findlib = pkgs.ocamlPackages.findlib; # needed? 8 | ocaml_version = (stdenv.lib.getVersion ocaml); 9 | in 10 | let 11 | rresult = stdenv.mkDerivation { 12 | name = "ocaml-rresult"; 13 | 14 | src = fetchgit { 15 | url = https://github.com/dbuenzli/rresult.git; 16 | rev = "4524762a5"; 17 | sha256 = "1zriaj4xaj7a5zw848m6sp0rh69xk15zdazpnkpw899y39yv5a0p"; 18 | }; 19 | 20 | buildInputs = [ ocaml findlib pkgs.opam pkgs.ocamlPackages.ctypes ]; 21 | 22 | buildPhase = '' 23 | 24 | ocaml pkg/git.ml 25 | ocaml pkg/build.ml native=true native-dynlink=true # FIXME tr not sure about these; trying to get the same result as https://github.com/dbuenzli/rresult/blob/master/opam 26 | 27 | ''; 28 | 29 | installPhase = '' 30 | opam-installer --prefix=$out/lib/ocaml/${ocaml_version}/site-lib/ --libdir=. rresult.install 31 | ''; 32 | 33 | createFindlibDestdir = true; 34 | 35 | }; 36 | in 37 | stdenv.mkDerivation { 38 | name = "ocaml-unix-errno"; 39 | 40 | src = fetchgit { 41 | url = https://github.com/dsheets/ocaml-unix-errno.git; 42 | rev = "5b705b7"; 43 | sha256 = "0pf54p7pcvbxhszh7scsw81m8p2yl7l3mqpy7mxz9nygaq6xibrp"; 44 | }; 45 | 46 | buildInputs = [ ocaml findlib pkgs.ocamlPackages.ctypes rresult ]; 47 | 48 | createFindlibDestdir = true; 49 | 50 | rresult = rresult; 51 | 52 | } 53 | -------------------------------------------------------------------------------- /fs_test/example_traces/fs_trace1-fs.trace: -------------------------------------------------------------------------------- 1 | mkdir /tmp_dir_1490/ 0 2 | Tau 3 | RV_none 4 | mkdir /tmp_dir_1490/d1 0 5 | Tau 6 | RV_none 7 | mkdir /tmp_dir_1490/d1/empty_dir1 0 8 | Tau 9 | RV_none 10 | mkdir /tmp_dir_1490/d1/empty_dir2 0 11 | Tau 12 | RV_none 13 | mkdir /tmp_dir_1490/d1/nonempty_dir1 0 14 | Tau 15 | RV_none 16 | open_close /tmp_dir_1490/d1/nonempty_dir1/f1.txt [O_CREAT] 0 17 | Tau 18 | RV_none 19 | open_close /tmp_dir_1490/d1/nonempty_dir1/f2.txt [O_CREAT] 0 20 | Tau 21 | RV_none 22 | mkdir /tmp_dir_1490/d1/nonempty_dir1/d2 0 23 | Tau 24 | RV_none 25 | open_close /tmp_dir_1490/d1/nonempty_dir1/d2/f3.txt [O_CREAT] 0 26 | Tau 27 | RV_none 28 | open_close /tmp_dir_1490/d1/nonempty_dir1/d2/f4.txt [O_CREAT] 0 29 | Tau 30 | RV_none 31 | mkdir /tmp_dir_1490/d1/nonempty_dir1/d2/d3 0 32 | Tau 33 | RV_none 34 | mkdir /tmp_dir_1490/d1/nonempty_dir1/d2/d4 0 35 | Tau 36 | RV_none 37 | mkdir /tmp_dir_1490/d1/nonempty_dir2 0 38 | Tau 39 | RV_none 40 | open_close /tmp_dir_1490/d1/nonempty_dir2/f1.txt [O_CREAT] 0 41 | Tau 42 | RV_none 43 | open_close /tmp_dir_1490/d1/nonempty_dir2/f2.txt [O_CREAT] 0 44 | Tau 45 | RV_none 46 | mkdir /tmp_dir_1490/d1/nonempty_dir2/d2 0 47 | Tau 48 | RV_none 49 | open_close /tmp_dir_1490/d1/nonempty_dir2/d2/f3.txt [O_CREAT] 0 50 | Tau 51 | RV_none 52 | open_close /tmp_dir_1490/d1/nonempty_dir2/d2/f4.txt [O_CREAT] 0 53 | Tau 54 | RV_none 55 | mkdir /tmp_dir_1490/d1/nonempty_dir2/d2/d3 0 56 | Tau 57 | RV_none 58 | mkdir /tmp_dir_1490/d1/nonempty_dir2/d2/d4 0 59 | Tau 60 | RV_none 61 | rename /tmp_dir_1490/ /tmp_dir_1490/d1/nonempty_dir1/f1.txt/ 62 | Tau 63 | EINVAL 64 | -------------------------------------------------------------------------------- /.nix/lem/default.nix: -------------------------------------------------------------------------------- 1 | { }: 2 | let 3 | pkgs = import {}; 4 | stdenv = pkgs.stdenv; 5 | fetchgit = pkgs.fetchgit; 6 | ocaml = pkgs.ocaml; 7 | git = pkgs.git; 8 | findlib = pkgs.ocamlPackages.findlib; # needed? 9 | # isabelle = import ./../isabelle { }; # not needed? 10 | in stdenv.mkDerivation { 11 | name = "lem"; 12 | 13 | src = fetchgit { 14 | url = https://tomridge@bitbucket.org/tomridge/lem.git; 15 | rev = "5b4a168"; 16 | sha256 = "19642yadi089p8si87n0rbn0mwwxyvzjrv33g848gaqy811i0zak"; 17 | }; 18 | 19 | buildInputs = [ ocaml git pkgs.perl ]; # isabelle pkgs.pkgconfig findlib 20 | 21 | buildPhase = '' 22 | echo 'let v="5b4a168"' >src/version.ml # complete hack - the source code isn't a git repo after fetchgit 23 | echo "!!!" 24 | make 25 | 26 | echo "!!!" 27 | make ocaml-libs 28 | 29 | #mkdir -p $out/lem/.isabelle # after build, need to copy these images to local .isabelle 30 | #export USER_HOME=$out/lem 31 | # make isa-libs 32 | #isabelle build -d isabelle-lib -b LEM # do this in the lem source dir 33 | 34 | # sudo chmod u+w ~/.isabelle/Isabelle2014/heaps/polyml-5.5.2_x86-linux/* 35 | # cp .isabelle/Isabelle2014/heaps/polyml-5.5.2_x86-linux/* ~/.isabelle/Isabelle2014/heaps/polyml-5.5.2_x86-linux/ 36 | ''; 37 | 38 | installPhase = '' 39 | mkdir -p $out/lem && cp -R -L * $out/lem 40 | ''; # so we can inspect the result 41 | # note that we need to export LEM_LIBRARY_PATH=/library before invoking lem 42 | 43 | } 44 | -------------------------------------------------------------------------------- /.nix/ocaml_cow/default.nix: -------------------------------------------------------------------------------- 1 | { }: 2 | let 3 | pkgs = import {}; 4 | stdenv = pkgs.stdenv; 5 | fetchurl = pkgs.fetchurl; 6 | ocaml = pkgs.ocaml; 7 | op = pkgs.ocamlPackages; 8 | findlib = op.findlib; 9 | dyntype = import ../dyntype { }; 10 | omd = import ../omd { }; 11 | ulex = import ../ulex { }; 12 | cstruct = op.cstruct; 13 | ocaml_version = (stdenv.lib.getVersion ocaml); 14 | strace = 15 | if stdenv.isDarwin then null else pkgs.strace; 16 | in stdenv.mkDerivation { 17 | name = "ocaml_cow"; 18 | 19 | src = fetchurl { 20 | url = https://github.com/mirage/ocaml-cow/archive/v1.2.1.tar.gz; 21 | sha256 = "c9ae1f0be8ca2fb37673e89c5e5f1a4cfb70d7cfa7e99322ca49592431434ba0"; 22 | }; 23 | 24 | # patches = ./patch; 25 | 26 | 27 | # postConfigure = '' 28 | # substituteInPlace camlp4/META.in \ 29 | # --replace +camlp4 $out/lib/ocaml/${ocaml_version}/site-lib/camlp4 30 | # ''; 31 | 32 | # substituteInPlace camlp4/config/Camlp4_config.ml \ 33 | # --replace \ 34 | # "Filename.concat ocaml_standard_library" \ 35 | # "Filename.concat \"$out/lib/ocaml/${ocaml_version}/site-lib\"" 36 | 37 | 38 | camlp4=op.camlp4; 39 | 40 | buildInputs = [ ocaml findlib pkgs.which strace ]; 41 | 42 | propagatedBuildInputs = [ dyntype omd op.type_conv op.re ulex op.uri op.xmlm op.ezjsonm op.camlp4 cstruct ]; 43 | 44 | buildPhase = " 45 | export LD_LIBRARY_PATH=${cstruct}/lib/ocaml/${ocaml_version}/site-lib/cstruct 46 | make 47 | "; 48 | 49 | # installPhase="true"; 50 | 51 | createFindlibDestdir = true; 52 | 53 | } 54 | -------------------------------------------------------------------------------- /.tr61/create_coverage_report.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | # this script uses bisect to generate an html report from a directory 4 | # containing bisect files 5 | # 6 | # Usage: 7 | # myself directory_with_posix_results 8 | # 9 | # or for quiet mode 10 | # myself -q directory_with_posix_results 11 | 12 | if [[ ! $@ || $1 == "-h" || $1 == "--help" ]] 13 | then 14 | echo "Usage: create_coverage_report.sh ... [DIR] 15 | 16 | OPTIONS: 17 | -h,--help show a message help 18 | " 19 | exit 0; 20 | fi; 21 | 22 | results_dir=`readlink -f $1` 23 | coverage_report_dir=coverage_report_$(date -I)_$(basename $results_dir) 24 | final_bisect_file=$coverage_report_dir/final_bisect.out 25 | 26 | echo "creating report dir $coverage_report_dir" 27 | mkdir -p $coverage_report_dir 28 | 29 | first_fragment=`find $results_dir -wholename *results/bisect0001.out | head -1` 30 | # we initialize the final_bisect_file with the first bisect fragment we find 31 | cp $first_fragment $final_bisect_file 32 | 33 | echo "merging fragments in $final_bisect_file" 34 | for bisect_fragment in `find $results_dir -wholename *results/bisect*`; 35 | do 36 | # we merge the final_bisect_file with all the bisect fragments 37 | bisect-report -bisect $final_bisect_file $final_bisect_file $bisect_fragment 38 | done; 39 | 40 | initial_dir=`pwd .` 41 | cd build_spec 42 | echo "creating html report in $coverage_report_dir" 43 | bisect-report -html $initial_dir/$coverage_report_dir $initial_dir/$final_bisect_file 44 | 45 | echo "done" 46 | echo "to see the html:" 47 | echo "firefox $initial_dir/$coverage_report_dir/index.html" 48 | -------------------------------------------------------------------------------- /install_opam_deps.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ocaml 2 | 3 | let () = 4 | try Topdirs.dir_directory (Sys.getenv "OCAML_TOPLEVEL_PATH") 5 | with Not_found -> () 6 | ;; 7 | 8 | #use "topfind" 9 | #require "unix" 10 | 11 | let pkg_dir = 12 | "posix-fs-spec-opam-repo/packages/posix-fs-spec/posix-fs-spec.0.0.0" 13 | 14 | let add_dev_repo = [ 15 | "mkdir -p " ^ pkg_dir; 16 | "cp opam " ^ (Filename.concat pkg_dir "opam"); 17 | "opam remote add posix-fs-spec posix-fs-spec-opam-repo"; 18 | ] 19 | 20 | let deps = [ 21 | "posix-fs-spec", add_dev_repo; 22 | ] 23 | 24 | let exec cmdline = 25 | Printf.printf "+ %s\n%!" cmdline; 26 | Unix.system cmdline 27 | 28 | let is_success = function 29 | | Unix.WEXITED 0 -> true 30 | | _ -> false 31 | 32 | let rec run_commands = function 33 | | [] -> () 34 | | cmd::rest -> 35 | begin match exec cmd with 36 | | Unix.WEXITED 0 -> run_commands rest 37 | | Unix.WEXITED x -> 38 | Printf.printf "Subcommand exited with %d, aborting.\n%!" x 39 | | _ -> Printf.printf "Subcommand exited abnormally, aborting.\n%!" 40 | end 41 | 42 | let install_flags = 43 | let argc = Array.length Sys.argv in 44 | let rec find_install i = 45 | if i < argc 46 | then 47 | let n = i + 1 in 48 | if Sys.argv.(i) = "--install" 49 | then if n < argc then Sys.argv.(n) else "" 50 | else find_install n 51 | else "" 52 | in find_install 1 53 | ;; 54 | 55 | List.iter (fun (pkgname, cmds) -> 56 | if not (is_success (exec ("opam info " ^ pkgname))) 57 | then run_commands cmds 58 | else () 59 | ) deps; 60 | 61 | run_commands [ 62 | "opam update"; 63 | "opam pin add posix-fs-spec ."; 64 | "opam update"; 65 | "opam install " ^ install_flags ^ " --deps-only posix-fs-spec"; 66 | ] 67 | -------------------------------------------------------------------------------- /fs_test/lib/.interactive: -------------------------------------------------------------------------------- 1 | #use "topfind";; 2 | #require "unix";; 3 | #require "bigarray";; 4 | #require "str";; 5 | #require "sha";; 6 | #require "num";; 7 | 8 | #require "sexplib";; 9 | #require "sexplib.syntax";; 10 | #require "sexplib.top";; 11 | #camlp4o;; 12 | 13 | #require "bytes";; 14 | #require "cmdliner";; 15 | #require "fd-send-recv";; 16 | 17 | (* 18 | #require "cow";; (* stops "let lexer = " bindings *) 19 | #require "cow.syntax";; 20 | *) 21 | 22 | #directory "../../src_ext/lem/ocaml-lib/_build";; 23 | #load "extract.cma";; 24 | 25 | #directory "../../fs_spec/build";; 26 | #load "fs_spec_lib.cma";; 27 | 28 | (* 29 | 30 | Maybe try: 31 | 32 | #load "fs_check_lib.cma";; 33 | 34 | at the moment this fails with the error: 35 | 36 | Camlp4: Uncaught exception: Symtable.Error (Tag1 ("unix_lseek_int_command")) 37 | 38 | because the syscall_stubs.c aren't available to the top-loop 39 | 40 | NB order of following from: ocamlfind ocamldep -package sexplib,sexplib.syntax,cow,cow.syntax -syntax camlp4o -sort *.ml , then remove those that depend on syscall 41 | *) 42 | 43 | #mod_use "diff.ml";; 44 | #mod_use "fs_path.ml";; 45 | #mod_use "posix_agent.ml";; 46 | #mod_use "stat.ml";; 47 | #mod_use "dump.ml";; 48 | #mod_use "checklib_shared_types.ml";; 49 | #mod_use "fs_ast.ml";; 50 | #mod_use "fs_lr_parser.ml";; (* not with cow *) 51 | #mod_use "fs_lexer.ml";; 52 | #mod_use "trace.ml";; 53 | #mod_use "checkLib.ml";; 54 | 55 | (* 56 | 57 | #load "diff.cmo";; 58 | #load "fs_path.cmo";; 59 | #load "posix_agent.cmo";; 60 | #load "stat.cmo";; 61 | #load "dump.cmo";; 62 | #load "checklib_shared_types.cmo";; 63 | #load "fs_ast.cmo";; 64 | #load "fs_lr_parser.cmo";; 65 | #load "fs_lexer.cmo";; 66 | #load "trace.cmo";; 67 | #load "checkLib.cmo";; 68 | 69 | *) 70 | 71 | -------------------------------------------------------------------------------- /fs_test/example_traces/resolve_test-int.trace: -------------------------------------------------------------------------------- 1 | # create a directory without any permissions 2 | mkdir /tmp_dir_1490/ 0o000 3 | 4 | #we get an error when trying to create a subdirectory 5 | mkdir /tmp_dir_1490/d1 0o700 6 | 7 | #resolving allows using that dir as an argument to change it's permissions 8 | chmod /tmp_dir_1490/ 0o700 9 | chown /tmp_dir_1490/ (User_id 0) Group_id 0 10 | 11 | # now we can create the subdirectory 12 | mkdir /tmp_dir_1490/d1 0o700 13 | mkdir /tmp_dir_1490/d1/empty_dir1 0o700 14 | 15 | # let's remove the search permission from the top dir 16 | chmod /tmp_dir_1490 0o000 17 | 18 | # despite the permissions on d1 not changing, we can't create another subdir now 19 | mkdir /tmp_dir_1490/d1/empty_dir2 0o700 20 | 21 | # with more permissions it works 22 | chmod /tmp_dir_1490 --x------ 23 | mkdir /tmp_dir_1490/d1/empty_dir2 0o700 24 | 25 | #let's try chdir and relative paths 26 | chdir /tmp_dir_1490/d1/ 27 | mkdir empty_dir3 0o700 28 | 29 | chdir .. 30 | mkdir d1/empty_dir4 0o700 31 | 32 | # chdir to a non-existing dir 33 | chdir /tmp_dir_1490/non_existing/ 34 | 35 | # chdir to a file / notice that cwd did not change in previous call 36 | open_close d1/f1.txt [O_CREAT;O_RDWR] 0o777 37 | chdir d1/f1.txt 38 | 39 | # change dir so our working dir always has search permission 40 | # this is required by the implemenentation of the tool posix2 41 | chdir / 42 | 43 | # chdir with missing search permssions 44 | chmod /tmp_dir_1490 --------- 45 | chdir /tmp_dir_1490/d1/ 46 | 47 | chdir / 48 | chmod /tmp_dir_1490 --x------ 49 | chdir /tmp_dir_1490/d1/ 50 | 51 | chdir / 52 | chmod /tmp_dir_1490/d1 --------- 53 | chdir /tmp_dir_1490/d1/ 54 | 55 | # add sufficient permissions for dump to work with posix2 56 | chmod /tmp_dir_1490/ 0o777 57 | chmod /tmp_dir_1490/d1 0o777 58 | dump -------------------------------------------------------------------------------- /fs_test/default.nix: -------------------------------------------------------------------------------- 1 | { }: 2 | let 3 | pkgs = import {}; 4 | inherit (pkgs) stdenv fetchgit ocaml; 5 | op = pkgs.ocamlPackages; 6 | inherit (op) findlib cppo sexplib cstruct; 7 | sha = import ../.nix/sha { }; 8 | fd_send_recv = import ../.nix/fd-send-recv { }; 9 | lem_in_nix = import ../.nix/lem { }; 10 | ocaml_cow = import ../.nix/ocaml_cow { }; 11 | ocaml_dyntype = import ../.nix/dyntype { }; 12 | ocaml-unix-fcntl = import ../.nix/ocaml-unix-fcntl { }; 13 | ocaml-unix-errno = import ../.nix/ocaml-unix-errno { }; 14 | ocaml_version = (stdenv.lib.getVersion ocaml); 15 | fs_spec = import ../fs_spec { }; 16 | in 17 | stdenv.mkDerivation { 18 | 19 | name = "fs_test"; 20 | 21 | src = ./.; 22 | buildInputs = [ ocaml findlib cppo sexplib sha op.ctypes op.cmdliner fd_send_recv 23 | lem_in_nix pkgs.coreutils pkgs.git op.menhir ocaml_cow ocaml-unix-fcntl 24 | ocaml-unix-errno ocaml-unix-errno.rresult fs_spec ]; # git for version num 25 | 26 | LEMLIB = "${lem_in_nix}/lem/library"; 27 | LD_LIBRARY_PATH = "${cstruct}/lib/ocaml/${ocaml_version}/site-lib/cstruct"; 28 | EXTRACTDIR = "${lem_in_nix}/lem/ocaml-lib/_build"; 29 | SPEC_BUILD = "${fs_spec}/_build"; 30 | DISABLE_BYTE = "true"; 31 | 32 | buildPhase = '' 33 | export GIT_REV="$out" 34 | export DIRTY_FLAG="" 35 | make 36 | mkdir -p $out 37 | ''; 38 | 39 | 40 | # commenting so that the closure is not too large 41 | # cp -RL ${fs_spec}/build $out; mkdir -p $out/fs_test; cp -RL . $out/fs_test 42 | 43 | installPhase = '' 44 | mkdir -p $out/bin 45 | cp fs_test fs_test_check fs_test_posix run_trace test_generation/tgen lib/fs_test_version.ml $out/bin 46 | # paths/testpath.native testall.sh 47 | ''; 48 | 49 | # dontPatchELF = true; 50 | dontPatchShebangs = true; 51 | 52 | } 53 | -------------------------------------------------------------------------------- /fs_spec/src/Makefile: -------------------------------------------------------------------------------- 1 | SHELL:=/bin/bash 2 | 3 | # bash will read this config file first 4 | BASH_ENV=bash_env.sh 5 | export BASH_ENV 6 | 7 | # expect files to be linked in from ../Makefile 8 | all: stage1 9 | $(MAKE) fs_spec_lib.cma fs_spec_lib.cmxa # so deps are there 10 | 11 | FORCE: 12 | 13 | run_cppo: $(wildcard *.lem_cppo) 14 | (for f in *.lem_cppo; do $$cppo $$CPPO_ARGS $$f -o $${f/.lem_cppo/.lem}; done) 15 | touch $@ 16 | 17 | # we have to invoke lem with the files in the right order 18 | 19 | dot_lem:=\ 20 | t_list_array.lem \ 21 | t_fs_prelude.lem \ 22 | t_fs_spec_properties.lem \ 23 | t_fs_spec.lem \ 24 | t_fs_spec_fs_command_properties.lem \ 25 | t_fs_spec_properties_perms.lem \ 26 | t_dir_heap.lem 27 | 28 | run_lem: run_cppo $(wildcard *.lem) 29 | $$lem -lib $$LEMLIB $$LEMFLAGS -ocaml $(dot_lem) 30 | sed -i.bak -f patch_lem.sed t_fs_spec.ml 31 | touch $@ 32 | 33 | # now we are sure lem accepts the files, copy them to plain ml 34 | run_cp: run_lem 35 | for f in t_*.ml; do cp $$f $${f/t_/}; sed -i.bak -f patch_gen_ml.sed $${f/t_/}; done 36 | touch $@ 37 | 38 | # now we have various stages of ocaml compilation 39 | 40 | stage1: run_cp 41 | touch $@ 42 | 43 | include .depend 44 | %.x: %.mli %.ml stage1 45 | $$ocamlc -c $*.mli $*.ml 46 | $$ocamlopt -c $*.mli $*.ml 47 | touch $@ 48 | 49 | %.x: %.ml stage1 50 | $$ocamlc -c $*.ml 51 | $$ocamlopt -c $*.ml 52 | touch $@ 53 | 54 | fs_spec_lib.cma: $(xs) 55 | $$mk_cma -g -a -o $@ $(xs:.x=.cmo) 56 | 57 | fs_spec_lib.cmxa: $(xs) 58 | $$mk_cmxa -g -a -o $@ $(xs:.x=.cmx) 59 | 60 | clean_ocaml: FORCE 61 | rm -f *.cmi *.cmo *.cmx *.o *.x *.cma *.cmxa *.a a.out 62 | 63 | clean: FORCE 64 | if [ `basename $(CURDIR)` = "src" ]; then false; fi # fail if in src! 65 | -rm -rf $$(comm -13 <(cd ../src && ls -1 | sort) <(ls -1 |sort) ) # comm may not exist on all systems 66 | 67 | .SUFFIXES: 68 | -------------------------------------------------------------------------------- /fs_test/adhoc_tests/adhoc_open_test: -------------------------------------------------------------------------------- 1 | # test for open with more than one file access mode 2 | # 3 | mkdir /tmp_dir_0/ 0 4 | mkdir /tmp_dir_0/empty_dir 0 5 | mkdir /tmp_dir_0/nonempty_dir 0 6 | open_close /tmp_dir_0/nonempty_dir/f1.txt [O_RDWR;O_CREAT] 0 7 | open_close /tmp_dir_0/nonempty_dir/f2.txt [O_RDWR;O_CREAT] 0 8 | pwrite /tmp_dir_0/nonempty_dir/f2.txt 0 "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit an" 875 9 | open /tmp_dir_0/nonempty_dir/f1.txt [O_RDWR;O_WRONLY] 0 10 | # 11 | # test open with create flag but no mode argument 12 | open /tmp_dir_0/nonempty_dir/f3.txt [O_RDWR;O_CREAT] 13 | # stat /tmp_dir_0/nonempty_dir/f3.txt 14 | # 15 | # on ext4 under linux we get e.g. 16 | # 17 | # $ ls -al /tmp/tmp2/tmp_dir_0/nonempty_dir/f3.txt 18 | # ---x------ 1 tr61 tr61 0 Apr 7 16:05 /tmp/tmp2/tmp_dir_0/nonempty_dir/f3.txt 19 | # 20 | # ie the file is executable, but that is all 21 | close (FD 4) 22 | # 23 | # the following causes an error in posix; persumably the permission error can't be mapped for some reason 24 | #open /tmp_dir_0/nonempty_dir/f3.txt [O_RDWR;O_CREAT] 25 | -------------------------------------------------------------------------------- /fs_test/lib/fs_test_util.mli: -------------------------------------------------------------------------------- 1 | (****************************************************************************) 2 | (* Copyright (c) 2013, 2014, 2015, Tom Ridge, David Sheets, Thomas Tuerk, *) 3 | (* Andrea Giugliano (as part of the SibylFS project) *) 4 | (* *) 5 | (* Permission to use, copy, modify, and/or distribute this software for *) 6 | (* any purpose with or without fee is hereby granted, provided that the *) 7 | (* above copyright notice and this permission notice appear in all *) 8 | (* copies. *) 9 | (* *) 10 | (* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL *) 11 | (* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED *) 12 | (* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE *) 13 | (* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL *) 14 | (* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR *) 15 | (* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER *) 16 | (* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR *) 17 | (* PERFORMANCE OF THIS SOFTWARE. *) 18 | (* *) 19 | (* Meta: *) 20 | (* - Headers maintained using headache. *) 21 | (* - License source: http://opensource.org/licenses/ISC *) 22 | (****************************************************************************) 23 | 24 | val split : string list -> string -> char -> string list 25 | -------------------------------------------------------------------------------- /fs_test/lib/checkLib_with_posix.ml: -------------------------------------------------------------------------------- 1 | (****************************************************************************) 2 | (* Copyright (c) 2013, 2014, 2015, Tom Ridge, David Sheets, Thomas Tuerk, *) 3 | (* Andrea Giugliano (as part of the SibylFS project) *) 4 | (* *) 5 | (* Permission to use, copy, modify, and/or distribute this software for *) 6 | (* any purpose with or without fee is hereby granted, provided that the *) 7 | (* above copyright notice and this permission notice appear in all *) 8 | (* copies. *) 9 | (* *) 10 | (* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL *) 11 | (* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED *) 12 | (* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE *) 13 | (* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL *) 14 | (* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR *) 15 | (* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER *) 16 | (* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR *) 17 | (* PERFORMANCE OF THIS SOFTWARE. *) 18 | (* *) 19 | (* Meta: *) 20 | (* - Headers maintained using headache. *) 21 | (* - License source: http://opensource.org/licenses/ISC *) 22 | (****************************************************************************) 23 | 24 | module Check_posix = CheckLib.Check(Posix_ops.Posix_ops) 25 | -------------------------------------------------------------------------------- /fs_test/lib/checkLib_with_posix.mli: -------------------------------------------------------------------------------- 1 | (****************************************************************************) 2 | (* Copyright (c) 2013, 2014, 2015, Tom Ridge, David Sheets, Thomas Tuerk, *) 3 | (* Andrea Giugliano (as part of the SibylFS project) *) 4 | (* *) 5 | (* Permission to use, copy, modify, and/or distribute this software for *) 6 | (* any purpose with or without fee is hereby granted, provided that the *) 7 | (* above copyright notice and this permission notice appear in all *) 8 | (* copies. *) 9 | (* *) 10 | (* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL *) 11 | (* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED *) 12 | (* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE *) 13 | (* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL *) 14 | (* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR *) 15 | (* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER *) 16 | (* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR *) 17 | (* PERFORMANCE OF THIS SOFTWARE. *) 18 | (* *) 19 | (* Meta: *) 20 | (* - Headers maintained using headache. *) 21 | (* - License source: http://opensource.org/licenses/ISC *) 22 | (****************************************************************************) 23 | 24 | module Check_posix: CheckLib.Check_result with type m_os_state = Posix_ops.posix_os_state 25 | -------------------------------------------------------------------------------- /fs_spec/src/fs_interface.ml: -------------------------------------------------------------------------------- 1 | (****************************************************************************) 2 | (* Copyright (c) 2013, 2014, 2015, Tom Ridge, David Sheets, Thomas Tuerk, *) 3 | (* Andrea Giugliano (as part of the SibylFS project) *) 4 | (* *) 5 | (* Permission to use, copy, modify, and/or distribute this software for *) 6 | (* any purpose with or without fee is hereby granted, provided that the *) 7 | (* above copyright notice and this permission notice appear in all *) 8 | (* copies. *) 9 | (* *) 10 | (* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL *) 11 | (* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED *) 12 | (* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE *) 13 | (* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL *) 14 | (* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR *) 15 | (* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER *) 16 | (* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR *) 17 | (* PERFORMANCE OF THIS SOFTWARE. *) 18 | (* *) 19 | (* Meta: *) 20 | (* - Headers maintained using headache. *) 21 | (* - License source: http://opensource.org/licenses/ISC *) 22 | (****************************************************************************) 23 | 24 | module Fs_spec_intf = Fs_spec 25 | 26 | module Dir_heap_intf = Dir_heap 27 | 28 | module Fs_dump_intf = Fs_dump 29 | 30 | module Fs_printer_intf = Fs_printer 31 | 32 | -------------------------------------------------------------------------------- /fs_test/lib/fs_path.mli: -------------------------------------------------------------------------------- 1 | (****************************************************************************) 2 | (* Copyright (c) 2013, 2014, 2015, Tom Ridge, David Sheets, Thomas Tuerk, *) 3 | (* Andrea Giugliano (as part of the SibylFS project) *) 4 | (* *) 5 | (* Permission to use, copy, modify, and/or distribute this software for *) 6 | (* any purpose with or without fee is hereby granted, provided that the *) 7 | (* above copyright notice and this permission notice appear in all *) 8 | (* copies. *) 9 | (* *) 10 | (* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL *) 11 | (* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED *) 12 | (* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE *) 13 | (* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL *) 14 | (* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR *) 15 | (* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER *) 16 | (* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR *) 17 | (* PERFORMANCE OF THIS SOFTWARE. *) 18 | (* *) 19 | (* Meta: *) 20 | (* - Headers maintained using headache. *) 21 | (* - License source: http://opensource.org/licenses/ISC *) 22 | (****************************************************************************) 23 | 24 | type t = string list 25 | 26 | val of_string : string -> t 27 | val to_string : t -> string 28 | val concat : string list -> string list -> string list 29 | 30 | val resolve : string list -> string list 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *Theory.* 2 | *.a 3 | *.o 4 | *.cmo 5 | *.cmi 6 | *.cmx 7 | *.cmt 8 | *.cmti 9 | *.cma 10 | *.cmxa 11 | a.out 12 | *.so 13 | *.native 14 | *.byte 15 | _build 16 | # posix-fs-spec-opam-repo ? needed? 17 | doc/www/_book/ 18 | fs_spec/build/posix 19 | fs_spec/build/tr 20 | src_ext/lem 21 | 22 | # fs_spec/build artefacts 23 | fs_spec/build/Lem_support.thy 24 | fs_spec/build/README 25 | fs_spec/build/T_fs_spec.patch 26 | fs_spec/build/abstract_string.ml 27 | fs_spec/build/abstract_string.mli 28 | fs_spec/build/dir_heap.ml 29 | fs_spec/build/fs_dict_wrappers.ml 30 | fs_spec/build/fs_dict_wrappers.mli 31 | fs_spec/build/fs_dump.ml 32 | fs_spec/build/fs_interface.ml 33 | fs_spec/build/fs_interface.mli 34 | fs_spec/build/fs_prelude.ml 35 | fs_spec/build/fs_prelude.mli 36 | fs_spec/build/fs_printer.ml 37 | fs_spec/build/fs_spec.ml 38 | fs_spec/build/fs_spec_fs_command_properties.ml 39 | fs_spec/build/fs_spec_properties.ml 40 | fs_spec/build/fs_spec_properties_perms.ml 41 | fs_spec/build/generated_lem 42 | fs_spec/build/generated_ml 43 | fs_spec/build/generated_tml 44 | fs_spec/build/lem_support.ml 45 | fs_spec/build/lem_support.mli 46 | fs_spec/build/link 47 | fs_spec/build/list_array.ml 48 | fs_spec/build/list_array.mli 49 | 50 | fs_spec/build/run_lem 51 | fs_spec/build/t_dir_heap.lem 52 | fs_spec/build/t_dir_heap.lem_cppo 53 | fs_spec/build/t_dir_heap.ml 54 | fs_spec/build/t_fs_prelude.lem 55 | fs_spec/build/t_fs_prelude.ml 56 | fs_spec/build/t_fs_spec.lem 57 | fs_spec/build/t_fs_spec.lem_cppo 58 | fs_spec/build/t_fs_spec.ml 59 | fs_spec/build/t_fs_specScript.patch 60 | fs_spec/build/t_fs_spec_fs_command_properties.lem 61 | fs_spec/build/t_fs_spec_fs_command_properties.lem_cppo 62 | fs_spec/build/t_fs_spec_fs_command_properties.ml 63 | fs_spec/build/t_fs_spec_properties.lem 64 | fs_spec/build/t_fs_spec_properties.ml 65 | fs_spec/build/t_fs_spec_properties_perms.lem 66 | fs_spec/build/t_fs_spec_properties_perms.lem_cppo 67 | fs_spec/build/t_fs_spec_properties_perms.ml 68 | fs_spec/build/t_list_array.lem 69 | fs_spec/build/t_list_array.ml 70 | fs_spec/build/t_list_arrayAuxiliary.ml 71 | -------------------------------------------------------------------------------- /fs_spec/src/Lem_support.thy: -------------------------------------------------------------------------------- 1 | theory "Lem_support" 2 | 3 | imports 4 | Main 5 | begin 6 | 7 | subsection {* Finite sets *} 8 | 9 | typedef 'a finset = "{s::'a set. finite s}" 10 | morphisms set_from_finset finset_from_set 11 | proof 12 | show "{} \ {s. finite s}" by simp 13 | qed 14 | 15 | declare set_from_finset_inverse[simp] 16 | lemmas finset_from_set_inverse[simp] = finset_from_set_inverse[simplified] 17 | 18 | definition list_from_finset :: "'a finset \ 'a list" where 19 | "list_from_finset fs = (SOME l. (set l = set_from_finset fs))" 20 | 21 | lemma finite_set_from_finset [simp] : 22 | "finite (set_from_finset fs)" 23 | using set_from_finset[of fs] by simp 24 | 25 | lemma set_list_from_finset [simp] : 26 | "set (list_from_finset fs) = set_from_finset fs" 27 | proof - 28 | have "finite (set_from_finset fs)" 29 | by simp 30 | hence "\l. set l = set_from_finset fs" 31 | by (rule finite_list) 32 | thus ?thesis 33 | unfolding list_from_finset_def 34 | by (rule someI_ex) 35 | qed 36 | 37 | 38 | definition finset_from_list :: "'a list \ 'a finset" where 39 | "finset_from_list l = finset_from_set (set l)" 40 | 41 | lemma finset_from_list_inv [simp] : 42 | "finset_from_list (list_from_finset fs) = fs" 43 | unfolding finset_from_list_def 44 | by simp 45 | 46 | lemma set_from_finset_from_list [simp]: 47 | "set_from_finset (finset_from_list l) = set l" 48 | unfolding finset_from_list_def by simp 49 | 50 | lemmas finset_from_set_inject [simp] = finset_from_set_inject[simplified] 51 | 52 | lemma list_from_finset_eq_nil[simp]: 53 | "(list_from_finset fs = []) = (fs = finset_from_set {})" 54 | unfolding list_from_finset_def 55 | proof (rule someI2_ex) 56 | show "\a. set a = set_from_finset fs" 57 | by (rule finite_list) simp 58 | next 59 | fix s 60 | assume set_s_eq: "set s = set_from_finset fs" 61 | 62 | show "(s = []) = (fs = finset_from_set {})" 63 | using set_s_eq 64 | by (metis set_empty2 set_from_finset_from_list set_from_finset_inverse) 65 | qed 66 | 67 | 68 | end 69 | -------------------------------------------------------------------------------- /fs_spec/src/tr/5: -------------------------------------------------------------------------------- 1 | rename /tmp_dir_252/d1/nonempty_dir1/f1.txt /tmp_dir_252/d1/empty_dir1/ 2 | [ENOTDIR] 3 | 4 | posix says http://pubs.opengroup.org/onlinepubs/9699919799/ (and none of the conditions apply) 5 | 6 | [ENOTDIR] 7 | [CX] A component of either path prefix names an existing file that is neither a directory nor a symbolic link to a directory; or the old argument names a directory and the new argument names a non-directory file; or the old argument contains at least one non- character and ends with one or more trailing characters and the last pathname component names an existing file that is neither a directory nor a symbolic link to a directory; or the old argument names an existing non-directory file and the new argument names a nonexistent file, contains at least one non- character, and ends with one or more trailing characters; or the new argument names an existing non-directory file, contains at least one non- character, and ends with one or more trailing characters. 8 | 9 | 10 | [ENOTDIR] [CX] A component of either path prefix names an existing 11 | file that is neither a directory nor a symbolic link to a directory; 12 | 13 | NA 14 | 15 | or the old argument names a directory and the new argument names a 16 | non-directory file; 17 | 18 | NA 19 | 20 | or the old argument contains at least one non- 21 | character and ends with one or more trailing 22 | characters and the last pathname component names an existing file that 23 | is neither a directory nor a symbolic link to a directory; 24 | 25 | NA 26 | 27 | or the old 28 | argument names an existing non-directory file and the new argument 29 | names a nonexistent file, contains at least one non- 30 | character, and ends with one or more trailing characters; 31 | 32 | NA 33 | 34 | or 35 | the new argument names an existing non-directory file, contains at 36 | least one non- character, and ends with one or more trailing 37 | characters. 38 | 39 | NA -------------------------------------------------------------------------------- /fs_test/lib/fs_test_util.ml: -------------------------------------------------------------------------------- 1 | (****************************************************************************) 2 | (* Copyright (c) 2013, 2014, 2015, Tom Ridge, David Sheets, Thomas Tuerk, *) 3 | (* Andrea Giugliano (as part of the SibylFS project) *) 4 | (* *) 5 | (* Permission to use, copy, modify, and/or distribute this software for *) 6 | (* any purpose with or without fee is hereby granted, provided that the *) 7 | (* above copyright notice and this permission notice appear in all *) 8 | (* copies. *) 9 | (* *) 10 | (* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL *) 11 | (* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED *) 12 | (* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE *) 13 | (* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL *) 14 | (* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR *) 15 | (* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER *) 16 | (* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR *) 17 | (* PERFORMANCE OF THIS SOFTWARE. *) 18 | (* *) 19 | (* Meta: *) 20 | (* - Headers maintained using headache. *) 21 | (* - License source: http://opensource.org/licenses/ISC *) 22 | (****************************************************************************) 23 | 24 | let rec split acc str char = 25 | try 26 | let spc = String.index str char in 27 | let next = String.sub str 0 spc in 28 | let str = String.sub str (spc+1) ((String.length str) - spc - 1) in 29 | split (next::acc) str char 30 | with Not_found -> List.rev (str::acc) 31 | -------------------------------------------------------------------------------- /fs_test/adhoc_tests/adhoc_open_test.interp_result: -------------------------------------------------------------------------------- 1 | # test for open with more than one file access mode 2 | # 3 | OS_CALL(Pid 1,mkdir /tmp_dir_0/ 0o000) 4 | None1 5 | OS_CALL(Pid 1,mkdir /tmp_dir_0/empty_dir 0o000) 6 | None1 7 | OS_CALL(Pid 1,mkdir /tmp_dir_0/nonempty_dir 0o000) 8 | None1 9 | OS_CALL(Pid 1,open_close /tmp_dir_0/nonempty_dir/f1.txt [O_RDWR;O_CREAT] 0o000) 10 | None1 11 | OS_CALL(Pid 1,open_close /tmp_dir_0/nonempty_dir/f2.txt [O_RDWR;O_CREAT] 0o000) 12 | None1 13 | OS_CALL(Pid 1,pwrite /tmp_dir_0/nonempty_dir/f2.txt 0 "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit an" 875) 14 | Int1(875) 15 | OS_CALL(Pid 1,open /tmp_dir_0/nonempty_dir/f1.txt [O_RDWR;O_WRONLY] 0o000) 16 | Int1(3) 17 | # 18 | # test open with create flag but no mode argument 19 | OS_CALL(Pid 1,open /tmp_dir_0/nonempty_dir/f3.txt [O_RDWR;O_CREAT]) 20 | Int1(4) 21 | # stat /tmp_dir_0/nonempty_dir/f3.txt 22 | # 23 | # on ext4 under linux we get e.g. 24 | # 25 | # $ ls -al /tmp/tmp2/tmp_dir_0/nonempty_dir/f3.txt 26 | # ---x------ 1 tr61 tr61 0 Apr 7 16:05 /tmp/tmp2/tmp_dir_0/nonempty_dir/f3.txt 27 | # 28 | # ie the file is executable, but that is all 29 | OS_CALL(Pid 1,close (FD 4)) 30 | None1 31 | # 32 | # the following causes an error in posix; persumably the permission error can't be mapped for some reason 33 | #open /tmp_dir_0/nonempty_dir/f3.txt [O_RDWR;O_CREAT] 34 | -------------------------------------------------------------------------------- /fs_test/adhoc_tests/adhoc_open_test.posix_result: -------------------------------------------------------------------------------- 1 | # test for open with more than one file access mode 2 | # 3 | OS_CALL(Pid 1,mkdir /tmp_dir_0/ 0o000) 4 | None1 5 | OS_CALL(Pid 1,mkdir /tmp_dir_0/empty_dir 0o000) 6 | None1 7 | OS_CALL(Pid 1,mkdir /tmp_dir_0/nonempty_dir 0o000) 8 | None1 9 | OS_CALL(Pid 1,open_close /tmp_dir_0/nonempty_dir/f1.txt [O_RDWR;O_CREAT] 0o000) 10 | None1 11 | OS_CALL(Pid 1,open_close /tmp_dir_0/nonempty_dir/f2.txt [O_RDWR;O_CREAT] 0o000) 12 | None1 13 | OS_CALL(Pid 1,pwrite /tmp_dir_0/nonempty_dir/f2.txt 0 "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit an" 875) 14 | Int1(875) 15 | OS_CALL(Pid 1,open /tmp_dir_0/nonempty_dir/f1.txt [O_RDWR;O_WRONLY] 0o000) 16 | Int1(3) 17 | # 18 | # test open with create flag but no mode argument 19 | OS_CALL(Pid 1,open /tmp_dir_0/nonempty_dir/f3.txt [O_RDWR;O_CREAT]) 20 | Int1(4) 21 | # stat /tmp_dir_0/nonempty_dir/f3.txt 22 | # 23 | # on ext4 under linux we get e.g. 24 | # 25 | # $ ls -al /tmp/tmp2/tmp_dir_0/nonempty_dir/f3.txt 26 | # ---x------ 1 tr61 tr61 0 Apr 7 16:05 /tmp/tmp2/tmp_dir_0/nonempty_dir/f3.txt 27 | # 28 | # ie the file is executable, but that is all 29 | OS_CALL(Pid 1,close (FD 4)) 30 | None1 31 | # 32 | # the following causes an error in posix; persumably the permission error can't be mapped for some reason 33 | #open /tmp_dir_0/nonempty_dir/f3.txt [O_RDWR;O_CREAT] 34 | -------------------------------------------------------------------------------- /fs_test/ld_preload/mycommand.ml: -------------------------------------------------------------------------------- 1 | (****************************************************************************) 2 | (* Copyright (c) 2013, 2014, 2015, Tom Ridge, David Sheets, Thomas Tuerk, *) 3 | (* Andrea Giugliano (as part of the SibylFS project) *) 4 | (* *) 5 | (* Permission to use, copy, modify, and/or distribute this software for *) 6 | (* any purpose with or without fee is hereby granted, provided that the *) 7 | (* above copyright notice and this permission notice appear in all *) 8 | (* copies. *) 9 | (* *) 10 | (* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL *) 11 | (* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED *) 12 | (* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE *) 13 | (* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL *) 14 | (* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR *) 15 | (* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER *) 16 | (* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR *) 17 | (* PERFORMANCE OF THIS SOFTWARE. *) 18 | (* *) 19 | (* Meta: *) 20 | (* - Headers maintained using headache. *) 21 | (* - License source: http://opensource.org/licenses/ISC *) 22 | (****************************************************************************) 23 | 24 | print_endline "Hello from mycommand" 25 | 26 | let cwd = Sys.getcwd() 27 | 28 | let args = Array.to_list Sys.argv 29 | 30 | let main () = ( 31 | print_endline ("cwd is: "^cwd); 32 | print_endline ("args are: "); 33 | ignore(List.map print_endline args)) 34 | 35 | let _ = main () 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /fs_test/Makefile: -------------------------------------------------------------------------------- 1 | SHELL:=/bin/bash 2 | 3 | # bash will read this config file first 4 | BASH_ENV=bash_env.sh 5 | export BASH_ENV 6 | 7 | NATIVES:=debug/check2.native debug/debug.native paths/testpath.native fs_test_check fs_test_posix fs_test run_trace test_generation/tgen 8 | 9 | ######################################## target: all 10 | all: include # do this first 11 | $(MAKE) lib/fs_check_lib.cmxa $(NATIVES) 12 | $(MAKE) -C ld_preload 13 | 14 | ######################################## include - copy the .cm... files from fs_spec, and cmis from lem 15 | 16 | # no dep tracking: if anything changes in fs_spec you have to make clean 17 | include: 18 | mkdir -p include 19 | cp $$from_lem $$from_spec include 20 | chmod u+w include/* # in case we need to overwrite, and they are readonly from nix 21 | touch include 22 | 23 | ######################################## lib/fs_check_lib.cmxa 24 | 25 | lib/fs_check_lib.cmxa: 26 | $(MAKE) -C lib 27 | 28 | ######################################## targets depending on fs_check_lib.cmxa 29 | 30 | # FIXME could be tidier if we used consistent naming 31 | 32 | debug/check2.native debug/debug.native: lib/fs_check_lib.cmxa 33 | $(MAKE) -C debug/ 34 | 35 | paths/testpath.native: %.native: %.ml lib/fs_check_lib.cmxa 36 | $$mk_native -linkpkg -o $@ $< 37 | 38 | %: %.ml lib/fs_check_lib.cmxa 39 | $$mk_native -linkpkg -o $@ $< 40 | 41 | fs_test_check fs_test_posix: fs_test_%: %.ml lib/fs_check_lib.cmxa 42 | $$mk_native -linkpkg -o $@ $< 43 | 44 | 45 | ######################################## clean 46 | clean_natives: 47 | rm -f $(NATIVES) 48 | 49 | clean_not_lib: 50 | rm -f $(NATIVES) 51 | rm -rf include 52 | -$(MAKE) -C debug clean 53 | -$(MAKE) -C ld_preload clean 54 | rm -f paths/testpath.cmi paths/testpath.cmx paths/testpath.o paths/testpath.native 55 | rm -f *.cmi *.cmx *.cmo *.o 56 | rm -f test_generation/*.cmi test_generation/*.cmx test_generation/*.cmo test_generation/*.o 57 | rm -f ./result 58 | 59 | clean: clean_not_lib 60 | -$(MAKE) -C lib clean 61 | 62 | FORCE: 63 | 64 | 65 | -include Makefile.local 66 | 67 | # Local variables: 68 | # mode: outline-minor 69 | # outline-regexp: "[#][#]+ .*" 70 | # End: 71 | -------------------------------------------------------------------------------- /fs_spec/src/tr/7: -------------------------------------------------------------------------------- 1 | rename /tmp_dir_25/ /tmp_dir_25/d1/nonempty_dir1/f1.txt/ 2 | [EINVAL] 3 | 4 | posix says: 5 | 6 | [EINVAL] 7 | [CX] [Option Start] The old pathname names an ancestor directory of the new pathname, or either pathname argument contains a final component that is dot or dot-dot. [Option End] 8 | 9 | 10 | NB this behaviour seems unreasonable because .../f1.txt/ doesn't 11 | exist, and so doesn't have a canonical path, so we can't really check 12 | subdir relationship. 13 | 14 | Presumably the Linux implementation starts working down the path 15 | /tmp_dir_25/d1/nonempty_dir1/f1.txt/ and stops after /tmp_dir_25/d1 16 | because it knows that the target, *if it resolves*, will be a subdir 17 | of the source (except that the path may contain .. entries, so it 18 | eventually doesn't resolve to a subdir). So this short-cuts proper 19 | evaluation of the path. This suggests that good tests would be 20 | 21 | rename /tmp_dir_25/ /tmp_dir_25/d1/nonempty_dir1/f1.txt/../../../.. (which maybe looks like a rename of tmp_dir_25 onto itself, which might succeed, but which should fail with ENOTDIR) 22 | 23 | rename /tmp_dir_25/ /tmp_dir_25/d1/.. (which maybe looks like a rename of root onto root, which should succeed) 24 | 25 | rename /tmp_dir_25/ /tmp_dir_25/d1/nonempty_dir1/f1.txt/nonexist_file 26 | 27 | 28 | -- 29 | 30 | However, elsewhere (base_definitions/ch_4_general_concepts path 31 | resolution) posix says that if attempting to move a directory, and the 32 | last component is to be created, then the last component is not 33 | resolved. So in this case the error returned would be OK, since f1.txt/ 34 | isn't actually looked at. 35 | 36 | 37 | -- 38 | 39 | ../posix/rename ENOTDIR:5 seems to capture this case pretty clearly: 40 | 41 | ENOTDIR:5 or 42 | the new argument names an existing non-directory file, contains at 43 | least one non- character, and ends with one or more trailing 44 | characters. 45 | 46 | -- 47 | 48 | but problem is to rule out EINVAL, rather than rule in ENOTDIR 49 | 50 | -- 51 | 52 | summary: not completely clear if posix/rename EINVAL:1 applies; ENOTDIR:5 certainly does apply but that is not enough to rule out EINVAL -------------------------------------------------------------------------------- /fs_test/lib/diff.mli: -------------------------------------------------------------------------------- 1 | (****************************************************************************) 2 | (* Copyright (c) 2013, 2014, 2015, Tom Ridge, David Sheets, Thomas Tuerk, *) 3 | (* Andrea Giugliano (as part of the SibylFS project) *) 4 | (* *) 5 | (* Permission to use, copy, modify, and/or distribute this software for *) 6 | (* any purpose with or without fee is hereby granted, provided that the *) 7 | (* above copyright notice and this permission notice appear in all *) 8 | (* copies. *) 9 | (* *) 10 | (* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL *) 11 | (* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED *) 12 | (* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE *) 13 | (* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL *) 14 | (* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR *) 15 | (* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER *) 16 | (* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR *) 17 | (* PERFORMANCE OF THIS SOFTWARE. *) 18 | (* *) 19 | (* Meta: *) 20 | (* - Headers maintained using headache. *) 21 | (* - License source: http://opensource.org/licenses/ISC *) 22 | (****************************************************************************) 23 | 24 | open Sexplib.Std 25 | 26 | type 'a diff = ('a * 'a) option with sexp 27 | 28 | val diff : 'a -> 'a -> 'a diff 29 | 30 | val inter_diff_map : 31 | ('a -> 'b) * ('a * 'a -> 'c) * ('a -> 'd) -> 32 | ('a -> 'a -> int) -> 'a list -> 'a list -> 'b list * 'c list * 'd list 33 | 34 | val inter_diff : 35 | ('a -> 'a -> int) -> 36 | 'a list -> 'a list -> 'a list * ('a * 'a) list * 'a list 37 | -------------------------------------------------------------------------------- /fs_spec/src/abstract_string.mli: -------------------------------------------------------------------------------- 1 | (****************************************************************************) 2 | (* Copyright (c) 2013, 2014, 2015, Tom Ridge, David Sheets, Thomas Tuerk, *) 3 | (* Andrea Giugliano (as part of the SibylFS project) *) 4 | (* *) 5 | (* Permission to use, copy, modify, and/or distribute this software for *) 6 | (* any purpose with or without fee is hereby granted, provided that the *) 7 | (* above copyright notice and this permission notice appear in all *) 8 | (* copies. *) 9 | (* *) 10 | (* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL *) 11 | (* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED *) 12 | (* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE *) 13 | (* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL *) 14 | (* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR *) 15 | (* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER *) 16 | (* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR *) 17 | (* PERFORMANCE OF THIS SOFTWARE. *) 18 | (* *) 19 | (* Meta: *) 20 | (* - Headers maintained using headache. *) 21 | (* - License source: http://opensource.org/licenses/ISC *) 22 | (****************************************************************************) 23 | 24 | (* Abstract_string is a type isomorphic to string; we want to retain 25 | the possibility of substituting a possibly-more-efficient type in 26 | generated OCaml. *) 27 | 28 | type t with sexp 29 | 30 | val to_list : t -> char list 31 | 32 | val of_list : char list -> t 33 | 34 | val of_string : string -> t 35 | 36 | val to_string : t -> string 37 | 38 | val dim : t -> int 39 | 40 | val resize : t -> int -> t 41 | 42 | val equal : t -> t -> bool 43 | -------------------------------------------------------------------------------- /fs_spec/src/list_array.mli: -------------------------------------------------------------------------------- 1 | (****************************************************************************) 2 | (* Copyright (c) 2013, 2014, 2015, Tom Ridge, David Sheets, Thomas Tuerk, *) 3 | (* Andrea Giugliano (as part of the SibylFS project) *) 4 | (* *) 5 | (* Permission to use, copy, modify, and/or distribute this software for *) 6 | (* any purpose with or without fee is hereby granted, provided that the *) 7 | (* above copyright notice and this permission notice appear in all *) 8 | (* copies. *) 9 | (* *) 10 | (* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL *) 11 | (* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED *) 12 | (* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE *) 13 | (* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL *) 14 | (* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR *) 15 | (* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER *) 16 | (* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR *) 17 | (* PERFORMANCE OF THIS SOFTWARE. *) 18 | (* *) 19 | (* Meta: *) 20 | (* - Headers maintained using headache. *) 21 | (* - License source: http://opensource.org/licenses/ISC *) 22 | (****************************************************************************) 23 | 24 | val to_list : Abstract_string.t -> char list 25 | 26 | val of_string : string -> Abstract_string.t 27 | val to_string : Abstract_string.t -> string 28 | val dim : Abstract_string.t -> int 29 | (* val char_list_sub : 'a list -> Nat_num.nat -> Nat_num.nat -> 'a list *) 30 | val sub : Abstract_string.t -> int -> int -> Abstract_string.t 31 | (* val char_list_resize : char list -> Nat_num.nat -> char list *) 32 | val resize : Abstract_string.t -> int -> Abstract_string.t 33 | val list_array_write : Abstract_string.t * int * int -> Abstract_string.t * int -> Abstract_string.t 34 | -------------------------------------------------------------------------------- /fs_spec/src/fs_dict_wrappers.mli: -------------------------------------------------------------------------------- 1 | (****************************************************************************) 2 | (* Copyright (c) 2013, 2014, 2015, Tom Ridge, David Sheets, Thomas Tuerk, *) 3 | (* Andrea Giugliano (as part of the SibylFS project) *) 4 | (* *) 5 | (* Permission to use, copy, modify, and/or distribute this software for *) 6 | (* any purpose with or without fee is hereby granted, provided that the *) 7 | (* above copyright notice and this permission notice appear in all *) 8 | (* copies. *) 9 | (* *) 10 | (* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL *) 11 | (* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED *) 12 | (* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE *) 13 | (* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL *) 14 | (* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR *) 15 | (* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER *) 16 | (* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR *) 17 | (* PERFORMANCE OF THIS SOFTWARE. *) 18 | (* *) 19 | (* Meta: *) 20 | (* - Headers maintained using headache. *) 21 | (* - License source: http://opensource.org/licenses/ISC *) 22 | (****************************************************************************) 23 | 24 | module Fmap_default : 25 | sig 26 | val fmap_remove : 27 | ('a, 'b) Fs_prelude.fmap -> 'a -> ('a, 'b) Fs_prelude.fmap 28 | val fmap_update : 29 | ('a, 'b) Fs_prelude.fmap -> 'a * 'b -> ('a, 'b) Fs_prelude.fmap 30 | val fmap_update_option : 31 | ('a, 'b) Fs_prelude.fmap -> 'a * 'b option -> ('a, 'b) Fs_prelude.fmap 32 | val fmap_from_list : ('a * 'b) list -> ('a, 'b) Fs_prelude.fmap 33 | val fmap_lookup : ('a, 'b) Fs_prelude.fmap -> 'a -> 'b option 34 | val fmap_empty : unit -> ('a, 'b) Fs_prelude.fmap 35 | val fmap_dom : ('a, 'b) Fs_prelude.fmap -> 'a Lem_support.finset 36 | end 37 | -------------------------------------------------------------------------------- /fs_test/README.md: -------------------------------------------------------------------------------- 1 | Files: 2 | 3 | * `check.{ml,native}` - take a trace (e.g. derived from posix 4 | command) and check that it is accepted by the specification; os 5 | and fs level; typically used via `fs_test.sh` 6 | 7 | * `default.nix` - build file; type `nix-build` in this directory to 8 | build using nix 9 | 10 | * `fs_test.{ml,native,sh}` - run collections of test suites against 11 | various filesystems; `fs_test.sh` is the default entry point 12 | 13 | * `fs_test_version.ml` - version info, typically derived from git 14 | commit, generated by Makefile 15 | 16 | * `Makefile` - build file; type `make` in this directory to build 17 | using make 18 | 19 | * `posix.{ml,native}` - run test commands against the POSIX C library 20 | interface; usually accessed via `fs_test.sh` 21 | 22 | The executable `posix.native` provides direct access to 23 | syscalls. Syscalls can be given on stdin, or processed in batch mode 24 | from a file. See posix.ml for command line options etc. 25 | 26 | Typical usage: ./posix.native -b -r /tmp/unix_impl_test test_commands 27 | 28 | * `run_trace.{ml,native}` - FIXME 29 | 30 | * `testall.sh` - after making, try to run some very simple tests; 31 | use this after making changes to the spec to check that things 32 | aren't messed up too badly. 33 | 34 | * `traces.md` - some high level documentation of traces and 35 | how to use them 36 | 37 | 38 | Subdirectories: 39 | 40 | * `adhoc_tests` - adhoc tests that should be run at the same time as 41 | the tests automatically generated by `testgen`. 42 | 43 | [ ] incorporate all test scripts into a "main" test script; rename 44 | directories so that there is no clash with autogenerated test 45 | script 46 | 47 | * `debug` - contains versions of check that produce debugging info, 48 | to analyse failing traces 49 | 50 | * `docker` - instructions for running tests in a docker container 51 | 52 | * `example_traces` - test traces, for checking basic tool 53 | functionality 54 | 55 | * `ld_preload` - some fancy C code for intercepting library calls 56 | and redirecting them 57 | 58 | * `lib` - common test library files 59 | 60 | * `paths` - unit tests for path resolution code, module `Resolve` in 61 | the spec 62 | 63 | * `repro` - reproduce buggy filesystem behaviour, using simple C 64 | code (for upstreaming bug reports) 65 | 66 | * `testgen` - (fairly) exhaustive test generation for each operation 67 | 68 | -------------------------------------------------------------------------------- /fs_test/lib/posix_ops.mli: -------------------------------------------------------------------------------- 1 | (****************************************************************************) 2 | (* Copyright (c) 2013, 2014, 2015, Tom Ridge, David Sheets, Thomas Tuerk, *) 3 | (* Andrea Giugliano (as part of the SibylFS project) *) 4 | (* *) 5 | (* Permission to use, copy, modify, and/or distribute this software for *) 6 | (* any purpose with or without fee is hereby granted, provided that the *) 7 | (* above copyright notice and this permission notice appear in all *) 8 | (* copies. *) 9 | (* *) 10 | (* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL *) 11 | (* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED *) 12 | (* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE *) 13 | (* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL *) 14 | (* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR *) 15 | (* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER *) 16 | (* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR *) 17 | (* PERFORMANCE OF THIS SOFTWARE. *) 18 | (* *) 19 | (* Meta: *) 20 | (* - Headers maintained using headache. *) 21 | (* - License source: http://opensource.org/licenses/ISC *) 22 | (****************************************************************************) 23 | 24 | val reset_global_state : unit -> unit 25 | 26 | val stop_all : unit -> unit 27 | 28 | val rm_recursive : string -> unit 29 | 30 | val run_in_child_process : 31 | (?pids:int list -> int list -> int -> unit) -> 32 | (?status:Unix.process_status -> unit -> unit) -> 33 | (unit -> int) -> unit 34 | 35 | type posix_os_state 36 | 37 | (** The ty_arch argument is used to munge os_label s. The string 38 | argument is the path under which to execute tests *) 39 | val posix_initial_state : 40 | Fs_interface.Fs_spec_intf.Fs_types.ty_arch -> string -> posix_os_state 41 | 42 | module Posix_ops : 43 | (*functor (M : sig val root_dir : string end) ->*) Checklib_shared_types.Os_ops with type os_state = posix_os_state 44 | -------------------------------------------------------------------------------- /fs_test/lib/checklib_shared_types.mli: -------------------------------------------------------------------------------- 1 | (****************************************************************************) 2 | (* Copyright (c) 2013, 2014, 2015, Tom Ridge, David Sheets, Thomas Tuerk, *) 3 | (* Andrea Giugliano (as part of the SibylFS project) *) 4 | (* *) 5 | (* Permission to use, copy, modify, and/or distribute this software for *) 6 | (* any purpose with or without fee is hereby granted, provided that the *) 7 | (* above copyright notice and this permission notice appear in all *) 8 | (* copies. *) 9 | (* *) 10 | (* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL *) 11 | (* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED *) 12 | (* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE *) 13 | (* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL *) 14 | (* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR *) 15 | (* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER *) 16 | (* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR *) 17 | (* PERFORMANCE OF THIS SOFTWARE. *) 18 | (* *) 19 | (* Meta: *) 20 | (* - Headers maintained using headache. *) 21 | (* - License source: http://opensource.org/licenses/ISC *) 22 | (****************************************************************************) 23 | 24 | type 'os_state gen_os_state_or_special = 25 | GOS_normal of 'os_state 26 | | GOS_special of 27 | (Fs_interface.Fs_spec_intf.Fs_types.monad_special_state * string) 28 | module type Os_ops = 29 | sig 30 | type os_state 31 | val os_trans : 32 | os_state -> 33 | Fs_interface.Fs_spec_intf.Fs_types.os_label -> 34 | os_state gen_os_state_or_special Lem_support.finset 35 | val allowed_results_for_pid : 36 | Fs_interface.Fs_spec_intf.Fs_types.ty_pid -> 37 | os_state -> 38 | Fs_interface.Fs_spec_intf.Fs_types.ret_value 39 | Fs_interface.Fs_spec_intf.Fs_types.error_or_value Lem_support.finset 40 | val dump_of_path : os_state -> string -> Dump.t 41 | end 42 | -------------------------------------------------------------------------------- /fs_spec/src/posix/lseek.md: -------------------------------------------------------------------------------- 1 | # NAME 2 | 3 | > lseek - move the read/write file offset 4 | 5 | # SYNOPSIS 6 | 7 | > #include 8 | > off_t lseek(int fildes, off_t offset, int whence); 9 | 10 | # DESCRIPTION 11 | 12 | > The lseek() function shall set the file offset for the open file 13 | > description associated with the file descriptor fildes, as 14 | > follows: 15 | > - If whence is SEEK_SET, the file offset shall be set to offset bytes. 16 | > - If whence is SEEK_CUR, the file offset shall be set to its current location plus offset. 17 | > - If whence is SEEK_END, the file offset shall be set to the size of the file plus offset. 18 | 19 | > The symbolic constants SEEK_SET, SEEK_CUR, and SEEK_END are 20 | > defined in . 21 | 22 | > The behavior of lseek() on devices which are incapable of 23 | > seeking is implementation-defined. The value of the file offset 24 | > associated with such a device is undefined. 25 | 26 | > The lseek() function shall allow the file offset to be set 27 | > beyond the end of the existing data in the file. If data is 28 | > later written at this point, subsequent reads of data in the gap 29 | > shall return bytes with the value 0 until data is actually 30 | > written into the gap. 31 | 32 | > The lseek() function shall not, by itself, extend the size of a 33 | > file. 34 | 35 | > If fildes refers to a shared memory object, the result of the lseek() function is unspecified. 36 | > If fildes refers to a typed memory object, the result of the lseek() function is unspecified. 37 | 38 | # RETURN VALUE 39 | 40 | > Upon successful completion, the resulting offset, as measured in 41 | > bytes from the beginning of the file, shall be 42 | > returned. Otherwise, -1 shall be returned, errno shall be set to 43 | > indicate the error, and the file offset shall remain unchanged. 44 | 45 | # ERRORS 46 | 47 | > The lseek() function shall fail if: 48 | 49 | > [EBADF] 50 | > The fildes argument is not an open file descriptor. 51 | 52 | EBADF:1 53 | 54 | > [EINVAL] 55 | > The whence argument is not a proper value, 56 | 57 | EINVAL:1 58 | 59 | > or the resulting file offset would be negative for a regular 60 | > file, block special file, or directory. 61 | 62 | EINVAL:2 63 | 64 | 65 | > [EOVERFLOW] 66 | > The resulting file offset would be a value which cannot be represented correctly in an object of type off_t. 67 | > [ESPIPE] 68 | > The fildes argument is associated with a pipe, FIFO, or socket. -------------------------------------------------------------------------------- /fs_test/example_traces/resolve_test-fs.trace: -------------------------------------------------------------------------------- 1 | # create a directory without any permissions 2 | mkdir /tmp_dir_1490/ 0o000 3 | Tau 4 | RV_none 5 | 6 | 7 | #we get an error when trying to create a subdirectory 8 | mkdir /tmp_dir_1490/d1 0o700 9 | Tau 10 | EACCES 11 | 12 | 13 | #resolving allows using that dir as an argument to change it's permissions 14 | chmod /tmp_dir_1490/ 0o700 15 | Tau 16 | RV_none 17 | 18 | chown /tmp_dir_1490/ (User_id 0) (Group_id 0) 19 | Tau 20 | RV_none 21 | 22 | 23 | # now we can create the subdirectory 24 | mkdir /tmp_dir_1490/d1 0o700 25 | Tau 26 | RV_none 27 | 28 | mkdir /tmp_dir_1490/d1/empty_dir1 0o700 29 | Tau 30 | RV_none 31 | 32 | 33 | # let's remove the search permission from the top dir 34 | chmod /tmp_dir_1490 0o000 35 | Tau 36 | RV_none 37 | 38 | 39 | # despite the permissions on d1 not changing, we can't create another subdir now 40 | mkdir /tmp_dir_1490/d1/empty_dir2 0o700 41 | Tau 42 | EACCES 43 | 44 | 45 | # with more permissions it works 46 | chmod /tmp_dir_1490 0o100 47 | Tau 48 | RV_none 49 | 50 | mkdir /tmp_dir_1490/d1/empty_dir2 0o700 51 | Tau 52 | RV_none 53 | 54 | 55 | #let's try chdir and relative paths 56 | chdir /tmp_dir_1490/d1/ 57 | Tau 58 | RV_none 59 | 60 | mkdir empty_dir3 0o700 61 | Tau 62 | RV_none 63 | 64 | 65 | chdir .. 66 | Tau 67 | RV_none 68 | 69 | mkdir d1/empty_dir4 0o700 70 | Tau 71 | RV_none 72 | 73 | 74 | # chdir to a non-existing dir 75 | chdir /tmp_dir_1490/non_existing/ 76 | Tau 77 | ENOENT 78 | 79 | 80 | # chdir to a file / notice that cwd did not change in previous call 81 | open_close d1/f1.txt [O_RDWR;O_CREAT] 0o777 82 | Tau 83 | RV_none 84 | 85 | chdir d1/f1.txt 86 | Tau 87 | ENOTDIR 88 | 89 | 90 | # change dir so our working dir always has search permission 91 | # this is required by the implemenentation of the tool posix2 92 | chdir / 93 | Tau 94 | RV_none 95 | 96 | 97 | # chdir with missing search permssions 98 | chmod /tmp_dir_1490 0o000 99 | Tau 100 | RV_none 101 | 102 | chdir /tmp_dir_1490/d1/ 103 | Tau 104 | EACCES 105 | 106 | 107 | chdir / 108 | Tau 109 | RV_none 110 | 111 | chmod /tmp_dir_1490 0o100 112 | Tau 113 | RV_none 114 | 115 | chdir /tmp_dir_1490/d1/ 116 | Tau 117 | RV_none 118 | 119 | 120 | chdir / 121 | Tau 122 | RV_none 123 | 124 | chmod /tmp_dir_1490/d1 0o000 125 | Tau 126 | RV_none 127 | 128 | chdir /tmp_dir_1490/d1/ 129 | Tau 130 | EACCES 131 | 132 | 133 | # add sufficient permissions for dump to work with posix2 134 | chmod /tmp_dir_1490/ 0o777 135 | Tau 136 | RV_none 137 | 138 | chmod /tmp_dir_1490/d1 0o777 139 | Tau 140 | RV_none 141 | 142 | dump 143 | -------------------------------------------------------------------------------- /fs_test/adhoc_tests/adhoc_state_explosion-check.trace: -------------------------------------------------------------------------------- 1 | # demonstrating state explosion problem 2 | # create 3 processes and let them all write to a file 3 | # with and without returns in the middle. 4 | 5 | 6 | # initialisation 7 | 8 | create Pid 2 User_id 0 Group_id 0 9 | create Pid 3 User_id 0 Group_id 0 10 | 11 | 12 | # start on empty file and write something 13 | Pid 1 -> open f1.txt [O_RDWR;O_CREAT] 0o666 14 | Tau 15 | Pid 1 <- RV_num(3) 16 | 17 | Pid 2 -> open f1.txt [O_RDWR;O_CREAT] 0o666 18 | Tau 19 | Pid 2 <- RV_num(3) 20 | 21 | Pid 3 -> open f1.txt [O_RDWR;O_CREAT] 0o666 22 | Tau 23 | Pid 3 <- RV_num(3) 24 | 25 | 26 | # with return statements, it is fast 27 | 28 | Pid 1 -> write (FD 3) "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" 100 29 | Tau 30 | Pid 1 <- RV_num(10) 31 | Pid 2 -> write (FD 3) "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" 100 32 | Tau 33 | Pid 2 <- RV_num(15) 34 | Pid 3 -> write (FD 3) "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" 100 35 | Tau 36 | Pid 3 <- RV_num(80) 37 | 38 | 39 | # without return we run into state explosion problems 40 | Pid 1 -> write (FD 3) "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" 100 41 | Tau 42 | Pid 2 -> write (FD 3) "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" 100 43 | Tau 44 | Pid 3 -> write (FD 3) "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" 100 45 | Tau 46 | Pid 1 <- RV_num(10) 47 | Pid 2 <- RV_num(15) 48 | Pid 3 <- RV_num(80) 49 | 50 | 51 | # too loose return statements also lead to state-explosion 52 | Pid 1 -> write (FD 3) "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" 100 53 | Tau 54 | Pid 1 <- {RV_num(0);RV_num(1);RV_num(2);RV_num(3);RV_num(4);RV_num(5);RV_num(6);RV_num(7);RV_num(8);RV_num(9);RV_num(10);RV_num(11);RV_num(12);RV_num(13);RV_num(14);RV_num(15);RV_num(16);RV_num(17);RV_num(18);RV_num(19)} 55 | Pid 2 -> write (FD 3) "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" 100 56 | Tau 57 | Pid 2 <- - 58 | Pid 3 -> write (FD 3) "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" 100 59 | Tau 60 | Pid 3 <- - 61 | 62 | 63 | # cleaning up 64 | Pid 1 -> close (FD 3) 65 | Tau 66 | Pid 1 <- RV_none 67 | 68 | Pid 2 -> close (FD 3) 69 | Tau 70 | Pid 2 <- RV_none 71 | 72 | Pid 3 -> close (FD 3) 73 | Tau 74 | Pid 3 <- RV_none 75 | 76 | -------------------------------------------------------------------------------- /fs_spec/src/posix/permissions/utils_ch2: -------------------------------------------------------------------------------- 1 | 2.12. Shell Execution Environment 2 | 3 | A shell execution environment consists of the following: 4 | 5 | Open files inherited upon invocation of the shell, plus open files controlled by exec 6 | 7 | Working directory as set by cd 8 | 9 | File creation mask set by umask 10 | 11 | Current traps set by trap 12 | 13 | Shell parameters that are set by variable assignment (see the set special built-in) or from the System Interfaces volume of POSIX.1-2008 environment inherited by the shell when it begins (see the export special built-in) 14 | 15 | Shell functions; see Function Definition Command 16 | 17 | Options turned on at invocation or by set 18 | 19 | Process IDs of the last commands in asynchronous lists known to this shell environment; see Asynchronous Lists 20 | 21 | Shell aliases; see Alias Substitution 22 | 23 | Utilities other than the special built-ins (see Special Built-In Utilities) shall be invoked in a separate environment that consists of the following. The initial value of these objects shall be the same as that for the parent shell, except as noted below. 24 | 25 | Open files inherited on invocation of the shell, open files controlled by the exec special built-in plus any modifications, and additions specified by any redirections to the utility 26 | 27 | Current working directory 28 | 29 | File creation mask 30 | 31 | If the utility is a shell script, traps caught by the shell shall be set to the default values and traps ignored by the shell shall be set to be ignored by the utility; if the utility is not a shell script, the trap actions (default or ignore) shall be mapped into the appropriate signal handling actions for the utility 32 | 33 | Variables with the export attribute, along with those explicitly exported for the duration of the command, shall be passed to the utility environment variables 34 | 35 | The environment of the shell process shall not be changed by the utility unless explicitly specified by the utility description (for example, cd and umask). 36 | 37 | A subshell environment shall be created as a duplicate of the shell environment, except that signal traps that are not being ignored shall be set to the default action. Changes made to the subshell environment shall not affect the shell environment. Command substitution, commands that are grouped with parentheses, and asynchronous lists shall be executed in a subshell environment. Additionally, each command of a multi-command pipeline is in a subshell environment; as an extension, however, any or all commands in a pipeline may be executed in the current environment. All other commands shall be executed in the current shell environment. -------------------------------------------------------------------------------- /fs_spec/src/t_fs_spec_properties_perms.lem_cppo: -------------------------------------------------------------------------------- 1 | (******************************************************************************) 2 | (* This file contains high level properties of the specifition in *) 3 | (* It is used to tranlate these properties to various backend such that *) 4 | (* they can be proved with these backends *) 5 | (******************************************************************************) 6 | 7 | 8 | open import Bool Maybe Maybe_extra Basic_classes Tuple Num List List_extra Word Function_extra 9 | open import T_fs_spec T_fs_prelude 10 | open Resolve Finset Fs_operations Fs_types 11 | 12 | #ifdef aspect_perms 13 | open Fs_permissions 14 | 15 | (* -------------------------------------------------------------------------- *) 16 | (* Permissions *) 17 | (* -------------------------------------------------------------------------- *) 18 | 19 | lemma S_IRWXU_eq : (S_IRWXU = combine_file_perms [S_IRUSR; S_IWUSR; S_IXUSR]) 20 | lemma S_IRWXG_eq : (S_IRWXG = combine_file_perms [S_IRGRP; S_IWGRP; S_IXGRP]) 21 | lemma S_IRWXO_eq : (S_IRWXO = combine_file_perms [S_IROTH; S_IWOTH; S_IXOTH]) 22 | 23 | lemma dest_file_perm_simp : forall p. File_perm (dest_file_perm p) = p 24 | 25 | (* some sanity checks *) 26 | lemma set_unset_file_perms_0 : forall p. set_file_perms p (File_perm 0O0000) = p 27 | lemma set_unset_file_perms_1 : forall p. unset_file_perms p (File_perm 0) = p 28 | lemma set_unset_file_perms_2 : forall p. set_file_perms (File_perm 0) p = p 29 | lemma set_unset_file_perms_3 : forall p. unset_file_perms (File_perm 0) p = File_perm 0 30 | lemma set_unset_file_perms_4 : forall p1 p2. (set_file_perms (unset_file_perms p1 p2) p2 = set_file_perms p1 p2) 31 | 32 | (* usual lemmata I had in mind while defining it *) 33 | theorem check_file_perms_refl : forall p. check_file_perms p p 34 | theorem check_file_perms_trans : forall p1 p2 p3. check_file_perms p1 p2 --> check_file_perms p2 p3 --> check_file_perms p1 p3 35 | theorem check_file_perms_antisym : forall p1 p2. check_file_perms p1 p2 --> check_file_perms p2 p1 --> (p1 = p2) 36 | 37 | theorem check_file_perms_set : forall p1 p2 p3. check_file_perms p2 p3 --> check_file_perms (set_file_perms p1 p2) p3 38 | theorem check_file_perms_unset : forall p1 p2 p3. ((dest_file_perm p2) land (dest_file_perm p3) <> 0) --> 39 | not (check_file_perms (unset_file_perms p1 p2) p3) 40 | 41 | theorem set_file_perms_combine : forall p1 p2 p3. set_file_perms (set_file_perms p1 p2) p3 = set_file_perms p1 (combine_file_perms [p2;p3]) 42 | theorem unset_file_perms_combine : forall p1 p2 p3. unset_file_perms (unset_file_perms p1 p2) p3 = unset_file_perms p1 (combine_file_perms [p2;p3]) 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /fs_test/lib/stat.mli: -------------------------------------------------------------------------------- 1 | (****************************************************************************) 2 | (* Copyright (c) 2013, 2014, 2015, Tom Ridge, David Sheets, Thomas Tuerk, *) 3 | (* Andrea Giugliano (as part of the SibylFS project) *) 4 | (* *) 5 | (* Permission to use, copy, modify, and/or distribute this software for *) 6 | (* any purpose with or without fee is hereby granted, provided that the *) 7 | (* above copyright notice and this permission notice appear in all *) 8 | (* copies. *) 9 | (* *) 10 | (* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL *) 11 | (* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED *) 12 | (* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE *) 13 | (* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL *) 14 | (* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR *) 15 | (* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER *) 16 | (* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR *) 17 | (* PERFORMANCE OF THIS SOFTWARE. *) 18 | (* *) 19 | (* Meta: *) 20 | (* - Headers maintained using headache. *) 21 | (* - License source: http://opensource.org/licenses/ISC *) 22 | (****************************************************************************) 23 | 24 | type t = Fs_interface.Fs_spec_intf.Fs_types.ty_stats 25 | type d_t = { 26 | d_st_kind : Fs_interface.Fs_spec_intf.Fs_types.file_kind Diff.diff; 27 | d_st_perm : Fs_interface.Fs_spec_intf.Fs_types.file_perm Diff.diff; 28 | d_st_size : int64 Diff.diff; 29 | d_st_nlink : int Diff.diff; 30 | d_st_uid : Fs_interface.Fs_spec_intf.Fs_types.uid Diff.diff; 31 | d_st_gid : Fs_interface.Fs_spec_intf.Fs_types.gid Diff.diff; 32 | d_st_atime : Fs_interface.Fs_spec_intf.Fs_types.float_t Diff.diff; 33 | d_st_mtime : Fs_interface.Fs_spec_intf.Fs_types.float_t Diff.diff; 34 | d_st_ctime : Fs_interface.Fs_spec_intf.Fs_types.float_t Diff.diff; 35 | } 36 | val __d_t_of_sexp__ : Sexplib.Sexp.t -> d_t 37 | val d_t_of_sexp : Sexplib.Sexp.t -> d_t 38 | val sexp_of_d_t : d_t -> Sexplib.Sexp.t 39 | val is_d_zero : d_t -> bool 40 | val diff : 41 | Fs_interface.Fs_spec_intf.Fs_types.ty_stats -> 42 | Fs_interface.Fs_spec_intf.Fs_types.ty_stats -> d_t 43 | -------------------------------------------------------------------------------- /.nix/isabelle/default.nix: -------------------------------------------------------------------------------- 1 | { }: 2 | 3 | # adapted from nixpkgs by tr 4 | 5 | let 6 | pkgs = import {}; 7 | stdenv = pkgs.stdenv; 8 | fetchurl = pkgs.fetchurl; 9 | perl = pkgs.perl; 10 | nettools = pkgs.nettools; 11 | # java = pkgs.jre; 12 | # polyml = pkgs.polyml; 13 | # proofgeneral = pkgs.emacs24Packages.proofgeneral; 14 | 15 | in 16 | 17 | #{ stdenv, fetchurl, perl, nettools, java, polyml, proofgeneral }: 18 | # nettools needed for hostname 19 | 20 | let 21 | dirname = "Isabelle2014"; 22 | theories = ["HOL" "FOL" "ZF"]; 23 | in 24 | 25 | stdenv.mkDerivation { 26 | name = "isabelle-2014"; 27 | inherit dirname theories; 28 | 29 | 30 | 31 | src = if stdenv.isDarwin 32 | then fetchurl { 33 | url = http://isabelle.in.tum.de/dist/Isabelle2014_macos.tar.gz; # FIXME update 34 | sha256 = "1aa3vz2nnkkyd4mlsqbs69jqfxlll5h0k5fj9m1j9wqiddqwvwcf"; 35 | } 36 | else fetchurl { 37 | url = http://isabelle.in.tum.de/website-Isabelle2014/dist/Isabelle2014_linux.tar.gz; 38 | sha256 = "0z81pwwllavka4r57fx6yi9kbpbb9xbanp8dsjix49qpyj2a72jy"; 39 | }; 40 | 41 | buildInputs = [ perl ] 42 | ++ stdenv.lib.optionals (!stdenv.isDarwin) [ nettools ]; 43 | 44 | sourceRoot = dirname; 45 | 46 | postPatch = '' 47 | ENV=$(type -p env) 48 | patchShebangs "." 49 | substituteInPlace lib/Tools/env \ 50 | --replace /usr/bin/env $ENV 51 | substituteInPlace lib/Tools/install \ 52 | --replace /usr/bin/env $ENV 53 | ''; 54 | 55 | # substituteInPlace etc/settings \ 56 | # --subst-var-by ML_HOME "${polyml}/bin" \ 57 | # --subst-var-by PROOFGENERAL_HOME "${proofgeneral}/share/emacs/site-lisp/ProofGeneral" 58 | # substituteInPlace contrib/jdk/etc/settings \ 59 | # --replace ISABELLE_JDK_HOME= '#ISABELLE_JDK_HOME=' 60 | # substituteInPlace contrib/polyml-5.5.2-1/etc/settings \ 61 | # --replace 'ML_HOME="$POLYML_HOME/$ML_PLATFORM"' \ 62 | # "ML_HOME=\"${polyml}/bin\"" 63 | 64 | 65 | buildPhase = '' 66 | # note the -b in the following 67 | ''; 68 | 69 | installPhase = '' 70 | mkdir -p $out/bin 71 | mv $TMP/$dirname $out 72 | cd $out/$dirname 73 | bin/isabelle install $out/bin 74 | # $out/bin/isabelle build -s -b HOL 75 | ''; 76 | 77 | meta = { 78 | description = "A generic proof assistant"; 79 | 80 | longDescription = '' 81 | Isabelle is a generic proof assistant. It allows mathematical formulas 82 | to be expressed in a formal language and provides tools for proving those 83 | formulas in a logical calculus. 84 | ''; 85 | homepage = http://isabelle.in.tum.de/; 86 | license = "LGPL"; 87 | maintainers = [ stdenv.lib.maintainers.jwiegley ]; 88 | }; 89 | } 90 | -------------------------------------------------------------------------------- /fs_test/example_traces/os_perms1-os.trace: -------------------------------------------------------------------------------- 1 | # make sure we are not running as root 2 | create Pid 2 User_id 2 Group_id 2 3 | 4 | # create dirs with access permissions options for rwx 5 | Pid 2 -> mkdir /tmp_dir_uwx/ -wx------ 6 | Tau 7 | Pid 2 <- - 8 | 9 | Pid 2 -> mkdir /tmp_dir_uw/ -w------- 10 | Tau 11 | Pid 2 <- - 12 | 13 | Pid 2 -> mkdir /tmp_dir_ux/ --x------ 14 | Tau 15 | Pid 2 <- - 16 | 17 | # creating a subdir requieres both w or x permission 18 | Pid 2 -> mkdir /tmp_dir_uwx/d1 --------- 19 | Tau 20 | Pid 2 <- - 21 | 22 | Pid 2 -> mkdir /tmp_dir_uw/d1 --------- 23 | Tau 24 | Pid 2 <- EACCES 25 | 26 | Pid 2 -> mkdir /tmp_dir_ux/d1 --------- 27 | Tau 28 | Pid 2 <- EACCES 29 | 30 | # trying to access files in dirs without search permissions does not work 31 | Pid 2 -> open /tmp_dir_uw/f-nonexist.txt [O_RDONLY] 32 | Tau 33 | Pid 2 <- EACCES 34 | 35 | # creating files with permissions and trying to open them again 36 | # with various openflags 37 | Pid 2 -> open /tmp_dir_uwx/f1rwx.txt [O_CREAT;O_RDWR] rwx------ 38 | Tau 39 | Pid 2 <- - 40 | 41 | Pid 2 -> open /tmp_dir_uwx/f1rwx.txt [O_RDONLY] 42 | Tau 43 | Pid 2 <- - 44 | 45 | Pid 2 -> open /tmp_dir_uwx/f1rwx.txt [O_WRONLY] 46 | Tau 47 | Pid 2 <- - 48 | 49 | Pid 2 -> open /tmp_dir_uwx/f1rwx.txt [O_RDWR] 50 | Tau 51 | Pid 2 <- - 52 | 53 | Pid 2 -> open /tmp_dir_uwx/f1rwx.txt [O_EXEC] 54 | Tau 55 | Pid 2 <- - 56 | 57 | Pid 2 -> open /tmp_dir_uwx/f1r.txt [O_CREAT;O_RDWR] r-------- 58 | Tau 59 | Pid 2 <- - 60 | 61 | Pid 2 -> open /tmp_dir_uwx/f1r.txt [O_RDONLY] 62 | Tau 63 | Pid 2 <- - 64 | 65 | Pid 2 -> open /tmp_dir_uwx/f1r.txt [O_WRONLY] 66 | Tau 67 | Pid 2 <- EACCES 68 | 69 | Pid 2 -> open /tmp_dir_uwx/f1r.txt [O_RDWR] 70 | Tau 71 | Pid 2 <- EACCES 72 | 73 | Pid 2 -> open /tmp_dir_uwx/f1r.txt [O_EXEC] 74 | Tau 75 | Pid 2 <- EACCES 76 | 77 | Pid 2 -> open /tmp_dir_uwx/f1w.txt [O_CREAT;O_RDWR] -w------- 78 | Tau 79 | Pid 2 <- - 80 | 81 | Pid 2 -> open /tmp_dir_uwx/f1w.txt [O_RDONLY] 82 | Tau 83 | Pid 2 <- EACCES 84 | 85 | Pid 2 -> open /tmp_dir_uwx/f1w.txt [O_WRONLY] 86 | Tau 87 | Pid 2 <- - 88 | 89 | Pid 2 -> open /tmp_dir_uwx/f1w.txt [O_RDWR] 90 | Tau 91 | Pid 2 <- EACCES 92 | 93 | Pid 2 -> open /tmp_dir_uwx/f1w.txt [O_EXEC] 94 | Tau 95 | Pid 2 <- EACCES 96 | 97 | Pid 2 -> open /tmp_dir_uwx/f1x.txt [O_CREAT;O_RDWR] --x------ 98 | Tau 99 | Pid 2 <- - 100 | 101 | Pid 2 -> open /tmp_dir_uwx/f1x.txt [O_RDONLY] 102 | Tau 103 | Pid 2 <- EACCES 104 | 105 | Pid 2 -> open /tmp_dir_uwx/f1x.txt [O_WRONLY] 106 | Tau 107 | Pid 2 <- EACCES 108 | 109 | Pid 2 -> open /tmp_dir_uwx/f1x.txt [O_RDWR] 110 | Tau 111 | Pid 2 <- EACCES 112 | 113 | Pid 2 -> open /tmp_dir_uwx/f1x.txt [O_EXEC] 114 | Tau 115 | Pid 2 <- - 116 | 117 | 118 | -------------------------------------------------------------------------------- /fs_spec/src/lem_support.ml: -------------------------------------------------------------------------------- 1 | (****************************************************************************) 2 | (* Copyright (c) 2013, 2014, 2015, Tom Ridge, David Sheets, Thomas Tuerk, *) 3 | (* Andrea Giugliano (as part of the SibylFS project) *) 4 | (* *) 5 | (* Permission to use, copy, modify, and/or distribute this software for *) 6 | (* any purpose with or without fee is hereby granted, provided that the *) 7 | (* above copyright notice and this permission notice appear in all *) 8 | (* copies. *) 9 | (* *) 10 | (* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL *) 11 | (* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED *) 12 | (* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE *) 13 | (* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL *) 14 | (* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR *) 15 | (* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER *) 16 | (* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR *) 17 | (* PERFORMANCE OF THIS SOFTWARE. *) 18 | (* *) 19 | (* Meta: *) 20 | (* - Headers maintained using headache. *) 21 | (* - License source: http://opensource.org/licenses/ISC *) 22 | (****************************************************************************) 23 | 24 | (* Additional defns required by Lem-exported ocaml defns, which we 25 | don't want in Lem for some reason *) 26 | 27 | type 'a finset = Finset of 'a list 28 | let list_from_finset (Finset l) = l 29 | let finset_from_list l = (Finset l) 30 | 31 | open Sexplib.Std 32 | 33 | module Int32 = struct 34 | include Int32 35 | let t_of_sexp = int32_of_sexp 36 | let sexp_of_t = sexp_of_int32 37 | end 38 | 39 | module Int64 = struct 40 | include Int64 41 | let t_of_sexp = int64_of_sexp 42 | let sexp_of_t = sexp_of_int64 43 | end 44 | 45 | (* FIXME move float_t here *) 46 | (* 47 | let float_t_of_sexp = fun _ -> failwith "lem_support: FIXME float_t" 48 | let sexp_of_float_t = fun _ -> failwith "lem_support: FIXME float_t" 49 | *) 50 | 51 | (* 52 | module MyDynArray2 = struct 53 | include Dynarray.MyDynArray2 54 | 55 | let t_of_sexp s = Sexplib.Conv.(pair_of_sexp int_of_sexp bigstring_of_sexp s) 56 | let sexp_of_t t = Sexplib.Conv.(sexp_of_pair sexp_of_int sexp_of_bigstring t) 57 | end 58 | *) 59 | -------------------------------------------------------------------------------- /fs_test/lib/diff.ml: -------------------------------------------------------------------------------- 1 | (****************************************************************************) 2 | (* Copyright (c) 2013, 2014, 2015, Tom Ridge, David Sheets, Thomas Tuerk, *) 3 | (* Andrea Giugliano (as part of the SibylFS project) *) 4 | (* *) 5 | (* Permission to use, copy, modify, and/or distribute this software for *) 6 | (* any purpose with or without fee is hereby granted, provided that the *) 7 | (* above copyright notice and this permission notice appear in all *) 8 | (* copies. *) 9 | (* *) 10 | (* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL *) 11 | (* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED *) 12 | (* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE *) 13 | (* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL *) 14 | (* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR *) 15 | (* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER *) 16 | (* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR *) 17 | (* PERFORMANCE OF THIS SOFTWARE. *) 18 | (* *) 19 | (* Meta: *) 20 | (* - Headers maintained using headache. *) 21 | (* - License source: http://opensource.org/licenses/ISC *) 22 | (****************************************************************************) 23 | 24 | open Sexplib.Std 25 | 26 | type 'a diff = ('a * 'a) option with sexp 27 | 28 | let diff a b = if a = b then None else Some (a,b) 29 | 30 | let inter_diff_map (fn_l,fn_c,fn_r) cmp l l' = 31 | let l = List.sort cmp l in 32 | let l' = List.sort cmp l' in 33 | 34 | let rec group (only, both, only') l l' = 35 | match (l, l') with 36 | | ([], _) -> 37 | (List.rev_map fn_l only, 38 | List.rev_map fn_c both, 39 | List.rev_map fn_r (l' @ only')) 40 | | (_, []) -> 41 | (List.rev_map fn_l (l @ only), 42 | List.rev_map fn_c both, 43 | List.rev_map fn_r only') 44 | | (e1 :: l, e2 :: l') -> 45 | if cmp e1 e2 = 0 46 | then group (only, (e1, e2) :: both, only') l l' 47 | else if cmp e1 e2 < 0 48 | then group (e1::only, both, only') l (e2::l') 49 | else group (only, both, e2::only') (e1::l) l' 50 | in 51 | group ([], [], []) l l' 52 | 53 | let inter_diff cmp = inter_diff_map ((fun x -> x),(fun x -> x),(fun x -> x)) cmp 54 | -------------------------------------------------------------------------------- /fs_spec/src/abstract_string.ml: -------------------------------------------------------------------------------- 1 | (****************************************************************************) 2 | (* Copyright (c) 2013, 2014, 2015, Tom Ridge, David Sheets, Thomas Tuerk, *) 3 | (* Andrea Giugliano (as part of the SibylFS project) *) 4 | (* *) 5 | (* Permission to use, copy, modify, and/or distribute this software for *) 6 | (* any purpose with or without fee is hereby granted, provided that the *) 7 | (* above copyright notice and this permission notice appear in all *) 8 | (* copies. *) 9 | (* *) 10 | (* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL *) 11 | (* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED *) 12 | (* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE *) 13 | (* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL *) 14 | (* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR *) 15 | (* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER *) 16 | (* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR *) 17 | (* PERFORMANCE OF THIS SOFTWARE. *) 18 | (* *) 19 | (* Meta: *) 20 | (* - Headers maintained using headache. *) 21 | (* - License source: http://opensource.org/licenses/ISC *) 22 | (****************************************************************************) 23 | 24 | open Sexplib.Std 25 | open Sexplib.Conv 26 | 27 | type t = string with sexp 28 | 29 | (* http://stackoverflow.com/questions/10068713/string-to-list-of-char *) 30 | let explode s = 31 | let rec exp i l = 32 | if i < 0 then l else exp (i - 1) (s.[i] :: l) in 33 | exp (String.length s - 1) [] 34 | 35 | let to_list : t -> char list = explode 36 | 37 | (* http://caml.inria.fr/pub/old_caml_site/FAQ/FAQ_EXPERT-eng.html#strings *) 38 | let implode l = 39 | let res = String.create (List.length l) in 40 | let rec imp i = function 41 | | [] -> res 42 | | c :: l -> res.[i] <- c; imp (i + 1) l in 43 | imp 0 l 44 | 45 | let of_list : char list -> t = implode 46 | 47 | let of_string : string -> t = fun x -> x 48 | 49 | let to_string : t -> string = fun x -> x 50 | 51 | let dim : t -> int = String.length 52 | 53 | let resize : t -> int -> t = fun s i -> 54 | if i < dim s then String.sub s 0 i else 55 | let s' = String.make (i - dim s) '\000' in 56 | s^s' 57 | 58 | let equal: t -> t -> bool = (=) 59 | -------------------------------------------------------------------------------- /fs_spec/src/tr/27: -------------------------------------------------------------------------------- 1 | On Mac OS/X: 2 | 3 | 4 | ##################################### 5 | # Test 18 6 | ##################################### 7 | 2061: mkdir /test_dir_0018 0o777 8 | 2062: Tau 9 | 2063: RV_none 10 | 11 | 2065: chdir /test_dir_0018 12 | 2066: Tau 13 | 2067: RV_none 14 | 15 | 2069: mkdir empty_dir1 0o777 16 | 2070: Tau 17 | 2071: RV_none 18 | 19 | 2073: mkdir empty_dir2 0o777 20 | 2074: Tau 21 | 2075: RV_none 22 | 23 | 2077: mkdir nonempty_dir1 0o777 24 | 2078: Tau 25 | 2079: RV_none 26 | 27 | 2081: open_close nonempty_dir1/f1.txt [O_CREAT;O_WRONLY] 0o666 28 | 2082: Tau 29 | 2083: RV_none 30 | 31 | 2085: mkdir nonempty_dir1/d2 0o777 32 | 2086: Tau 33 | 2087: RV_none 34 | 35 | 2089: open nonempty_dir1/d2/f3.txt [O_CREAT;O_WRONLY] 0o666 36 | 2090: Tau 37 | 2091: RV_num(3) 38 | 39 | 2093: write! (FD 3) "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor inc" 83 40 | 2094: Tau 41 | 2095: RV_num(83) 42 | 43 | 2097: close (FD 3) 44 | 2098: Tau 45 | 2099: RV_none 46 | 47 | 2101: mkdir nonempty_dir1/d2/d3 0o777 48 | 2102: Tau 49 | 2103: RV_none 50 | 51 | 2105: mkdir nonempty_dir2 0o777 52 | 2106: Tau 53 | 2107: RV_none 54 | 55 | 2109: open_close nonempty_dir2/f1.txt [O_CREAT;O_WRONLY] 0o666 56 | 2110: Tau 57 | 2111: RV_none 58 | 59 | 2113: open nonempty_dir2/f2.txt [O_CREAT;O_WRONLY] 0o666 60 | 2114: Tau 61 | 2115: RV_num(3) 62 | 63 | 2117: write! (FD 3) "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exer" 167 64 | 2118: Tau 65 | 2119: RV_num(167) 66 | 67 | 2121: close (FD 3) 68 | 2122: Tau 69 | 2123: RV_none 70 | 71 | 2125: mkdir nonempty_dir2/d2 0o777 72 | 2126: Tau 73 | 2127: RV_none 74 | 75 | 2129: mkdir nonempty_dir2/d2/d3 0o777 76 | 2130: Tau 77 | 2131: RV_none 78 | 79 | 2133: symlink f1.txt nonempty_dir1/sl_f1.txt 80 | 2134: Tau 81 | 2135: RV_none 82 | 83 | 2137: symlink ../f1.txt nonempty_dir1/d2/sl_dotdot_f1.txt 84 | 2138: Tau 85 | 2139: RV_none 86 | 87 | 2141: symlink no_such_target nonempty_dir1/d2/sl_no_such_target 88 | 2142: Tau 89 | 2143: RV_none 90 | 91 | 2145: symlink ../d2 nonempty_dir1/d2/sl_dotdot_d2 92 | 2146: Tau 93 | 2147: RV_none 94 | 95 | 2149: symlink ../../nonempty_dir1/d2/f3.txt nonempty_dir2/d2/sl_f3.txt 96 | 2150: Tau 97 | 2151: RV_none 98 | 99 | 2153: link empty_dir1 nonempty_dir1/d2/sl_dotdot_f1.txt/ 100 | 2154: Tau 101 | 2155: EEXIST 102 | 103 | Error: 2155: EEXIST 104 | unexpected results: EEXIST 105 | allowed are only: EPERM, ENOTDIR 106 | continuing execution with EPERM, ENOTDIR 107 | 108 | Note that this behaviour only happens on a symlink -------------------------------------------------------------------------------- /fs_spec/src/fs_dict_wrappers.ml: -------------------------------------------------------------------------------- 1 | (****************************************************************************) 2 | (* Copyright (c) 2013, 2014, 2015, Tom Ridge, David Sheets, Thomas Tuerk, *) 3 | (* Andrea Giugliano (as part of the SibylFS project) *) 4 | (* *) 5 | (* Permission to use, copy, modify, and/or distribute this software for *) 6 | (* any purpose with or without fee is hereby granted, provided that the *) 7 | (* above copyright notice and this permission notice appear in all *) 8 | (* copies. *) 9 | (* *) 10 | (* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL *) 11 | (* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED *) 12 | (* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE *) 13 | (* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL *) 14 | (* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR *) 15 | (* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER *) 16 | (* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR *) 17 | (* PERFORMANCE OF THIS SOFTWARE. *) 18 | (* *) 19 | (* Meta: *) 20 | (* - Headers maintained using headache. *) 21 | (* - License source: http://opensource.org/licenses/ISC *) 22 | (****************************************************************************) 23 | 24 | (* wrappers around LEM generated OCaml code that instantiates dictionaries *) 25 | open Fs_prelude 26 | 27 | module FmapFunctor = functor (D : sig 28 | val map_dict : unit -> 'a Lem_map.mapKeyType_class 29 | val set_dict : unit -> 'a Lem_basic_classes.setType_class 30 | end) -> struct 31 | (* open Fmap *) 32 | 33 | let fmap_remove m a = fmap_remove (D.map_dict ()) m a;; 34 | let fmap_update m (a,b) = fmap_update (D.map_dict ()) m (a,b);; 35 | let fmap_update_option m (k,vopt) = fmap_update_option (D.map_dict ()) m (k,vopt);; 36 | let fmap_from_list l = fmap_from_list (D.map_dict ()) l;; 37 | let fmap_lookup m a = fmap_lookup (D.map_dict ()) m a;; 38 | let fmap_empty () = fmap_empty (D.map_dict ()) ();; 39 | 40 | let fmap_dom m = fmap_dom (D.map_dict ()) (D.set_dict ()) m;; 41 | end 42 | 43 | module Fmap_default = FmapFunctor (struct 44 | let map_dict () = Lem_map.instance_Map_MapKeyType_var_dict Lem_basic_classes.instance_Basic_classes_SetType_var_dict 45 | let set_dict () = Lem_basic_classes.instance_Basic_classes_SetType_var_dict 46 | end);; 47 | -------------------------------------------------------------------------------- /fs_test/lib/fs_path.ml: -------------------------------------------------------------------------------- 1 | (****************************************************************************) 2 | (* Copyright (c) 2013, 2014, 2015, Tom Ridge, David Sheets, Thomas Tuerk, *) 3 | (* Andrea Giugliano (as part of the SibylFS project) *) 4 | (* *) 5 | (* Permission to use, copy, modify, and/or distribute this software for *) 6 | (* any purpose with or without fee is hereby granted, provided that the *) 7 | (* above copyright notice and this permission notice appear in all *) 8 | (* copies. *) 9 | (* *) 10 | (* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL *) 11 | (* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED *) 12 | (* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE *) 13 | (* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL *) 14 | (* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR *) 15 | (* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER *) 16 | (* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR *) 17 | (* PERFORMANCE OF THIS SOFTWARE. *) 18 | (* *) 19 | (* Meta: *) 20 | (* - Headers maintained using headache. *) 21 | (* - License source: http://opensource.org/licenses/ISC *) 22 | (****************************************************************************) 23 | 24 | type t = string list 25 | 26 | let split_string delimiter name = 27 | let rec doit part acc = 28 | let open String in 29 | let len = length part in 30 | let idx = try index part delimiter with _ -> len in 31 | let fst = sub part 0 idx in 32 | let idx' = idx + 1 in 33 | if idx' <= len then 34 | let rt = sub part idx' (len - idx') in 35 | doit rt (fst :: acc) 36 | else 37 | fst :: acc 38 | in 39 | List.rev (doit name []) 40 | 41 | let of_string : string -> t = split_string '/' 42 | let to_string (p:t) : string = String.concat "/" p 43 | 44 | let concat p1 p2 = match List.rev p1, p2 with 45 | | "" :: p1, "" :: p2 | "" :: p1, p2 | p1, "" :: p2 | p1, p2 -> 46 | List.rev_append p1 p2 47 | 48 | let resolve path = 49 | let rec remove_dots parts outp = match parts, outp with 50 | | ".."::r, a::rt -> remove_dots r rt 51 | | ".."::r, [] -> raise Not_found 52 | | "."::r , rt -> remove_dots r rt 53 | | r::rs , rt -> remove_dots rs (r :: rt) 54 | | [] , rt -> List.rev rt 55 | in 56 | remove_dots path [] 57 | -------------------------------------------------------------------------------- /fs_spec/src/posix/permissions/ch_4_general_concepts: -------------------------------------------------------------------------------- 1 | ### 4.2 Directory Protection 2 | 3 | > If a directory is writable and the mode bit S_ISVTX is set on the directory, a process may remove or rename files within that directory only if one or more of the following is true: 4 | > 5 | > - The effective user ID of the process is the same as that of the owner ID of the file. 6 | > 7 | > - The effective user ID of the process is the same as that of the owner ID of the directory. 8 | > 9 | > - The process has appropriate privileges. 10 | > 11 | > - Optionally, the file is writable by the process. Whether or not files that are writable by the process can be removed or renamed is implementation-defined. 12 | > 13 | > If the S_ISVTX bit is set on a non-directory file, the behavior is unspecified. 14 | 15 | --- 16 | 17 | ### 4.4 File Access Permissions 18 | 19 | 20 | > The standard file access control mechanism uses the file permission bits, as described below. 21 | > 22 | > Implementations may provide additional or alternate file access control mechanisms, or both. An additional access control mechanism shall only further restrict the access permissions defined by the file permission bits. An alternate file access control mechanism shall: 23 | > 24 | > - Specify file permission bits for the file owner class, file group class, and file other class of that file, corresponding to the access permissions. 25 | > 26 | > - Be enabled only by explicit user action, on a per-file basis by the file owner or a user with appropriate privileges. 27 | > 28 | > - Be disabled for a file after the file permission bits are changed for that file with chmod(). The disabling of the alternate mechanism need not disable any additional mechanisms supported by an implementation. 29 | > 30 | > Whenever a process requests file access permission for read, write, or execute/search, if no additional mechanism denies access, access shall be determined as follows: 31 | > 32 | > - If a process has appropriate privileges: 33 | > 34 | > * If read, write, or directory search permission is requested, access shall be granted. 35 | > 36 | > * If execute permission is requested, access shall be granted if execute permission is granted to at least one user by the file permission bits or by an alternate access control mechanism; otherwise, access shall be denied. 37 | > 38 | > - Otherwise: 39 | > 40 | > * The file permission bits of a file contain read, write, and execute/search permissions for the file owner class, file group class, and file other class. 41 | > 42 | > * Access shall be granted if an alternate access control mechanism is not enabled and the requested access permission bit is set for the class (file owner class, file group class, or file other class) to which the process belongs, or if an alternate access control mechanism is enabled and it allows the requested access; otherwise, access shall be denied. 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /fs_test/adhoc_tests/adhoc_open_multiple_tests-os.trace: -------------------------------------------------------------------------------- 1 | # Tests for open and close with multiple 2 | # file descriptors opened by multiple processes 3 | # essentially just check we get the right ids back 4 | 5 | # WARNING: these tests won't work with posix, 6 | # because its implementation maps everything to 7 | # just one process 8 | 9 | create Pid 2 User_id 0 Group_id 0 10 | 11 | ############################################## 12 | # basic cases that should work 13 | ############################################## 14 | 15 | # create a file 16 | Pid 1 -> open f1.txt [O_WRONLY;O_CREAT] 0o644 17 | Tau 18 | Pid 1 <- RV_num(3) 19 | 20 | Pid 1 -> close (FD 3) 21 | Tau 22 | Pid 1 <- RV_none 23 | 24 | # and another file 25 | Pid 1 -> open f2.txt [O_WRONLY;O_CREAT] 0o644 26 | Tau 27 | Pid 1 <- RV_num(3) 28 | 29 | Pid 1 -> close (FD 3) 30 | Tau 31 | Pid 1 <- RV_none 32 | 33 | 34 | # open both files in the same process 35 | Pid 1 -> open f1.txt [] 36 | Tau 37 | Pid 1 <- RV_num(3) 38 | 39 | Pid 1 -> open f2.txt [] 40 | Tau 41 | Pid 1 <- RV_num(4) 42 | 43 | Pid 1 -> close (FD 3) 44 | Tau 45 | Pid 1 <- RV_none 46 | 47 | Pid 1 -> close (FD 4) 48 | Tau 49 | Pid 1 <- RV_none 50 | 51 | 52 | # open both files in the same process 53 | # and close and open again 54 | Pid 1 -> open f1.txt [] 55 | Tau 56 | Pid 1 <- RV_num(3) 57 | 58 | Pid 1 -> open f2.txt [] 59 | Tau 60 | Pid 1 <- RV_num(4) 61 | 62 | Pid 1 -> close (FD 4) 63 | Tau 64 | Pid 1 <- RV_none 65 | 66 | Pid 1 -> open f2.txt [] 67 | Tau 68 | Pid 1 <- RV_num(4) 69 | 70 | Pid 1 -> close (FD 3) 71 | Tau 72 | Pid 1 <- RV_none 73 | 74 | Pid 1 -> close (FD 4) 75 | Tau 76 | Pid 1 <- RV_none 77 | 78 | 79 | # open both files in the same process 80 | # and close and open again 81 | Pid 1 -> open f1.txt [] 82 | Tau 83 | Pid 1 <- RV_num(3) 84 | 85 | Pid 1 -> open f2.txt [] 86 | Tau 87 | Pid 1 <- RV_num(4) 88 | 89 | Pid 1 -> close (FD 3) 90 | Tau 91 | Pid 1 <- RV_none 92 | 93 | Pid 1 -> open f1.txt [] 94 | Tau 95 | Pid 1 <- RV_num(3) 96 | 97 | Pid 1 -> close (FD 4) 98 | Tau 99 | Pid 1 <- RV_none 100 | 101 | Pid 1 -> close (FD 3) 102 | Tau 103 | Pid 1 <- RV_none 104 | 105 | 106 | # open both files in the same process 107 | # and close and open again 108 | Pid 1 -> open f1.txt [] 109 | Tau 110 | Pid 1 <- RV_num(3) 111 | 112 | Pid 1 -> open f2.txt [] 113 | Tau 114 | Pid 1 <- RV_num(4) 115 | 116 | Pid 1 -> close (FD 3) 117 | Tau 118 | Pid 1 <- RV_none 119 | 120 | Pid 1 -> open f1.txt [] 121 | Tau 122 | Pid 1 <- RV_num(3) 123 | 124 | Pid 1 -> close (FD 4) 125 | Tau 126 | Pid 1 <- RV_none 127 | 128 | Pid 1 -> close (FD 3) 129 | Tau 130 | Pid 1 <- RV_none 131 | 132 | 133 | 134 | 135 | # open both files in the different processes 136 | Pid 1 -> open f1.txt [] 137 | Tau 138 | Pid 1 <- RV_num(3) 139 | 140 | Pid 2 -> open f2.txt [] 141 | Tau 142 | Pid 2 <- RV_num(3) 143 | 144 | Pid 1 -> close (FD 3) 145 | Tau 146 | Pid 1 <- RV_none 147 | 148 | Pid 2 -> close (FD 3) 149 | Tau 150 | Pid 2 <- RV_none 151 | -------------------------------------------------------------------------------- /fs_test/adhoc_tests/adhoc_lseek_tests-int.trace: -------------------------------------------------------------------------------- 1 | # Tests for lseek 2 | 3 | 4 | ############################################## 5 | # reads combined with lseek 6 | ############################################## 7 | 8 | # initialise a file with some text 9 | open f1.txt [O_WRONLY;O_TRUNC;O_CREAT] 0o666 10 | write (FD 3) "0123456789" 10 11 | close (FD 3) 12 | 13 | open f1.txt [] 14 | 15 | # read 2 bytes and then 2 again 16 | read (FD 3) 2 17 | read (FD 3) 2 18 | 19 | # jump back to beginning 20 | lseek (FD 3) 0 SEEK_SET 21 | read (FD 3) 2 22 | 23 | # jump to absolute position 4 24 | lseek (FD 3) 4 SEEK_SET 25 | read (FD 3) 2 26 | 27 | # jump after end 28 | lseek (FD 3) 5 SEEK_END 29 | read (FD 3) 2 30 | 31 | # jump after end 32 | lseek (FD 3) 5 SEEK_END 33 | read (FD 3) 2 34 | 35 | # jump 2 before end 36 | lseek (FD 3) -2 SEEK_END 37 | read (FD 3) 2 38 | 39 | # 2 back and try again 40 | lseek (FD 3) -2 SEEK_CUR 41 | read (FD 3) 2 42 | 43 | # jump just to zero 44 | lseek (FD 3) -10 SEEK_CUR 45 | read (FD 3) 2 46 | 47 | # jump too far back (negative resulting offset) 48 | lseek (FD 3) -10 SEEK_CUR 49 | read (FD 3) 2 50 | 51 | # use wrong whence 52 | lseek (FD 3) 0 5 53 | read (FD 3) 2 54 | 55 | # check position 56 | lseek (FD 3) 0 SEEK_CUR 57 | lseek (FD 3) 0 SEEK_CUR 58 | 59 | close (FD 3) 60 | 61 | # use closed file-descriptor 62 | lseek (FD 3) 0 SEEK_CUR 63 | 64 | # use non-existing file-descriptor 65 | lseek (FD 4) 0 SEEK_CUR 66 | 67 | 68 | ############################################## 69 | # write and lseek 70 | ############################################## 71 | 72 | # jump after end of file should do nothing by itself 73 | open f1.txt [O_WRONLY;O_TRUNC] 0o666 74 | lseek (FD 3) 5 SEEK_SET 75 | close (FD 3) 76 | 77 | open f1.txt [O_RDONLY] 78 | read (FD 3) 100 79 | close (FD 3) 80 | 81 | 82 | # jump after end of file, then write adds 0s 83 | open f1.txt [O_WRONLY;O_TRUNC] 0o666 84 | lseek (FD 3) 5 SEEK_SET 85 | write (FD 3) "0123456789" 10 86 | close (FD 3) 87 | 88 | open f1.txt [O_RDONLY] 89 | read (FD 3) 100 90 | close (FD 3) 91 | 92 | 93 | # write then jump back and write, jump back, read 94 | open f1.txt [O_RDWR;O_TRUNC] 0o666 95 | write (FD 3) "0123456789" 10 96 | lseek (FD 3) -2 SEEK_CUR 97 | write (FD 3) "XX" 2 98 | lseek (FD 3) -6 SEEK_CUR 99 | read (FD 3) 2 100 | write (FD 3) "YY" 2 101 | close (FD 3) 102 | 103 | open f1.txt [O_RDONLY] 104 | read (FD 3) 100 105 | close (FD 3) 106 | 107 | 108 | ############################################## 109 | # lseek on dirs is not properly supported and 110 | # therefore not tested carefully 111 | ############################################## 112 | 113 | mkdir d1 0o777 114 | open_close d1/f1.txt [O_WRONLY;O_CREAT] 0o666 115 | open_close d1/f2.txt [O_WRONLY;O_CREAT] 0o666 116 | open_close d1/f3.txt [O_WRONLY;O_CREAT] 0o666 117 | 118 | 119 | open d1 [O_RDONLY] 120 | lseek (FD 3) 0 SEEK_CUR 121 | read (FD 3) 10 122 | 123 | lseek (FD 3) 4 SEEK_CUR 124 | read (FD 3) 10 125 | 126 | # the following fail with a oveflow 127 | lseek (FD 3) 0 SEEK_END 128 | lseek (FD 3) -2000 SEEK_END 129 | 130 | lseek (FD 3) 0 SEEK_SET 131 | read (FD 3) 10 132 | 133 | lseek (FD 3) 10 SEEK_SET 134 | read (FD 3) 10 135 | 136 | close (FD 3) -------------------------------------------------------------------------------- /fs_test/example_traces/os_perms_group1-os.trace: -------------------------------------------------------------------------------- 1 | # create two processes that are not root, 2 | # make sure they have different user ids, but 3 | # the user of the second process 3 belongs to the right group 4 | # moreover set umask of process 2 so it can create 5 | # directories with write permission for the group 6 | 7 | create Pid 2 User_id 2 Group_id 2 8 | create Pid 3 User_id 3 Group_id 3 9 | 10 | Pid 2 -> umask 0o000 11 | Tau 12 | Pid 2 <- RV_file_perm(0o022) 13 | 14 | Pid 2 -> add_user_to_group User_id 3 Group_id 2 15 | Tau 16 | Pid 2 <- - 17 | 18 | # create dirs with group access permissions options for rwx 19 | Pid 2 -> mkdir /tmp_dir_gwx/ ----wx--- 20 | Tau 21 | Pid 2 <- - 22 | 23 | Pid 2 -> mkdir /tmp_dir_gw/ ----w---- 24 | Tau 25 | Pid 2 <- - 26 | 27 | Pid 2 -> mkdir /tmp_dir_gx/ -----x--- 28 | Tau 29 | Pid 2 <- - 30 | 31 | # creating a subdir requieres both w or x permission 32 | Pid 3 -> mkdir /tmp_dir_gwx/d1 --------- 33 | Tau 34 | Pid 3 <- - 35 | 36 | Pid 3 -> mkdir /tmp_dir_gw/d1 --------- 37 | Tau 38 | Pid 3 <- EACCES 39 | 40 | Pid 3 -> mkdir /tmp_dir_gx/d1 --------- 41 | Tau 42 | Pid 3 <- EACCES 43 | 44 | # trying to access files in dirs without search permissions does not work 45 | Pid 3 -> open /tmp_dir_gw/f-nonexist.txt [O_RDONLY] 46 | Tau 47 | Pid 3 <- EACCES 48 | 49 | # creating files with permissions and trying to open them again 50 | # with various openflags 51 | Pid 2 -> mkdir /tmp_dir_uwx/ -wx--x--- 52 | Tau 53 | Pid 2 <- - 54 | 55 | Pid 2 -> open /tmp_dir_uwx/f1rwx.txt [O_CREAT;O_RDWR] ---rwx--- 56 | Tau 57 | Pid 2 <- - 58 | 59 | Pid 3 -> open /tmp_dir_uwx/f1rwx.txt [O_RDONLY] 60 | Tau 61 | Pid 3 <- - 62 | 63 | Pid 3 -> open /tmp_dir_uwx/f1rwx.txt [O_WRONLY] 64 | Tau 65 | Pid 3 <- - 66 | 67 | Pid 3 -> open /tmp_dir_uwx/f1rwx.txt [O_RDWR] 68 | Tau 69 | Pid 3 <- - 70 | 71 | Pid 3 -> open /tmp_dir_uwx/f1rwx.txt [O_EXEC] 72 | Tau 73 | Pid 3 <- - 74 | 75 | Pid 2 -> open /tmp_dir_uwx/f1r.txt [O_CREAT;O_RDWR] ---r----- 76 | Tau 77 | Pid 2 <- - 78 | 79 | Pid 3 -> open /tmp_dir_uwx/f1r.txt [O_RDONLY] 80 | Tau 81 | Pid 3 <- - 82 | 83 | Pid 3 -> open /tmp_dir_uwx/f1r.txt [O_WRONLY] 84 | Tau 85 | Pid 3 <- EACCES 86 | 87 | Pid 3 -> open /tmp_dir_uwx/f1r.txt [O_RDWR] 88 | Tau 89 | Pid 3 <- EACCES 90 | 91 | Pid 3 -> open /tmp_dir_uwx/f1r.txt [O_EXEC] 92 | Tau 93 | Pid 3 <- EACCES 94 | 95 | Pid 2 -> open /tmp_dir_uwx/f1w.txt [O_CREAT;O_RDWR] ----w---- 96 | Tau 97 | Pid 2 <- - 98 | 99 | Pid 3 -> open /tmp_dir_uwx/f1w.txt [O_RDONLY] 100 | Tau 101 | Pid 3 <- EACCES 102 | 103 | Pid 3 -> open /tmp_dir_uwx/f1w.txt [O_WRONLY] 104 | Tau 105 | Pid 3 <- - 106 | 107 | Pid 3 -> open /tmp_dir_uwx/f1w.txt [O_RDWR] 108 | Tau 109 | Pid 3 <- EACCES 110 | 111 | Pid 3 -> open /tmp_dir_uwx/f1w.txt [O_EXEC] 112 | Tau 113 | Pid 3 <- EACCES 114 | 115 | Pid 2 -> open /tmp_dir_uwx/f1x.txt [O_CREAT;O_RDWR] -----x--- 116 | Tau 117 | Pid 2 <- - 118 | 119 | Pid 3 -> open /tmp_dir_uwx/f1x.txt [O_RDONLY] 120 | Tau 121 | Pid 3 <- EACCES 122 | 123 | Pid 3 -> open /tmp_dir_uwx/f1x.txt [O_WRONLY] 124 | Tau 125 | Pid 3 <- EACCES 126 | 127 | Pid 3 -> open /tmp_dir_uwx/f1x.txt [O_RDWR] 128 | Tau 129 | Pid 3 <- EACCES 130 | 131 | Pid 3 -> open /tmp_dir_uwx/f1x.txt [O_EXEC] 132 | Tau 133 | Pid 3 <- - 134 | 135 | 136 | -------------------------------------------------------------------------------- /fs_spec/src/posix/opendir.md: -------------------------------------------------------------------------------- 1 | # SYNOPSIS 2 | 3 | #include 4 | 5 | DIR *fdopendir(int fd); 6 | DIR *opendir(const char *dirname); 7 | 8 | # DESCRIPTION 9 | 10 | > The fdopendir() function shall be equivalent to the opendir() 11 | > function except that the directory is specified by a file 12 | > descriptor rather than by a name. The file offset associated 13 | > with the file descriptor at the time of the call determines 14 | > which entries are returned. 15 | 16 | > Upon successful return from fdopendir(), the file descriptor is 17 | > under the control of the system, and if any attempt is made to 18 | > close the file descriptor, or to modify the state of the 19 | > associated description, other than by means of closedir(), 20 | > readdir(), readdir_r(), rewinddir(), or [XSI] [Option Start] 21 | > seekdir(), [Option End] the behavior is undefined. Upon calling 22 | > closedir() the file descriptor shall be closed. 23 | 24 | > It is unspecified whether the FD_CLOEXEC flag will be set on the 25 | > file descriptor by a successful call to fdopendir(). 26 | 27 | > The opendir() function shall open a directory stream 28 | > corresponding to the directory named by the dirname 29 | > argument. The directory stream is positioned at the first 30 | > entry. If the type DIR is implemented using a file descriptor, 31 | > applications shall only be able to open up to a total of 32 | > {OPEN_MAX} files and directories. 33 | 34 | > If the type DIR is implemented using a file descriptor, the 35 | > descriptor shall be obtained as if the O_DIRECTORY flag was 36 | > passed to open(). 37 | 38 | 39 | # RETURN VALUE 40 | 41 | > Upon successful completion, these functions shall return a 42 | > pointer to an object of type DIR. Otherwise, these functions 43 | > shall return a null pointer and set errno to indicate the error. 44 | 45 | # ERRORS 46 | 47 | > The opendir() function shall fail if: 48 | 49 | > [EACCES] 50 | > Search permission is denied for the component of the path 51 | > prefix of dirname or 52 | 53 | EACCES:1 54 | 55 | > read permission is denied for dirname. 56 | 57 | EACCES:2 58 | 59 | > [ELOOP] 60 | > A loop exists in symbolic links encountered during 61 | > resolution of the dirname argument. 62 | 63 | > [ENAMETOOLONG] 64 | > The length of a component of a pathname is longer than {NAME_MAX}. 65 | 66 | > [ENOENT] 67 | > A component of dirname does not name an existing directory or dirname is an empty string. 68 | 69 | ENOENT:1 70 | 71 | > [ENOTDIR] 72 | > A component of dirname names an existing file that is neither a directory nor a symbolic link to a directory. 73 | 74 | ENOTDIR:1 75 | 76 | > The opendir() function may fail if: 77 | 78 | > [ELOOP] 79 | > More than {SYMLOOP_MAX} symbolic links were encountered during resolution of the dirname argument. 80 | > [EMFILE] 81 | > All file descriptors available to the process are currently open. 82 | > [ENAMETOOLONG] 83 | > The length of a pathname exceeds {PATH_MAX}, or pathname resolution of a symbolic link produced an intermediate result with a length that exceeds {PATH_MAX}. 84 | > [ENFILE] 85 | > Too many files are currently open in the system. 86 | 87 | -------------------------------------------------------------------------------- /fs_spec/src/README: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | The core spec is written in Lem with CPPO preprocessing. 4 | This consists of the following files: 5 | 6 | t_fs_init.lem 7 | t_fs_prelude.lem t_list_array.lem 8 | t_fs_spec.lem_cppo 9 | t_dir_heap.lem_cppo 10 | 11 | The files in the second line depend on the file in the first line; 12 | t_fs_spec.lem depends on the previous files and t_dir_heap on all. 13 | Files with the ending cppo need preprocessing via cppo. This preprocessing 14 | is able to include or exclude aspects of the specification like permissions 15 | or timing. 16 | 17 | There are also files stating high-level properties of the specification: 18 | 19 | t_fs_spec_errors_raised.lem_cppo 20 | t_fs_spec_properties.lem 21 | t_fs_spec_properties_perms.lem_cppo 22 | 23 | Lem is used to generate Ocaml, Isabelle/HOL and HOL4 output from the model. 24 | 25 | # Generating Output 26 | 27 | Gnu make is used to generate the various output formats from Lem. 28 | 29 | ## OCaml 30 | Run `make lem_ocaml` to generate OCaml output. Afterwards, check the output and 31 | if it is OK, run `make copy_lem_over_ml` to make it productive. 32 | 33 | ## Isabelle/HOL 34 | Run `make lem_isa` to generate Isabelle output. Afterwards, check the output and 35 | if it is OK, run `make lem_isa_copy` to make it productive. 36 | 37 | ## HOL 38 | Run `make lem_hol` to generate HOL4 output 39 | 40 | ## Lem 41 | All other targets generate Lem code automatically. In order to only run cppo and 42 | generate Lem-code execute `make only_lem`. 43 | 44 | ## Aspects 45 | By default, all aspects are turned on. The variable `CPPO_ARGS` can be used to set 46 | the aspects. As an example, the following calls of `lem_ocaml` might be useful. The variable 47 | works for Isabelle and HOL as well, though. 48 | 49 | make lem_ocaml # all aspects 50 | make CPPO_ARGS="-D aspect_perms" lem_ocaml # use aspect "aspect_perms" 51 | make CPPO_ARGS="-U aspect_perms" lem_ocaml # don't use aspect "aspect_perms" 52 | 53 | in combination with `lem_only` the command cppo argument `-n` might be useful as well. It turns off 54 | source annotations and is therefore suitable when looking at the resulting Lem code without the connection 55 | to its source. 56 | 57 | 58 | # OCaml harness 59 | The OCaml output is currently then renamed e.g. t_fs_init.ml is 60 | renamed to fs_init.ml 61 | 62 | The .ml files use the Lem-generated OCaml files. For example 63 | 64 | fs_spec_extras.ml 65 | 66 | is a wrapper around these files. 67 | 68 | Parsing and pretty-printing support for operations: 69 | 70 | fs_parser.ml fs_printer.ml 71 | 72 | Other support libraries: 73 | 74 | tr_base64.ml tr_file.ml tr_list.ml tr_stream.ml 75 | 76 | Files related to interfacing the spec with the underlying unix 77 | filesystem: 78 | 79 | unix_impl.ml unix_impl_readonly.ml 80 | dynarray.ml 81 | 82 | To see the dependencies between files, type: make .depend 83 | 84 | There are also two subdirectories: 85 | 86 | posix - commented posix definitions 87 | 88 | tr - "traces" of behaviour to illustrate why the specification is 89 | how it is 90 | 91 | 92 | # Interactive use 93 | 94 | If you have installed from source, you may be able to interactively 95 | load the modules in an OCaml top-level. 96 | 97 | * Build the .ml files from the Lem sources. 98 | 99 | * Start an ocaml session. 100 | 101 | * Look at the instructions in the file `.interactive` -------------------------------------------------------------------------------- /fs_test/lib/fs_test_system.mli: -------------------------------------------------------------------------------- 1 | (****************************************************************************) 2 | (* Copyright (c) 2013, 2014, 2015, Tom Ridge, David Sheets, Thomas Tuerk, *) 3 | (* Andrea Giugliano (as part of the SibylFS project) *) 4 | (* *) 5 | (* Permission to use, copy, modify, and/or distribute this software for *) 6 | (* any purpose with or without fee is hereby granted, provided that the *) 7 | (* above copyright notice and this permission notice appear in all *) 8 | (* copies. *) 9 | (* *) 10 | (* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL *) 11 | (* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED *) 12 | (* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE *) 13 | (* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL *) 14 | (* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR *) 15 | (* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER *) 16 | (* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR *) 17 | (* PERFORMANCE OF THIS SOFTWARE. *) 18 | (* *) 19 | (* Meta: *) 20 | (* - Headers maintained using headache. *) 21 | (* - License source: http://opensource.org/licenses/ISC *) 22 | (****************************************************************************) 23 | 24 | exception Command_failure of string * string * string 25 | 26 | type process = { 27 | pid : int; 28 | stdout : Unix.file_descr; 29 | stdin : Unix.file_descr; 30 | stderr : Unix.file_descr; 31 | } 32 | 33 | val all : string -> string 34 | val megs : int -> int64 35 | 36 | val string_of_exec_args : string -> string array -> string 37 | 38 | val string_of_signal : int -> string 39 | val string_of_status : Unix.process_status -> string 40 | val ignore_failure : (unit -> unit) -> unit -> unit 41 | 42 | val subproc : chdir:string -> string -> string array -> unit 43 | 44 | val continue : string -> string array -> unit 45 | val exit_command : string -> string array -> 'a -> (int -> 'a option) -> 'a 46 | 47 | val read_command : 48 | ?exit_code:int -> ?env:string array -> string -> string list 49 | val read_command_err : 50 | ?exit_code:int -> ?env:string array -> string -> string list 51 | 52 | val create_process_exec_args : string -> string array -> string array -> process 53 | 54 | val create_process : string -> string array -> string array -> process 55 | 56 | val read_into_buf : ?block:bool -> Unix.file_descr -> Buffer.t -> int 57 | 58 | val drain_into_buf : Unix.file_descr -> Buffer.t -> int 59 | 60 | val waitpid : Unix.wait_flag list -> int -> int * Unix.process_status 61 | 62 | val tee : 63 | ?quiet:bool -> ?no_stderr:bool -> ?errfile:string -> process -> string -> int 64 | 65 | val kill_children : unit -> unit 66 | 67 | val get_system : unit -> Fs_test_config.Os.t 68 | 69 | val create_new_user : unit -> int * string 70 | 71 | val delete_user : ?force:bool -> string -> unit 72 | 73 | val create_new_group : unit -> int * string 74 | 75 | val delete_group : ?force:bool -> string -> unit 76 | 77 | val put_user_in_group : string -> string -> unit 78 | --------------------------------------------------------------------------------