Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Signal handling/zcurses

On Apr 21,  8:08pm, Anthony Charles wrote:
} Unforunately, I see no changes with this patch but with little debug,
} I found out that errno is first set to 4 (EINTR), then wgetch is
} restarted but failed

That would seem to indicate that once the read system call has been
interrupted inside wgetch(), it's not possible to pick up where you
left off by simply calling wgetch() again.

Interestingly, I'm able to reproduce your result with the script you
sent -- in spite of the fact that (a) Linux normally has restartable
system calls (b) the doc says that "Under the ncurses implementation,
handled signals never interrupt getch" and (c) my zsh is linked with
-lncursesw so this really should work.

An strace says

read(0, 0xbff8d41f, 1)                  = ? ERESTARTSYS (To be restarted)
--- SIGUSR1 (User defined signal 1) @ 0 (0) ---
rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], [USR1 CHLD], 8) = 0
rt_sigprocmask(SIG_SETMASK, [USR1 CHLD], ~[KILL STOP RTMIN RT_1], 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [USR1 CHLD], 8) = 0
write(1, "USR1\n", 5)                   = 5
rt_sigprocmask(SIG_BLOCK, [CHLD], [USR1 CHLD], 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [CHLD], [USR1 CHLD], 8) = 0
sigreturn()                             = ? (mask now [CHLD])
rt_sigprocmask(SIG_BLOCK, [CHLD], [CHLD], 8) = 0

This is strange because at this point [after sigreturn()] the read()
call should have been resumed, but that never happens.  GDB confirms
that the loop in my patch does call wget_wch() again, so EINTR was
returned (which surprises me, see above) but that wget_wch() returns
without making any system calls (which I think means it believes the
window to be invalid, but I'm not really sure).

Everything works (and straces) as expected with STOP/CONT signals.

read(0, 0xbfe8360f, 1)                  = ? ERESTARTSYS (To be restarted)
--- SIGSTOP (Stopped (signal)) @ 0 (0) ---
--- SIGSTOP (Stopped (signal)) @ 0 (0) ---
read(0, 0xbfe8360f, 1)                  = ? ERESTARTSYS (To be restarted)
--- SIGCONT (Continued) @ 0 (0) ---

} Strangely, if I comment my trap and kill -USR1 the script, it
} terminates immediately, no debug from curses.c as if it didn't receive
} the signal.

That's not strange at all -- the default response to USR1 is for the OS
to kill the process.  If you haven't trapped it, then zsh has not changed
that default, so ...

Messages sorted by: Reverse Date, Date, Thread, Author