serenity icon indicating copy to clipboard operation
serenity copied to clipboard

system(3) breaks stdin from the terminal

Open oskar-skog opened this issue 1 year ago • 2 comments

Any call to system(3) causes stdin to always return EOF, not just in the calling program, but any program reading from stdin in cooked mode. The problem persists even after running reset(1).
(Edit: I don't remember how I tested running reset, I suspect it was with another call to system(3).)

This only happens if /bin/sh points to /bin/Shell. Using ln -sf /bin/bash mnt/bin/sh in sync-local.sh solves the problem.

system(3)-breaks-terminal

This also somehow causes sys.stdin.readline to hang in Python after hitting enter.

oskar-skog avatar May 29 '23 15:05 oskar-skog

SerenityOS Shell, and subsequently EventLoopImplementationUnix uses a signal() call to register a signal handler, which is improper for this occasion as signaling the system() calling thread makes it signalled in the kernel which makes subsequent read()s (and their callers such as scanf()) return -EINTR since we interrupted the syscall with SIGCHLD. You can check that by adding a perror() call before returning from the PoC.

From what it looks like, registering the handler with sigaction() and with a SA_RESTART flag, which would restart the syscall after the interruption, should fix the problem and would also explain why bash works, because they do it.

cocateh avatar Jul 06 '23 14:07 cocateh

Hmm, my PoC solution with SA_RESTART does not save the problem? The thread in kernel is still signalled even though we handle the signal.

cocateh avatar Jul 07 '23 10:07 cocateh