alexherbo2 / kakoune.cr

A command-line tool for Kakoune
https://kakoune.org
The Unlicense
54 stars 11 forks source link

kcr shell --session ends with exception on mac #12

Closed vbauerster closed 3 years ago

vbauerster commented 3 years ago

Invoking kcr shell --session test on mac raises exception:

Create the session: test
Unhandled exception: Error executing process: 'setsid': No such file or directory (File::NotFoundError)
  from /usr/local/Cellar/crystal/1.0.0/src/crystal/system/unix/process.cr:225:34 in 'raise_exception_from_errno'
  from /usr/local/Cellar/crystal/1.0.0/src/crystal/system/unix/process.cr:156:9 in 'spawn'
  from /usr/local/Cellar/crystal/1.0.0/src/process.cr:230:21 in 'create'
  from .config/kak/plugins/github.com/alexherbo2/kakoune.cr/src/cli.cr:364:9 in 'start'
  from .config/kak/plugins/github.com/alexherbo2/kakoune.cr/src/cli.cr:597:1 in '__crystal_main'
  from /usr/local/Cellar/crystal/1.0.0/src/crystal/main.cr:110:5 in 'main'
alexherbo2 commented 3 years ago

It looks macOS doesn’t have setsid.

alexherbo2 commented 3 years ago

Can you try to create a session named test with the following code:

crystal eval <<EOF
  lib C
    fun setsid
  end

  Process.fork do
    C.setsid
    Process.run("kak", { "-s", "test", "-d" })
  end
EOF

The server should survive closing the terminal.

See C bindings for reference.

vbauerster commented 3 years ago

It looks macOS doesn’t have setsid.

You're right, there is no such executable in mac.

kak -l shows nothing, after invoking the snippet with C bindings.

alexherbo2 commented 3 years ago

According to the manual, the signature for setsid() is:

pid_t setsid(void);

Does it work better if you update with:

lib C
  fun setsid : Int32
end

Try also to replace Process.run with Process.new if it changes something. Normally no, as it runs in the background anyway.

alexherbo2 commented 3 years ago

Apparently, we should double fork to orphan the server, like in fork_server_to_background().

lib C
  fun setsid : Int32
end

class Process
  def self.setsid(command, arguments)
    fork do
      C.setsid

      # Double fork to orphan the server.
      fork do
        new(command, arguments)
      end
    end
  end
end

Process.setsid("kak", { "-s", "test", "-d" })
vbauerster commented 3 years ago

Thank you! I confirm that's been fixed.