Killing a process with swift programmatically - swift

I am trying to find a way to identify and kill specific processes in a Mac Application. Is there a built-in class that has functions that can return the list of running processes? There is one way of running terminal commands using Process() and execute the /usr/bin/killall command to kill processes but I need to do it programmatically as running terminal commands using an application is not a good practice. For example, deleting a file can also be done by running a terminal command using Process() while the better way to do it is using FileManager.default.remomveItem().

If you're looking for an application (rather than a process), then see NSWorkspace.shared.runningApplications. You can call terminate() or forceTerminate() on those elements.
If you want a list of all BSD processes (what you would get from a call to ps for example), that's done with sysctl (the code in the Q&A is in C; you'd have to wrap it to Swift, or rewrite it). I don't believe there's any Cocoa wrapper for that. To kill a process, once you have its PID, use signal, which is what the kill Unix command uses. Typically you want to send SIGTERM, which is a normal shutdown. To force-kill a process, send SIGKILL.

Related

How to make RUST run gracefully in the background and daemonize?

This is what i want to achieve
root> ./webserver start // Does not block the terminal after startup, runs in the background and the process is guarded
root>
My current implementation logic:
Logic running in the background
use std::process::Command;
use std::thread;
use std::env;
use std::time::Duration;
fn main() {
let args: Vec<String> = env::args().collect();
if args.len() == 2 {
if &args[1] == "start" {
// Main process start child process
let child = Command::new(&args[0])
.spawn().expect("Child process failed to start.");
println!("child pid: {}", child.id());
// Main process exit
}
} else {Is there any more elegant approach? Looking forward to your reply
// Main business logic
run webserver
}
}
In this way, rust will run in the background without blocking the terminal, but the information printed by rust in the background will still be displayed on the terminal, and the current rust program will exit when exiting the terminal
Process daemon logic
My idea is to monitor the exit signal of the system and not process the exit request
SIGHUP 1 /* Hangup (POSIX). */
SIGINT 2 /* Interrupt (ANSI). */
SIGQUIT 3 /* Quit (POSIX). */
SIGTERM 15 /* Termination (ANSI). */
code:
use signal_hook::{iterator::Signals, SIGHUP,SIGINT,SIGQUIT,SIGTERM};
use std::{thread, time::Duration};
pub fn process_daemon() {
let signals = match Signals::new(&[SIGHUP,SIGINT,SIGQUIT,SIGTERM]) {
Ok(t) => t,
Err(e) => panic!(e),
};Is there any more elegant approach? Looking forward to your reply
thread::spawn(move || {
for sig in signals.forever() {
println!("Received signal {:?}", sig);
}
});
thread::sleep(Duration::from_secs(2));
}
Is there any more elegant approach? Looking forward to your reply.
TLDR: if you really want your process to act like a service (and never quit), probably do the work to set up a service manager. Otherwise, just let it be a normal process.
Daemonizing a Process
One thing to notice right off the bat is that most of the considerations about daemonizing have nothing to do with Rust as a language and are more about:
The underlying system your processes are targeted for
The exact behavior of your daemon processes once spawned
By looking at your question, it seems you have realized most of this. Unfortunately to properly answer your question we have to delve a bit into the intricacies of processes and how they are managed. It should be noted that existing 'service' managers are a great solution if you are OK with significant platform dependence in your launching infrastructure.
Linux: systemd
FreeBSD: rc
MacOS: launchd
Windows: sc
As you can see, no simple feat if you want to have a simple deployment that just works (provided that it is compiled for the relevant system). These are just the bare metal service managers. If you want to support virtual environments you will have to think about Kubernetes services, dockerizing, etc.
These tools exist because there are many considerations to managing a long-running process on a system:
Should my daemon behave like a service and respawn if killed (or if the system is rebooted)? The tools above will allow for this.
If a service, should my daemon have status states associated with it to help with maintenance? This can help with managing outages and building tooling to scale horizontally.
If the daemon shouldn't be a service (unlikely in your case given your binary's name) there are even more questions: should it be attached to the parent process? Should it be attached to the login process group?
My guess for your process given how complex this can become, simply run the process directly. Don't daemonize at all.
For testing, (if you are in a unix-like environment) you can run your process in the background:
./webserver start &
This will spawn the new process in the background, but attach it to your shell's process list. This can be nice for testing, because if that shell goes away the system will clean up these attached processes along with it.
The above will direct stderr and stdout file descriptors back to your terminal and print them. If you wish to avoid that, you can always redirect the output somewhere else.
Disabling signals to a process like this doesn't seem like the right approach to me. Save these signals to gracefully exit your process once you need to save state or send a termination message to a client. If you do the above, your daemon will only be killable by a kill -9 <pid> or rebooting, or finding some non-standard signal you haven't overridden whose default behavior is to terminate.

Customise debugger stop/restart button behavior

I'm using VS Code to write and debug a C++ program binding to libfuse.
Unfortunately, if you kill a libfuse process with SIGKILL, you then have to use sudo umount -f <mountpoint> before you can start the program again. It's a minor nuisance if I have to do this every time I want to stop or restart debugging, especially as I shouldn't have to authenticate to do such a regular task (the sudo is somehow necessary despite the mount occurring as my user).
While I think this is mainly FUSE's fault (it should gracefully recover from a process being ungracefully killed and unmount automatically instead of leaving the directory saying Transport endpoint is not connected), I also think there should be a way to customise VS Code (or any IDE) to run some clean-up when you want to stop debugging.
I've found that entering -exec signal SIGTERM in the Debug Console will gracefully unmount the directory correctly, stop the process and tell VS Code it's no longer debugging (status bar changes back from orange to blue). But I can't seem to find a way to automate this. I've tried using a .gdbinit file, with some inspiration from this question:
handle SIGTERM nostop
# This doesn't work as hook-quit isn't run when quitting via MI mode, which VS Code uses...
define hook-quit
signal SIGTERM
end
But as noted in the linked question, GDB ignores quit hooks when in MI mode, and VS Code uses MI mode.
The ideal solution for me would be if I could put something in a .vscode configuration file telling it to send -exec signal SIGTERM when I click the stop or restart buttons (and then wait for whatever notification it's getting that debugging has stopped, before restarting if applicable) but I imagine there probably isn't an option for that.
Even if the buttons can't be customised, I'd be happy with the ability to have a keybinding that would just send -exec signal SIGTERM to the Debug Console without me having to open said console and enter the command, though the Command Palette doesn't show anything useful here (nothing that looks like it will send a specified Debug Console command), so I don't expect there's a bindable command for that either.
Does anyone have any suggestions? Or would these belong as feature requests over on the VS Code github? Any way to get GDB to respect its quit hook in MI mode, or to get FUSE to gracefully handle its process being killed would be appreciated too.

(rpi) linux how to kill a process (PiAUISuite) or find the file where the pid is written

I am using a program (PiAUISuite, http://stevenhickson.blogspot.com.es/) that I cannot find how to kill the process. Looking at the code (https://github.com/StevenHickson/PiAUISuite) I can see that it checks if the pid_file is empty or not, so it definitively employs it but I cannot find where is the file. Once the program is running, there's nothing in /var/run (at least that I can see).
Then the question is, how to properly kill a process in linux (raspberry pi, raspbian) when you don't know if the program offers such funcionality. And if you want to kill it through the PID, how to find where the PID_FILE is, provided that it seems that the program uses one?
I use 'sudo killall voicecommand'

How to run a command just after shutdown or halt in Debian?

I'm working with an embedded computer that has a Debian on it. I already manage to run a command just before it has booted and play the "bell" to tell that is ready to work, and for example try to connect to a service.
The problem is that I need to play the bell (or run any command/program) when the system is halted so is safe to un-plug the power. Is there any runscript that run just after halt?
If you have a look in /etc/init.d, you'll see a script called halt. I'm pretty certain that when /sbin/halt is called in a runlevel other than 0 or 6, it calls /sbin/shutdown, which runs this script (unless called with an -n flag). So maybe you could add your own hook into that script? Obviously, it would be before the final halt was called, but nothing runs after that, so maybe that's ok.
Another option would be to use the fact that all running processes get sent a SIGTERM followed (a second or so later) by a SIGKILL. So you could write a simple daemon that just sat there until given a SIGTERM, at which point it went "ping" and died.

Launching matlab remotely on windows via ssh? Impossible?

Howdy, I am trying to run matlab remotely on windows via OpenSSH installed with Cygwin, but launching matlab in windows without the GUI seems to be impossible.
If i am logged in locally, I can launch matlab -nodesktop -nodisplay -r script, and matlab will launch up a stripped down GUI and do the command.
However, this is impossible to do remotely via ssh, as, matlab needs to display the GUI.
Does anyone have any suggestions or work arounds?
Thanks,
Bob
Short story: is your script calling exit()? Are you using "-wait"?
Long story: I think you're fundamentally out of luck if you want to interact with it, but this should work if you just want to batch jobs up. Matlab on Windows is a GUI application, not a console application, and won't interact with character-only remote connectivity. But you can still launch the process. Matlab will actually display the GUI - it will just be in a desktop session on the remote computer that you have no access to. But if you can get it to do your job without further input, this can be made to work, for some value of "work".
Your "-r script" switch is the right direction. But realize that on Windows, Matlab's "-r" behavior is to finish the script and then go back to the GUI, waiting for further input. You need to explicitly include an "exit()" call to get your job to finish, and add try/catches to make sure that exit() gets reached. Also, you should use a "-logfile" switch to capture a copy of all the command window output to a log file so you can see what it's doing (since you can't see the GUI) and have a record of prior runs.
Also, matlab.exe is asynchronous by default. Your ssh call will launch Matlab and return right away unless you add the "-wait" switch. Check the processes on the machine you're sshing to; Matlab may actually be running. Add -wait if you want it to block until finished.
One way to do this stuff just use -r to call to a standard job wrapper script that initializes your libraries and paths, runs a job, and does cleanup and exit. You'll also want to make a .bat wrapper that sets up the -logfile switch to point to a file with the job name, timestamp, and other info in it. Something like this at the M-code level.
function run_batch_job(jobname)
try
init_my_matlab_library(); % By calling classpath(), javaclasspath(), etc
feval(jobname); % assumes jobname is an M-file on the path
catch err
warning('Error occurred while running job %s: %s', jobname, err.message)
end
try
exit();
catch err
% Yes, exit() can throw errors
java.lang.System.exit(1); % Scuttle the process hard to make sure job finishes
end
% If your code makes it to here, your job will hang
I've set up batch job systems using this style in Windows Scheduler, Tidal, and TWS before. I think it should work the same way under ssh or other remote access.
A Matlab batch system on Windows like this is brittle and hard to manage. Matlab on Windows is fundamentally not built to be a headless batch execution system; assumptions about an interactive GUI are pervasive in it and hard to work around. Low-level errors or license errors will pop up modal dialog boxes and hang your job. The Matlab startup sequence seems to have race conditions. You can't set the exit status of MATLAB.exe. There's no way of getting at the Matlab GUI to debug errors the job throws. The log file may be buffered and you lose output near hangs and crashes. And so on.
Seriously consider porting to Linux. Matlab is much more suitable as a batch system there.
If you have the money or spare licenses, you could also use the Matlab Distributed Computing toolbox and server to run code on remote worker nodes. This can work for parallelization or for remote batch jobs.
There are two undocumented hacks that reportedly fix a similar problem - they are not guarantied to solve your particular problem but they are worth a try. Both of them depend on modifying the java.opts file:
-Dsun.java2d.pmoffscreen=false
Setting this option fixes a problem of extreme GUI slowness when launching Matlab on a remote Linux/Solaris computer.
-Djava.compiler=NONE
This option disables the Java just-in-time compiler (JITC). Note that it has no effect on the Matlab interpreter JITC. It has a similar effect to running Matlab with the '–nojvm' command-line option. Note that this prevents many of Matlab's GUI capabilities. Unfortunately, in some cases there is no alternative. For example, when running on a remote console or when running pre-2007 Matlab releases on Intel-based Macs. In such cases, using the undocumented '-noawt' command-line option, which enables the JVM yet prevents JAVA GUI, is a suggested compromise.
Using putty use ssh -X remote "matlab" it should work