How catch ctrl-c in lua when ctrl-c is sent via the command line
Asked Answered
N

4

17

I would like to know when the user from a command line presses control-c so I can save some stuff.

How do I do this? I've looked but haven't really seen anything.

Note: I'm somewhat familiar with lua, but I'm no expert. I mostly use lua to use the library Torch (http://torch.ch/)

N answered 1/9, 2015 at 17:27 Comment(5)
Ctrl-C is catchable with pcallDissolve
Unfortunately, on LuaJIT Ctrl-C is not catchable with pcall.Dissolve
How exactly do you catch it with pcall? pcall(io.read()) won't catch double ctrl-c, only ctrl-c+enter.Angi
@KarlP - lua -e"print(pcall(io.read))" is interrupted by Ctrl-C without pressing Enter. Describe your testing method.Dissolve
@EgorSkriptunoff depends on the underlying libc I guess. OpenWrt/uclibc you need the enter, desktop linux you don't.Angi
O
12

Implementing a SIGINT handler is straightforward using the excellent luaposix library:

local signal = require("posix.signal")

signal.signal(signal.SIGINT, function(signum)
  io.write("\n")
  -- put code to save some stuff here
  os.exit(128 + signum)
end)

Refer to the posix.signal module's API documentation for more information.

Odell answered 22/12, 2015 at 5:52 Comment(0)
N
2

There exists io libraries that support this. I know zmq and libuv

Libuv example with lluv binding - https://github.com/moteus/lua-lluv/blob/master/examples/sig.lua

ZeroMQ return EINTR from poll function when user press Ctrl-C

But I do not handle thi byself

Neology answered 9/9, 2015 at 5:54 Comment(0)
B
1

windows : SetConsoleCtrlHandler

linux : signal

There are two behaviors of the signal which are undesirable, which will cause complexities in the code.

  1. Program termination
  2. Broken IO

The first behavior can be caught and remembered in a C program by using SetConsoleCtrlHandler/signal. This will allow your function to be called, and you can remember that the system needs to shutdown. Then at some point in the lua code you see it has happened (call to check), and perform your tidy up and shutdown.

The second behavior, is that a blocking operation (read/write) will be cancelled by the signal, and the operation will be unfinished. That would need to be checked at each IO event, and then re-started, or cancelled as appropriate.

Balalaika answered 5/9, 2015 at 4:50 Comment(3)
Any practical example?Mullen
Blocking operations are EINTR'ed on any signal, not just SIGINT (that is sent to process by terminal on C-c). But this only happens if SA_RESTART was not set when installing a new signal handler.Teena
Writing a signal handler in a low-level programming language like C or C++ is not an appropriate solution for just catching Ctrl+C in an application written in Lua. If everyone had to do that, we would end up with 10000 slightly different implementations. Handling the low-level stuff is the job of a library, not the application.Edgeworth
H
-2
require('sys')
sys.catch_ctrl_c()

I use this to catch the exit from cli.

Hedges answered 16/9, 2015 at 2:51 Comment(1)
I'm getting stdin:1: module 'sys' not found: ... if I try this at either the Lua or LuaJIT CLI.Pinnatifid

© 2022 - 2024 — McMap. All rights reserved.