src/Pure/System/bash.scala
changeset 73890 8f6b2eb15240
parent 73702 7202e12cb324
child 73895 b709faa96586
equal deleted inserted replaced
73889:5ec68c1a07d8 73890:8f6b2eb15240
    46 
    46 
    47   /* process and result */
    47   /* process and result */
    48 
    48 
    49   type Watchdog = (Time, Process => Boolean)
    49   type Watchdog = (Time, Process => Boolean)
    50 
    50 
       
    51   def process_signal(group_pid: String, signal: String = "0"): Boolean =
       
    52   {
       
    53     val bash =
       
    54       if (Platform.is_windows) List(Isabelle_System.cygwin_root() + "\\bin\\bash.exe")
       
    55       else List("/usr/bin/env", "bash")
       
    56     val (_, rc) =
       
    57       Isabelle_Env.process_output(Isabelle_Env.process(bash ::: List("-c", "kill -" + signal + " -" + group_pid)))
       
    58     rc == 0
       
    59   }
       
    60 
    51   def process(script: String,
    61   def process(script: String,
    52       cwd: JFile = null,
    62       cwd: JFile = null,
    53       env: Map[String, String] = Isabelle_System.settings(),
    63       env: Map[String, String] = Isabelle_System.settings(),
    54       redirect: Boolean = false,
    64       redirect: Boolean = false,
    55       cleanup: () => Unit = () => ()): Process =
    65       cleanup: () => Unit = () => ()): Process =
    78 
    88 
    79     private val script_file: JFile = Isabelle_System.tmp_file("bash_script")
    89     private val script_file: JFile = Isabelle_System.tmp_file("bash_script")
    80     File.write(script_file, winpid_script)
    90     File.write(script_file, winpid_script)
    81 
    91 
    82     private val proc =
    92     private val proc =
    83       Isabelle_System.process(
    93       Isabelle_Env.process(
    84         List(File.platform_path(Path.variable("ISABELLE_BASH_PROCESS")),
    94         List(File.platform_path(Path.variable("ISABELLE_BASH_PROCESS")),
    85           File.standard_path(timing_file), "bash", File.standard_path(script_file)),
    95           File.standard_path(timing_file), "bash", File.standard_path(script_file)),
    86         cwd = cwd, env = env, redirect = redirect)
    96         cwd = cwd, env = env, redirect = redirect)
    87 
    97 
    88 
    98 
   117 
   127 
   118     @tailrec private def signal(s: String, count: Int = 1): Boolean =
   128     @tailrec private def signal(s: String, count: Int = 1): Boolean =
   119     {
   129     {
   120       count <= 0 ||
   130       count <= 0 ||
   121       {
   131       {
   122         Isabelle_System.process_signal(group_pid, signal = s)
   132         process_signal(group_pid, signal = s)
   123         val running = root_process_alive() || Isabelle_System.process_signal(group_pid)
   133         val running = root_process_alive() || process_signal(group_pid)
   124         if (running) {
   134         if (running) {
   125           Time.seconds(0.1).sleep()
   135           Time.seconds(0.1).sleep()
   126           signal(s, count - 1)
   136           signal(s, count - 1)
   127         }
   137         }
   128         else false
   138         else false
   136       do_cleanup()
   146       do_cleanup()
   137     }
   147     }
   138 
   148 
   139     def interrupt(): Unit = Isabelle_Thread.try_uninterruptible
   149     def interrupt(): Unit = Isabelle_Thread.try_uninterruptible
   140     {
   150     {
   141       Isabelle_System.process_signal(group_pid, "INT")
   151       process_signal(group_pid, "INT")
   142     }
   152     }
   143 
   153 
   144 
   154 
   145     // JVM shutdown hook
   155     // JVM shutdown hook
   146 
   156