How to terminate (SIGINT) a subprocess in Haskell? - unix

I'm writing a small program in Haskell which manipulates the commands arecordmidi and aplaymidi to record short improvisations on my digital piano through MIDI. I will press the R key, my program will create a new subprocess with the command arecordmidi. When I press R again, I want my recording to stop, by terminating the command arecordmidi.
How do I terminate the arecordmidi subprocess? If in a shell, CTRL+C would stop recording. This is what I want.
I'm using the following code to create the subprocess:
import System.Process
main = do
let rec_command = "arecordmidi -p \"CASIO USB-MIDI\" myRecording.midi"
process <- createProcess (shell rec_command)
-- I could try the following code, but the documentation of System.Process
-- says it's bad to use terminateProcess:
let (_, _, _, processHandle) = process
terminateProcess processHandle

terminateProcess sends a SIGTERM (terminate) signal to the process, which corresponds to the default behavior of the unix command kill, which generally is not what you want when trying to end a process nicely.
Ctrl+C sends the signal SIGINT (interrupt), which many applications handle by an orderly shutdown, and in your case probably results in the arecordmidi process saving outstanding data, and closing any pipes and files.
Looks like the way to send SIGINT with System.Process is with interruptProcessGroupOf.

Related

Is there any command line tool to script tcp sockets

I'm playing around with building a MPD client for my private use and came across the following problem.
I need to (from a /bin/sh script):
send a command over tcp to the sever
wait for an OK on a line of its own
send a close command to the server to clean up the connection
Is there any command line tool I can use to do this (I could code it in C/Java/Python but would prefer not to introduce the dependency)
I have tried netcat but am unable to do step 2, which leads to me losing parts of the response from 1 as the connection is closed before the output is sent.
What I tried that did not work all the time was.
printf 'command_list_ok_begin\nnext\nstatus\nplaylistinfo\ncommand_list_end\nclose\n'|nc -w 5 $mpdhost 6600 #

How to stop TCP server in Julia?

TCP example
#async begin
server = listen(2000)
while true
sock = accept(server)
println("Hello World\n")
end
end
To close the connection, you need to call the close method:
close(sock)
How to stop the listener?
close(server) #LoadError: accept: software caused connection abort (ECONNABORTED)
Rather than keep commenting, here's what I think you were probably trying to do:
From the julia REPL:
julia> server = listen(2000)
Base.TCPServer(active)
julia> #async begin
while true
sock = accept(server)
print(readstring(sock))
end
end
From another terminal:
~ $ nc localhost 2000
Hello from the other terminal
[Ctrl-D] % i.e. signal end of file. this closes the connection
In the julia repl, you'll see "Hello from the other terminal" printed as soon as you send the EOF signal, but otherwise the julia prompt will continue as normal. If you repeat this process from the netcat terminal you'll see the message printed in the REPL again, because the socket keeps reactivating inside the while loop.
Ideally if you wanted to shut the whole thing down, you would first close(sock) and then close(server). But, you can't close the socket directly, because it's in the "while" loop and it keeps getting reactivated, and you don't have direct access to the variable "sock".
Therefore you can only close the server, fully expecting an error. So catch it in a try block instead
EDIT: sorry, my bad, the exception relates to the socket, not the server, so you need to wrap that in a try catch block inside your async block instead:
#async begin
while true
try
sock = accept(server)
print(readstring(sock))
catch ex
print("exiting while loop")
break
end
end
end

Weird delay when using "tail -f" command

To monitor a log file I have to connect to an ssh connection and redirect the output of the log file(let's call it RemoteLog.txt) out to a local machine so it can be read by a java program and put on a GUI.
Right now I have the output redirected out of the ssh connection and onto the local machine with the command:
ssh remote#ip.address tail logs/RemoteLog.txt -f > ~/Log/LocalLog.txt
and everything works fine technically with one exception: for some reason LocalLog.txt only gets updated with the changes to RemoteLog.txt every 35 seconds to the millisecond.
It doesn't matter the number of changes to RemoteLog, the number of lines specified with the tail command, or using the >> operator vs the > operator; there is always a 35 second delay between updates of LocalLog.txt while RemoteLog is constantly updating.
Does anyone have any clue why this might be?

How to get R to save its state when killed?

I would like to assign some code that will be run when R is killed, for instance, save(list=ls(),file="dump.RData"). I thought this would be by trapping signals, e.g. SIGTERM, as referred to in this post, but there's nothing about signals from the shell in ?conditions.
?conditions does mention user interrupts; you can e.g. catch a Ctrl-C with withCallingHandlers( Sys.sleep(10), interrupt=function (e){cat("I saw that.\n")} ), but this doesn't catch SIGTERM.
How can I do this?
Indeed if you send SIGUSR1 to an R process, it will dump the workspace and stop. On Linux you can do that with
kill -USR1 Rpid
where Rpid is the process id of the R instance you want to stop. You can find it with pgrep for instance.
If R is running in a terminal, you can interrupt it with CTRL-Z and then type
kill -USR1 %

how to redirect the output of serial console (e.g. /dev/ttyS0) to a buffer or file

Is it possible to pipe serial console output to a file or a buffer or some virtual or pseudo device (in /dev)?
The Kernel command line has in startup at this point "console=null,115200".
(Normally it has "console=ttyS0,115200" - my requirement is: if "console=null,115200", should the output go to some other place than ttyS0, e.g. a virtual or pseudo device or to a file/buffer)
Maybe somebody know if there is good solution available?
Thanks a lot in advance!
There are two ways that I am aware of :-
First way :-
get ttylog from sourceforge :-
http://sourceforge.net/projects/ttylog/files/latest/download
Fire the below command:-
nohup ttylog -b 115200 -d /dev/ttyS0 > log.txt
this will then show you the PID of the process that is running, you now need to disown that PID so it doesn't get killed when you log out. Note that 115200 is the serial port speed/baud rate you configured grub for on the box you are monitoring.
Second way :-
Setup a serial console from system under test to some other linux/windows box. In case of linux install minicom and set minicom to listen on the serial port define in grub of system under test. Save that as dfl. You are good to go for more info :-
https://www.kernel.org/doc/Documentation/serial-console.txt

Resources