kareman / SwiftShell

A Swift framework for shell scripting.
https://kareman.github.io/SwiftShell
MIT License
1.03k stars 87 forks source link

Mark the AsyncCommand stop() function as unavailable on linux and set… #60

Closed Ponyboy47 closed 6 years ago

Ponyboy47 commented 6 years ago

… up a test for it on macOS

Unfortunately the @available attribute doesn't actually have a Linux qualifier. So I had to mix it in with compiler flags.

Should resolve #59 though.

Ponyboy47 commented 6 years ago

The 2nd commit is not necessary to fix #59, but I figured that since it was easy enough, why not add all the signal functions that are available to Process to the AsyncCommand?

It gives people more control (at least on macOS). Since I don't use the functionality and don't have any plans to use it, feel free to reject the 2nd commit.

Ponyboy47 commented 6 years ago

FYI - Implementing the stop and interrupt functions on linux using the C kill function is trivial since the AsyncCommand process stores its PID. (I have a commit ready to push that implements those functions on Linux and it passes the same tests that would be running on macOS)

kareman commented 6 years ago

If you can get these functions to work on Linux that is even better. Do you think suspend and resume can be implemented too?

Ponyboy47 commented 6 years ago

I'm still looking into the suspend and resume functions.

The Apple documentation for terminate and interrupt state that they're just sending SIGTERM and SIGINT, so those were easy.

They do mention that it is not always possible to terminate/interrupt using those functions, so they must be using some utility (I'm assuming sigprocmask and sigismember) to check if the process is blocking those signals before sending them (because blocked signals really just end up queued until they're unblocked). I currently don't have this functionality in my branch yet, but will work to add it.

I suspect that suspend and resume just send SIGSTOP and SIGCONT, although I'm not sure if that's really what Apple is doing for them since they don't mention anything about that on their documentation for suspend or resume.

Ponyboy47 commented 6 years ago

So I got the functionality all implemented to mimic what Apple does on their platforms. Unfortunately, I couldn't use the sigprocmask or sigismember APIs since those only work for the current process, and getting information about the swift process isn't helpful...

I ended up using the ps utility that's installed on every linux bistro by default, so it works, but it's not as nice as I'd hoped for.

I also couldn't reliably test the suspend/resume functions by checking .isRunning and I had some ideas about using the ps utility to check if it's really running, but realized it would get incredibly complicated if I wanted to check it against processes that forked. So I just didn't include any test for suspend/resume.

kareman commented 6 years ago

This is awesome! Thank you very much.

Have you considered adding this code to the Swift Foundation project itself?

Ponyboy47 commented 6 years ago

I hadn't considered it, but maybe I'll look into it! It's pretty annoying that the functionality hasn't been implemented yet. I wish I could see how they do it on macOS so I could really match what they do.

I didn't like doing it the way that I did, but the only way to get the process information directly through C APIs would require installing a dev version of the ps utility which includes the header files that I could then expose to swift :/