Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

micro does not die when killing crontab and using micro as editor #2085

Open
EnderCrypt opened this issue Apr 17, 2021 · 3 comments
Open

micro does not die when killing crontab and using micro as editor #2085

EnderCrypt opened this issue Apr 17, 2021 · 3 comments

Comments

@EnderCrypt
Copy link

launching crontab with micro as editor, and then killing crontab (the entire terminal) causes micro to stay alive (other editors like vim does not exhibit this behaviour) and micro goes from eating ~0% cpu to eating ~40% cpu forever untill killed
sending a SIGTERM to the process does NOT kill it, but does cause it to drop its cpu usage from ~40% to ~13%
sending a SIGKILL does kill it as expected

how to reproduce

  1. open a GNU/Linux terminal of choice (i use konsole)
  2. execute EDITOR=`which micro` crontab -e
  3. kill the terminal by clicking the [x] (i used xkill instead)
  4. open a process monitorer (i use KSysGuard) and sort processes by cpu usage

Specifications

Version: 2.0.8
Commit hash: cfcb2e4
Compiled on February 21, 2021

OS: 5.9.16-1-MANJARO
Terminal: konsole (with zsh)

@dmaluka
Copy link
Collaborator

dmaluka commented Jun 18, 2024

AFAICS 0851499 did not fully fix this issue. Micro process indeed now exits if we kill crontab by closing the terminal window, but:

  • It doesn't exit if we kill crontab via killall crontab.
  • It doesn't exit by closing the terminal window if it is running a shell job e.g. via RunInteractiveShell().

@niten94
Copy link
Contributor

niten94 commented Jun 21, 2024

It doesn't exit if we kill crontab via killall crontab.

I tried searching a bit but I think errno is set as EIO when reading terminal input in background processes in POSIX. The error that would be set in errno in C is returned when calling Screen.PollEvent so I think it can be checked if event.(*tcell.EventError).Err() is *os.SyscallError. It is only printed in DoEvent in cmd/micro/micro.go so micro does not exit when it is in the background:

micro/cmd/micro/micro.go

Lines 453 to 470 in 0fa4a3a

if e, ok := event.(*tcell.EventError); ok {
log.Println("tcell event error: ", e.Error())
if e.Err() == io.EOF {
// shutdown due to terminal closing/becoming inaccessible
for _, b := range buffer.OpenBuffers {
if !b.Modified() {
b.Fini()
}
}
if screen.Screen != nil {
screen.Screen.Fini()
}
os.Exit(0)
}
return
}

It doesn't exit by closing the terminal window if it is running a shell job e.g. via RunInteractiveShell().

I was testing a bit but micro seems to hang when terminal is closed and Screen.Show is called in DoEvent. SIGHUP is received when the terminal is closed so I think checking if signals are received before the screen is displayed can be done. The signal can be ignored in programs that are run so I think functions in internal/shell like RunInteractiveShell would have to return when it is received.

@dmaluka
Copy link
Collaborator

dmaluka commented Jun 22, 2024

This is what nano does in this case:

		/* When we've failed to get a keycode millions of times in a row,
		 * assume our input source is gone and die gracefully.  We could
		 * check if errno is set to EIO ("Input/output error") and die in
		 * that case, but it's not always set properly.  Argh. */
		if (input == ERR && ++errcount == 12345678)
			die(_("Too many errors from stdin\n"));

This is how it looks like:

Too many errors from stdin

Buffer written to /tmp/crontab.x0ZKs2/crontab.save

So among other things, nano indeed dies gracefully (unlike micro), saving the modified buffer to a backup file.

Vim also behaves similarly:

Vim: Error reading input, exiting...
Vim: Finished.

Looks like this is where vim does that:

	if (wtime == -1 && ++count == 1000)
	    read_error_exit();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants