From 16a1e5cac427b493dd7a315c70af72136b34515c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=AA=E3=81=A4=E3=81=8D?= Date: Tue, 21 Feb 2023 14:57:03 -0800 Subject: [PATCH] Fix `jekyll serve --detach` with jekyll-sass-converter 3.x (#9304) Merge pull request 9304 --- lib/jekyll/commands/serve.rb | 7 +++++++ test/test_commands_serve.rb | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/lib/jekyll/commands/serve.rb b/lib/jekyll/commands/serve.rb index 4600130f..e54542ff 100644 --- a/lib/jekyll/commands/serve.rb +++ b/lib/jekyll/commands/serve.rb @@ -274,12 +274,19 @@ module Jekyll def boot_or_detach(server, opts) if opts["detach"] pid = Process.fork do + # Detach the process from controlling terminal + $stdin.reopen("/dev/null", "r") + $stdout.reopen("/dev/null", "w") + $stderr.reopen("/dev/null", "w") server.start end Process.detach(pid) Jekyll.logger.info "Server detached with pid '#{pid}'.", "Run `pkill -f jekyll' or `kill -9 #{pid}' to stop the server." + + # Exit without running `at_exit` inherited by the forked process. + Process.exit! 0 else t = Thread.new { server.start } trap("INT") { server.shutdown } diff --git a/test/test_commands_serve.rb b/test/test_commands_serve.rb index fe9d972c..b7828b01 100644 --- a/test/test_commands_serve.rb +++ b/test/test_commands_serve.rb @@ -313,4 +313,36 @@ class TestCommandsServe < JekyllUnitTest @merc.execute(:serve, "watch" => false) end end + + context "using --detach" do + setup do + skip_if_windows "fork is not supported on Windows" + skip("fork is not supported by JRuby") if jruby? + + @temp_dir = Dir.mktmpdir("jekyll_serve_detach_test") + @destination = File.join(@temp_dir, "_site") + Dir.mkdir(@destination) || flunk("Could not make directory #{@destination}") + end + + teardown do + FileUtils.remove_entry_secure(@temp_dir, true) + end + + should "fork into daemon process" do + process, output = Jekyll::Utils::Exec.run("jekyll", "serve", + "--source", @temp_dir, + "--dest", @destination, + "--detach") + + re = %r!Server detached with pid '(?\d+)'! + + assert_match re, output + assert_equal 0, process.exitstatus + + pid = re.match(output)["pid"].to_i + assert pid > 1 + + Process.kill 9, pid + end + end end