| author | wenzelm | 
| Sat, 22 Oct 2011 23:28:24 +0200 | |
| changeset 45248 | 3b7b64b194ee | 
| parent 45199 | 42316b81ef49 | 
| child 46502 | 3d43d4d4d071 | 
| permissions | -rw-r--r-- | 
| 40743 | 1 | (* Title: Pure/System/isabelle_system.ML | 
| 2 | Author: Makarius | |
| 3 | ||
| 4 | Isabelle system support. | |
| 5 | *) | |
| 6 | ||
| 7 | signature ISABELLE_SYSTEM = | |
| 8 | sig | |
| 9 | val isabelle_tool: string -> string -> int | |
| 10 | val mkdirs: Path.T -> unit | |
| 40745 | 11 | val mkdir: Path.T -> unit | 
| 40743 | 12 | val copy_dir: Path.T -> Path.T -> unit | 
| 42127 
8223e7f4b0da
Isabelle_System.create_tmp_path/with_tmp_file: optional extension;
 wenzelm parents: 
41944diff
changeset | 13 | val create_tmp_path: string -> string -> Path.T | 
| 
8223e7f4b0da
Isabelle_System.create_tmp_path/with_tmp_file: optional extension;
 wenzelm parents: 
41944diff
changeset | 14 | val with_tmp_file: string -> string -> (Path.T -> 'a) -> 'a | 
| 41307 
bb8468ae414e
slightly more standard Isabelle_System.with_tmp_file/with_tmp_dir (cf. Scala version);
 wenzelm parents: 
40785diff
changeset | 15 | val with_tmp_dir: string -> (Path.T -> 'a) -> 'a | 
| 43849 
00f4b305687d
access to process output stream via auxiliary fifo;
 wenzelm parents: 
43606diff
changeset | 16 | val with_tmp_fifo: (Path.T -> 'a) -> 'a | 
| 43851 | 17 | val bash_output_fifo: string -> (Path.T -> 'a) -> 'a | 
| 43850 
7f2cbc713344
moved bash operations to Isabelle_System (cf. Scala version);
 wenzelm parents: 
43849diff
changeset | 18 | val bash_output: string -> string * int | 
| 
7f2cbc713344
moved bash operations to Isabelle_System (cf. Scala version);
 wenzelm parents: 
43849diff
changeset | 19 | val bash: string -> int | 
| 40743 | 20 | end; | 
| 21 | ||
| 22 | structure Isabelle_System: ISABELLE_SYSTEM = | |
| 23 | struct | |
| 24 | ||
| 43850 
7f2cbc713344
moved bash operations to Isabelle_System (cf. Scala version);
 wenzelm parents: 
43849diff
changeset | 25 | (* bash *) | 
| 
7f2cbc713344
moved bash operations to Isabelle_System (cf. Scala version);
 wenzelm parents: 
43849diff
changeset | 26 | |
| 
7f2cbc713344
moved bash operations to Isabelle_System (cf. Scala version);
 wenzelm parents: 
43849diff
changeset | 27 | fun bash_output s = | 
| 
7f2cbc713344
moved bash operations to Isabelle_System (cf. Scala version);
 wenzelm parents: 
43849diff
changeset | 28 |   let val {output, rc, ...} = Bash.process s
 | 
| 
7f2cbc713344
moved bash operations to Isabelle_System (cf. Scala version);
 wenzelm parents: 
43849diff
changeset | 29 | in (output, rc) end; | 
| 
7f2cbc713344
moved bash operations to Isabelle_System (cf. Scala version);
 wenzelm parents: 
43849diff
changeset | 30 | |
| 
7f2cbc713344
moved bash operations to Isabelle_System (cf. Scala version);
 wenzelm parents: 
43849diff
changeset | 31 | fun bash s = | 
| 
7f2cbc713344
moved bash operations to Isabelle_System (cf. Scala version);
 wenzelm parents: 
43849diff
changeset | 32 | (case bash_output s of | 
| 
7f2cbc713344
moved bash operations to Isabelle_System (cf. Scala version);
 wenzelm parents: 
43849diff
changeset | 33 |     ("", rc) => rc
 | 
| 
7f2cbc713344
moved bash operations to Isabelle_System (cf. Scala version);
 wenzelm parents: 
43849diff
changeset | 34 | | (out, rc) => (writeln (perhaps (try (unsuffix "\n")) out); rc)); | 
| 
7f2cbc713344
moved bash operations to Isabelle_System (cf. Scala version);
 wenzelm parents: 
43849diff
changeset | 35 | |
| 
7f2cbc713344
moved bash operations to Isabelle_System (cf. Scala version);
 wenzelm parents: 
43849diff
changeset | 36 | |
| 40743 | 37 | (* system commands *) | 
| 38 | ||
| 39 | fun isabelle_tool name args = | |
| 40 | (case space_explode ":" (getenv "ISABELLE_TOOLS") |> get_first (fn dir => | |
| 43606 | 41 | let val path = File.platform_path (Path.append (Path.explode dir) (Path.basic name)) in | 
| 40743 | 42 | if can OS.FileSys.modTime path andalso | 
| 43 | not (OS.FileSys.isDir path) andalso | |
| 44 | OS.FileSys.access (path, [OS.FileSys.A_READ, OS.FileSys.A_EXEC]) | |
| 45 | then SOME path | |
| 46 | else NONE | |
| 47 | end handle OS.SysErr _ => NONE) of | |
| 48 | SOME path => bash (File.shell_quote path ^ " " ^ args) | |
| 49 |   | NONE => (writeln ("Unknown Isabelle tool: " ^ name); 2));
 | |
| 50 | ||
| 51 | fun system_command cmd = | |
| 52 |   if bash cmd <> 0 then error ("System command failed: " ^ cmd)
 | |
| 53 | else (); | |
| 54 | ||
| 55 | ||
| 56 | (* directory operations *) | |
| 57 | ||
| 58 | fun mkdirs path = system_command ("mkdir -p " ^ File.shell_path path);
 | |
| 59 | ||
| 40785 | 60 | fun mkdir path = | 
| 61 | if File.is_dir path then () else OS.FileSys.mkDir (File.platform_path path); | |
| 40743 | 62 | |
| 63 | fun copy_dir src dst = | |
| 64 | if File.eq (src, dst) then () | |
| 65 |   else (system_command ("cp -r -f " ^ File.shell_path src ^ "/. " ^ File.shell_path dst); ());
 | |
| 66 | ||
| 41307 
bb8468ae414e
slightly more standard Isabelle_System.with_tmp_file/with_tmp_dir (cf. Scala version);
 wenzelm parents: 
40785diff
changeset | 67 | |
| 
bb8468ae414e
slightly more standard Isabelle_System.with_tmp_file/with_tmp_dir (cf. Scala version);
 wenzelm parents: 
40785diff
changeset | 68 | (* unique tmp files *) | 
| 
bb8468ae414e
slightly more standard Isabelle_System.with_tmp_file/with_tmp_dir (cf. Scala version);
 wenzelm parents: 
40785diff
changeset | 69 | |
| 42127 
8223e7f4b0da
Isabelle_System.create_tmp_path/with_tmp_file: optional extension;
 wenzelm parents: 
41944diff
changeset | 70 | fun create_tmp_path name ext = | 
| 41307 
bb8468ae414e
slightly more standard Isabelle_System.with_tmp_file/with_tmp_dir (cf. Scala version);
 wenzelm parents: 
40785diff
changeset | 71 | let | 
| 42127 
8223e7f4b0da
Isabelle_System.create_tmp_path/with_tmp_file: optional extension;
 wenzelm parents: 
41944diff
changeset | 72 | val path = File.tmp_path (Path.basic (name ^ serial_string ()) |> Path.ext ext); | 
| 41307 
bb8468ae414e
slightly more standard Isabelle_System.with_tmp_file/with_tmp_dir (cf. Scala version);
 wenzelm parents: 
40785diff
changeset | 73 | val _ = File.exists path andalso | 
| 41944 
b97091ae583a
Path.print is the official way to show file-system paths to users -- note that Path.implode often indicates violation of the abstract datatype;
 wenzelm parents: 
41352diff
changeset | 74 |       raise Fail ("Temporary file already exists: " ^ Path.print path);
 | 
| 41307 
bb8468ae414e
slightly more standard Isabelle_System.with_tmp_file/with_tmp_dir (cf. Scala version);
 wenzelm parents: 
40785diff
changeset | 75 | in path end; | 
| 
bb8468ae414e
slightly more standard Isabelle_System.with_tmp_file/with_tmp_dir (cf. Scala version);
 wenzelm parents: 
40785diff
changeset | 76 | |
| 42127 
8223e7f4b0da
Isabelle_System.create_tmp_path/with_tmp_file: optional extension;
 wenzelm parents: 
41944diff
changeset | 77 | fun with_tmp_file name ext f = | 
| 
8223e7f4b0da
Isabelle_System.create_tmp_path/with_tmp_file: optional extension;
 wenzelm parents: 
41944diff
changeset | 78 | let val path = create_tmp_path name ext | 
| 
8223e7f4b0da
Isabelle_System.create_tmp_path/with_tmp_file: optional extension;
 wenzelm parents: 
41944diff
changeset | 79 | in Exn.release (Exn.capture f path before ignore (try File.rm path)) end; | 
| 41307 
bb8468ae414e
slightly more standard Isabelle_System.with_tmp_file/with_tmp_dir (cf. Scala version);
 wenzelm parents: 
40785diff
changeset | 80 | |
| 42127 
8223e7f4b0da
Isabelle_System.create_tmp_path/with_tmp_file: optional extension;
 wenzelm parents: 
41944diff
changeset | 81 | fun rm_tree path = system_command ("rm -r -f " ^ File.shell_path path);
 | 
| 41307 
bb8468ae414e
slightly more standard Isabelle_System.with_tmp_file/with_tmp_dir (cf. Scala version);
 wenzelm parents: 
40785diff
changeset | 82 | |
| 
bb8468ae414e
slightly more standard Isabelle_System.with_tmp_file/with_tmp_dir (cf. Scala version);
 wenzelm parents: 
40785diff
changeset | 83 | fun with_tmp_dir name f = | 
| 
bb8468ae414e
slightly more standard Isabelle_System.with_tmp_file/with_tmp_dir (cf. Scala version);
 wenzelm parents: 
40785diff
changeset | 84 | let | 
| 42127 
8223e7f4b0da
Isabelle_System.create_tmp_path/with_tmp_file: optional extension;
 wenzelm parents: 
41944diff
changeset | 85 | val path = create_tmp_path name ""; | 
| 41307 
bb8468ae414e
slightly more standard Isabelle_System.with_tmp_file/with_tmp_dir (cf. Scala version);
 wenzelm parents: 
40785diff
changeset | 86 | val _ = mkdirs path; | 
| 41352 
87adb55fb0fb
make SML/NJ and Poly/ML agree on the type of "before";
 wenzelm parents: 
41307diff
changeset | 87 | in Exn.release (Exn.capture f path before ignore (try rm_tree path)) end; | 
| 41307 
bb8468ae414e
slightly more standard Isabelle_System.with_tmp_file/with_tmp_dir (cf. Scala version);
 wenzelm parents: 
40785diff
changeset | 88 | |
| 43850 
7f2cbc713344
moved bash operations to Isabelle_System (cf. Scala version);
 wenzelm parents: 
43849diff
changeset | 89 | |
| 43851 | 90 | (* fifo *) | 
| 43850 
7f2cbc713344
moved bash operations to Isabelle_System (cf. Scala version);
 wenzelm parents: 
43849diff
changeset | 91 | |
| 43849 
00f4b305687d
access to process output stream via auxiliary fifo;
 wenzelm parents: 
43606diff
changeset | 92 | fun with_tmp_fifo f = | 
| 
00f4b305687d
access to process output stream via auxiliary fifo;
 wenzelm parents: 
43606diff
changeset | 93 | with_tmp_file "isabelle-fifo-" "" | 
| 
00f4b305687d
access to process output stream via auxiliary fifo;
 wenzelm parents: 
43606diff
changeset | 94 | (fn path => | 
| 
00f4b305687d
access to process output stream via auxiliary fifo;
 wenzelm parents: 
43606diff
changeset | 95 |       (case bash_output ("mkfifo -m 600 " ^ File.shell_path path) of
 | 
| 
00f4b305687d
access to process output stream via auxiliary fifo;
 wenzelm parents: 
43606diff
changeset | 96 | (_, 0) => f path | 
| 
00f4b305687d
access to process output stream via auxiliary fifo;
 wenzelm parents: 
43606diff
changeset | 97 | | (out, _) => error (perhaps (try (unsuffix "\n")) out))); | 
| 
00f4b305687d
access to process output stream via auxiliary fifo;
 wenzelm parents: 
43606diff
changeset | 98 | |
| 45199 | 99 | (* FIXME blocks on Cygwin 1.7.x *) | 
| 100 | (* See also http://cygwin.com/ml/cygwin/2010-08/msg00459.html *) | |
| 101 | fun bash_output_fifo script f = | |
| 43849 
00f4b305687d
access to process output stream via auxiliary fifo;
 wenzelm parents: 
43606diff
changeset | 102 | with_tmp_fifo (fn fifo => | 
| 
00f4b305687d
access to process output stream via auxiliary fifo;
 wenzelm parents: 
43606diff
changeset | 103 | uninterruptible (fn restore_attributes => fn () => | 
| 43850 
7f2cbc713344
moved bash operations to Isabelle_System (cf. Scala version);
 wenzelm parents: 
43849diff
changeset | 104 | (case Bash.process (script ^ " > " ^ File.shell_path fifo ^ " &") of | 
| 43849 
00f4b305687d
access to process output stream via auxiliary fifo;
 wenzelm parents: 
43606diff
changeset | 105 |         {rc = 0, terminate, ...} =>
 | 
| 43851 | 106 | (restore_attributes f fifo handle exn => (terminate (); reraise exn)) | 
| 43849 
00f4b305687d
access to process output stream via auxiliary fifo;
 wenzelm parents: 
43606diff
changeset | 107 |       | {output, ...} => error (perhaps (try (unsuffix "\n")) output))) ());
 | 
| 
00f4b305687d
access to process output stream via auxiliary fifo;
 wenzelm parents: 
43606diff
changeset | 108 | |
| 40743 | 109 | end; | 
| 110 |